diff options
Diffstat (limited to 'gnu')
324 files changed, 78738 insertions, 0 deletions
diff --git a/gnu/.gitignore b/gnu/.gitignore new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/gnu/.gitignore diff --git a/gnu/Makefile.am b/gnu/Makefile.am new file mode 100644 index 00000000..748aa949 --- /dev/null +++ b/gnu/Makefile.am @@ -0,0 +1,3112 @@ +# -*- buffer-read-only: t -*- vi: set ro: +# DO NOT EDIT! GENERATED AUTOMATICALLY! +## DO NOT EDIT! GENERATED AUTOMATICALLY! +## Process this file with automake to produce Makefile.in. +# Copyright (C) 2002-2012 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 <http://www.gnu.org/licenses/>. +# +# 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 --dir=. --local-dir=gl --lib=libgnu --source-base=gnu --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=lock --no-conditional-dependencies --no-libtool --macro-prefix=gl alloca argmatch argp argp-version-etc backupfile closeout configmake dirname error exclude exitfail fdopendir fdutimensat fileblocks fnmatch-gnu fseeko full-write futimens getline getopt-gnu getpagesize gettext gettime gitlog-to-changelog hash human inttostr inttypes lchown linkat localcharset mkdtemp mkfifoat modechange obstack openat parse-datetime priv-set progname quote quotearg readlinkat renameat rpmatch safe-read savedir setenv snprintf stat-time stdbool stdint stpcpy strdup-posix strerror strtol strtoul symlinkat timespec unlinkdir unlocked-io utimensat version-etc-fsf xalloc xalloc-die xgetcwd xstrtoumax xvasprintf + +AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects + +SUBDIRS = +noinst_HEADERS = +noinst_LIBRARIES = +noinst_LTLIBRARIES = +EXTRA_DIST = +BUILT_SOURCES = +SUFFIXES = +MOSTLYCLEANFILES = core *.stackdump +MOSTLYCLEANDIRS = +CLEANFILES = +DISTCLEANFILES = +MAINTAINERCLEANFILES = + +AM_CPPFLAGS = +AM_CFLAGS = + +noinst_LIBRARIES += libgnu.a + +libgnu_a_SOURCES = +libgnu_a_LIBADD = $(gl_LIBOBJS) +libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) +EXTRA_libgnu_a_SOURCES = + +## 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 <alloca.h> 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 + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/alloca.in.h; \ + } > $@-t && \ + mv -f $@-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 allocator + +libgnu_a_SOURCES += allocator.c + +EXTRA_DIST += allocator.h + +## end gnulib module allocator + +## begin gnulib module areadlink + +libgnu_a_SOURCES += areadlink.c + +EXTRA_DIST += areadlink.h + +## end gnulib module areadlink + +## begin gnulib module areadlinkat + +libgnu_a_SOURCES += areadlinkat.c + +EXTRA_DIST += areadlink.h at-func.c + +EXTRA_libgnu_a_SOURCES += at-func.c + +## end gnulib module areadlinkat + +## begin gnulib module argmatch + +libgnu_a_SOURCES += argmatch.c + +EXTRA_DIST += argmatch.h + +## end gnulib module argmatch + +## begin gnulib module argp + +libgnu_a_SOURCES += argp.h argp-ba.c argp-eexst.c \ + argp-fmtstream.c argp-fmtstream.h argp-fs-xinl.c argp-help.c \ + argp-namefrob.h argp-parse.c argp-pin.c argp-pv.c argp-pvh.c \ + argp-xinl.c + +## end gnulib module argp + +## begin gnulib module argp-version-etc + +libgnu_a_SOURCES += argp-version-etc.h argp-version-etc.c + +## end gnulib module argp-version-etc + +## begin gnulib module at-internal + + +EXTRA_DIST += openat-priv.h openat-proc.c + +EXTRA_libgnu_a_SOURCES += openat-proc.c + +## end gnulib module at-internal + +## begin gnulib module backupfile + +libgnu_a_SOURCES += backupfile.c + +EXTRA_DIST += backupfile.h + +## end gnulib module backupfile + +## begin gnulib module bitrotate + +libgnu_a_SOURCES += bitrotate.h + +## end gnulib module bitrotate + +## begin gnulib module btowc + + +EXTRA_DIST += btowc.c + +EXTRA_libgnu_a_SOURCES += btowc.c + +## end gnulib module btowc + +## 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 canonicalize-lgpl + + +EXTRA_DIST += canonicalize-lgpl.c + +EXTRA_libgnu_a_SOURCES += canonicalize-lgpl.c + +## end gnulib module canonicalize-lgpl + +## begin gnulib module careadlinkat + +libgnu_a_SOURCES += careadlinkat.c + +EXTRA_DIST += careadlinkat.h + +## end gnulib module careadlinkat + +## begin gnulib module chdir-long + + +EXTRA_DIST += chdir-long.c chdir-long.h + +EXTRA_libgnu_a_SOURCES += chdir-long.c + +## end gnulib module chdir-long + +## begin gnulib module chown + + +EXTRA_DIST += chown.c fchown-stub.c + +EXTRA_libgnu_a_SOURCES += chown.c fchown-stub.c + +## end gnulib module chown + +## begin gnulib module cloexec + +libgnu_a_SOURCES += cloexec.c + +EXTRA_DIST += cloexec.h + +## end gnulib module cloexec + +## begin gnulib module close + + +EXTRA_DIST += close.c + +EXTRA_libgnu_a_SOURCES += close.c + +## end gnulib module close + +## begin gnulib module close-stream + +libgnu_a_SOURCES += close-stream.c + +EXTRA_DIST += close-stream.h + +## end gnulib module close-stream + +## begin gnulib module closedir + + +EXTRA_DIST += closedir.c dirent-private.h + +EXTRA_libgnu_a_SOURCES += closedir.c + +## end gnulib module closedir + +## begin gnulib module closeout + +libgnu_a_SOURCES += closeout.c + +EXTRA_DIST += closeout.h + +## end gnulib module closeout + +## begin gnulib module configmake + +# Listed in the same order as the GNU makefile conventions, and +# provided by autoconf 2.59c+. +# The Automake-defined pkg* macros are appended, in the order +# listed in the Automake 1.10a+ documentation. +configmake.h: Makefile + $(AM_V_GEN)rm -f $@-t && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + echo '#define PREFIX "$(prefix)"'; \ + echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ + echo '#define BINDIR "$(bindir)"'; \ + echo '#define SBINDIR "$(sbindir)"'; \ + echo '#define LIBEXECDIR "$(libexecdir)"'; \ + echo '#define DATAROOTDIR "$(datarootdir)"'; \ + echo '#define DATADIR "$(datadir)"'; \ + echo '#define SYSCONFDIR "$(sysconfdir)"'; \ + echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \ + echo '#define LOCALSTATEDIR "$(localstatedir)"'; \ + echo '#define INCLUDEDIR "$(includedir)"'; \ + echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \ + echo '#define DOCDIR "$(docdir)"'; \ + echo '#define INFODIR "$(infodir)"'; \ + echo '#define HTMLDIR "$(htmldir)"'; \ + echo '#define DVIDIR "$(dvidir)"'; \ + echo '#define PDFDIR "$(pdfdir)"'; \ + echo '#define PSDIR "$(psdir)"'; \ + echo '#define LIBDIR "$(libdir)"'; \ + echo '#define LISPDIR "$(lispdir)"'; \ + echo '#define LOCALEDIR "$(localedir)"'; \ + echo '#define MANDIR "$(mandir)"'; \ + echo '#define MANEXT "$(manext)"'; \ + echo '#define PKGDATADIR "$(pkgdatadir)"'; \ + echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \ + echo '#define PKGLIBDIR "$(pkglibdir)"'; \ + echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ + } | sed '/""/d' > $@-t + mv -f $@-t $@ + +BUILT_SOURCES += configmake.h +CLEANFILES += configmake.h configmake.h-t + +## end gnulib module configmake + +## begin gnulib module dirent + +BUILT_SOURCES += dirent.h + +# We need the following in order to create <dirent.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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''@/$(GNULIB_OPENDIR)/g' \ + -e 's/@''GNULIB_READDIR''@/$(GNULIB_READDIR)/g' \ + -e 's/@''GNULIB_REWINDDIR''@/$(GNULIB_REWINDDIR)/g' \ + -e 's/@''GNULIB_CLOSEDIR''@/$(GNULIB_CLOSEDIR)/g' \ + -e 's/@''GNULIB_DIRFD''@/$(GNULIB_DIRFD)/g' \ + -e 's/@''GNULIB_FDOPENDIR''@/$(GNULIB_FDOPENDIR)/g' \ + -e 's/@''GNULIB_SCANDIR''@/$(GNULIB_SCANDIR)/g' \ + -e 's/@''GNULIB_ALPHASORT''@/$(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 && \ + mv $@-t $@ +MOSTLYCLEANFILES += dirent.h dirent.h-t + +EXTRA_DIST += dirent.in.h + +## end gnulib module dirent + +## begin gnulib module dirent-safer + +libgnu_a_SOURCES += opendir-safer.c + +EXTRA_DIST += dirent--.h dirent-safer.h + +## end gnulib module dirent-safer + +## begin gnulib module dirfd + + +EXTRA_DIST += dirfd.c + +EXTRA_libgnu_a_SOURCES += dirfd.c + +## 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 basename-lgpl.c stripslash.c + +EXTRA_DIST += dirname.h + +## end gnulib module dirname-lgpl + +## begin gnulib module dosname + + +EXTRA_DIST += dosname.h + +## end gnulib module dosname + +## begin gnulib module dup + + +EXTRA_DIST += dup.c + +EXTRA_libgnu_a_SOURCES += dup.c + +## end gnulib module dup + +## begin gnulib module dup2 + + +EXTRA_DIST += dup2.c + +EXTRA_libgnu_a_SOURCES += dup2.c + +## end gnulib module dup2 + +## begin gnulib module errno + +BUILT_SOURCES += $(ERRNO_H) + +# We need the following in order to create <errno.h> 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 + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -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 && \ + 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 + + +EXTRA_DIST += error.c error.h + +EXTRA_libgnu_a_SOURCES += error.c + +## end gnulib module error + +## begin gnulib module exclude + +libgnu_a_SOURCES += exclude.c + +EXTRA_DIST += exclude.h + +## end gnulib module exclude + +## begin gnulib module exitfail + +libgnu_a_SOURCES += exitfail.c + +EXTRA_DIST += exitfail.h + +## end gnulib module exitfail + +## begin gnulib module fchdir + + +EXTRA_DIST += fchdir.c + +EXTRA_libgnu_a_SOURCES += fchdir.c + +## end gnulib module fchdir + +## begin gnulib module fcntl + + +EXTRA_DIST += fcntl.c + +EXTRA_libgnu_a_SOURCES += fcntl.c + +## end gnulib module fcntl + +## begin gnulib module fcntl-h + +BUILT_SOURCES += fcntl.h + +# We need the following in order to create <fcntl.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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_FCNTL''@/$(GNULIB_FCNTL)/g' \ + -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \ + -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \ + -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \ + -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \ + -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|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 && \ + 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 fdopendir + + +EXTRA_DIST += fdopendir.c + +EXTRA_libgnu_a_SOURCES += fdopendir.c + +## end gnulib module fdopendir + +## begin gnulib module fdutimensat + +libgnu_a_SOURCES += fdutimensat.c + +EXTRA_DIST += utimens.h + +## end gnulib module fdutimensat + +## begin gnulib module fileblocks + + +EXTRA_DIST += fileblocks.c + +EXTRA_libgnu_a_SOURCES += fileblocks.c + +## end gnulib module fileblocks + +## 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 float + +BUILT_SOURCES += $(FLOAT_H) + +# We need the following in order to create <float.h> 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 + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ + -e 's|@''REPLACE_ITOLD''@|$(REPLACE_ITOLD)|g' \ + < $(srcdir)/float.in.h; \ + } > $@-t && \ + mv $@-t $@ +else +float.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += float.h float.h-t + +EXTRA_DIST += float.c float.in.h itold.c + +EXTRA_libgnu_a_SOURCES += float.c itold.c + +## end gnulib module float + +## begin gnulib module fnmatch + +BUILT_SOURCES += $(FNMATCH_H) + +# We need the following in order to create <fnmatch.h> when the system +# doesn't have one that supports the required API. +if GL_GENERATE_FNMATCH_H +fnmatch.h: fnmatch.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + < $(srcdir)/fnmatch.in.h; \ + } > $@-t && \ + mv -f $@-t $@ +else +fnmatch.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += fnmatch.h fnmatch.h-t + +EXTRA_DIST += fnmatch.c fnmatch.in.h fnmatch_loop.c + +EXTRA_libgnu_a_SOURCES += fnmatch.c fnmatch_loop.c + +## end gnulib module fnmatch + +## begin gnulib module fpending + + +EXTRA_DIST += fpending.c fpending.h + +EXTRA_libgnu_a_SOURCES += fpending.c + +## end gnulib module fpending + +## begin gnulib module fseek + + +EXTRA_DIST += fseek.c + +EXTRA_libgnu_a_SOURCES += fseek.c + +## end gnulib module fseek + +## begin gnulib module fseeko + + +EXTRA_DIST += fseeko.c stdio-impl.h + +EXTRA_libgnu_a_SOURCES += fseeko.c + +## end gnulib module fseeko + +## begin gnulib module fstat + + +EXTRA_DIST += fstat.c + +EXTRA_libgnu_a_SOURCES += fstat.c + +## end gnulib module fstat + +## begin gnulib module fstatat + + +EXTRA_DIST += at-func.c fstatat.c openat-priv.h + +EXTRA_libgnu_a_SOURCES += at-func.c fstatat.c + +## end gnulib module fstatat + +## begin gnulib module full-write + +libgnu_a_SOURCES += full-write.h full-write.c + +## end gnulib module full-write + +## begin gnulib module futimens + + +EXTRA_DIST += futimens.c + +EXTRA_libgnu_a_SOURCES += futimens.c + +## end gnulib module futimens + +## begin gnulib module getcwd + + +EXTRA_DIST += getcwd.c + +EXTRA_libgnu_a_SOURCES += getcwd.c + +## end gnulib module getcwd + +## begin gnulib module getcwd-lgpl + + +EXTRA_DIST += getcwd-lgpl.c + +EXTRA_libgnu_a_SOURCES += getcwd-lgpl.c + +## end gnulib module getcwd-lgpl + +## begin gnulib module getdelim + + +EXTRA_DIST += getdelim.c + +EXTRA_libgnu_a_SOURCES += getdelim.c + +## end gnulib module getdelim + +## begin gnulib module getdtablesize + + +EXTRA_DIST += getdtablesize.c + +EXTRA_libgnu_a_SOURCES += getdtablesize.c + +## end gnulib module getdtablesize + +## begin gnulib module getline + + +EXTRA_DIST += getline.c + +EXTRA_libgnu_a_SOURCES += getline.c + +## end gnulib module getline + +## begin gnulib module getopt-posix + +BUILT_SOURCES += $(GETOPT_H) + +# We need the following in order to create <getopt.h> when the system +# doesn't have one that works with the given compiler. +getopt.h: getopt.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_GETOPT_H''@|$(HAVE_GETOPT_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_GETOPT_H''@|$(NEXT_GETOPT_H)|g' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + < $(srcdir)/getopt.in.h; \ + } > $@-t && \ + mv -f $@-t $@ +MOSTLYCLEANFILES += getopt.h getopt.h-t + +EXTRA_DIST += getopt.c getopt.in.h getopt1.c getopt_int.h + +EXTRA_libgnu_a_SOURCES += getopt.c getopt1.c + +## end gnulib module getopt-posix + +## begin gnulib module getpagesize + + +EXTRA_DIST += getpagesize.c + +EXTRA_libgnu_a_SOURCES += getpagesize.c + +## end gnulib module getpagesize + +## begin gnulib module gettext + +# This is for those projects which use "gettextize --intl" to put a source-code +# copy of libintl into their package. In such projects, every Makefile.am needs +# -I$(top_builddir)/intl, so that <libintl.h> can be found in this directory. +# For the Makefile.ams in other directories it is the maintainer's +# responsibility; for the one from gnulib we do it here. +# This option has no effect when the user disables NLS (because then the intl +# directory contains no libintl.h file) or when the project does not use +# "gettextize --intl". +AM_CPPFLAGS += -I$(top_builddir)/intl + +EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath + +## end gnulib module gettext + +## 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 + + +EXTRA_DIST += gettimeofday.c + +EXTRA_libgnu_a_SOURCES += gettimeofday.c + +## end gnulib module gettimeofday + +## begin gnulib module gitlog-to-changelog + + +EXTRA_DIST += $(top_srcdir)/build-aux/gitlog-to-changelog + +## end gnulib module gitlog-to-changelog + +## begin gnulib module hash + +libgnu_a_SOURCES += hash.c + +EXTRA_DIST += hash.h + +## end gnulib module hash + +## begin gnulib module havelib + + +EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath + +## end gnulib module havelib + +## begin gnulib module human + +libgnu_a_SOURCES += human.c + +EXTRA_DIST += human.h + +## end gnulib module human + +## begin gnulib module intprops + + +EXTRA_DIST += intprops.h + +## end gnulib module intprops + +## begin gnulib module inttostr + +libgnu_a_SOURCES += \ + imaxtostr.c \ + inttostr.c \ + offtostr.c \ + uinttostr.c \ + umaxtostr.c + +EXTRA_DIST += anytostr.c inttostr.h + +EXTRA_libgnu_a_SOURCES += anytostr.c + +## end gnulib module inttostr + +## begin gnulib module inttypes-incomplete + +BUILT_SOURCES += inttypes.h + +# We need the following in order to create <inttypes.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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/@''PRI_MACROS_BROKEN''@/$(PRI_MACROS_BROKEN)/g' \ + -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ + -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ + -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ + -e 's/@''PRIPTR_PREFIX''@/$(PRIPTR_PREFIX)/g' \ + -e 's/@''GNULIB_IMAXABS''@/$(GNULIB_IMAXABS)/g' \ + -e 's/@''GNULIB_IMAXDIV''@/$(GNULIB_IMAXDIV)/g' \ + -e 's/@''GNULIB_STRTOIMAX''@/$(GNULIB_STRTOIMAX)/g' \ + -e 's/@''GNULIB_STRTOUMAX''@/$(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/@''REPLACE_STRTOIMAX''@/$(REPLACE_STRTOIMAX)/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 && \ + mv $@-t $@ +MOSTLYCLEANFILES += inttypes.h inttypes.h-t + +EXTRA_DIST += inttypes.in.h + +## end gnulib module inttypes-incomplete + +## begin gnulib module iswblank + + +EXTRA_DIST += iswblank.c + +EXTRA_libgnu_a_SOURCES += iswblank.c + +## end gnulib module iswblank + +## begin gnulib module langinfo + +BUILT_SOURCES += langinfo.h + +# We need the following in order to create an empty placeholder for +# <langinfo.h> when the system doesn't have one. +langinfo.h: langinfo.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_LANGINFO_H''@|$(NEXT_LANGINFO_H)|g' \ + -e 's/@''GNULIB_NL_LANGINFO''@/$(GNULIB_NL_LANGINFO)/g' \ + -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \ + -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \ + -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \ + -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \ + -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \ + -e 's|@''REPLACE_NL_LANGINFO''@|$(REPLACE_NL_LANGINFO)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/langinfo.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += langinfo.h langinfo.h-t + +EXTRA_DIST += langinfo.in.h + +## end gnulib module langinfo + +## begin gnulib module lchown + + +EXTRA_DIST += lchown.c + +EXTRA_libgnu_a_SOURCES += lchown.c + +## end gnulib module lchown + +## begin gnulib module link + + +EXTRA_DIST += link.c + +EXTRA_libgnu_a_SOURCES += link.c + +## end gnulib module link + +## begin gnulib module linkat + + +EXTRA_DIST += at-func2.c linkat.c + +EXTRA_libgnu_a_SOURCES += at-func2.c linkat.c + +## end gnulib module linkat + +## begin gnulib module localcharset + +libgnu_a_SOURCES += localcharset.h localcharset.c + +# We need the following in order to install a simple file in $(libdir) +# which is shared with other installed packages. We use a list of referencing +# packages so that "make uninstall" will remove the file if and only if it +# is not used by another installed package. +# On systems with glibc-2.1 or newer, the file is redundant, therefore we +# avoid installing it. + +all-local: charset.alias ref-add.sed ref-del.sed + +charset_alias = $(DESTDIR)$(libdir)/charset.alias +charset_tmp = $(DESTDIR)$(libdir)/charset.tmp +install-exec-local: install-exec-localcharset +install-exec-localcharset: all-local + if test $(GLIBC21) = no; then \ + case '$(host_os)' in \ + darwin[56]*) \ + need_charset_alias=true ;; \ + darwin* | cygwin* | mingw* | pw32* | cegcc*) \ + need_charset_alias=false ;; \ + *) \ + need_charset_alias=true ;; \ + esac ; \ + else \ + need_charset_alias=false ; \ + fi ; \ + if $$need_charset_alias; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ + fi ; \ + if test -f $(charset_alias); then \ + sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + else \ + if $$need_charset_alias; then \ + sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + fi ; \ + fi + +uninstall-local: uninstall-localcharset +uninstall-localcharset: all-local + if test -f $(charset_alias); then \ + sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ + if grep '^# Packages using this file: $$' $(charset_tmp) \ + > /dev/null; then \ + rm -f $(charset_alias); \ + else \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ + fi; \ + rm -f $(charset_tmp); \ + fi + +charset.alias: config.charset + $(AM_V_GEN)rm -f t-$@ $@ && \ + $(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \ + mv t-$@ $@ + +SUFFIXES += .sed .sin +.sin.sed: + $(AM_V_GEN)rm -f t-$@ $@ && \ + sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \ + mv t-$@ $@ + +CLEANFILES += charset.alias ref-add.sed ref-del.sed + +EXTRA_DIST += config.charset ref-add.sin ref-del.sin + +## end gnulib module localcharset + +## begin gnulib module lseek + + +EXTRA_DIST += lseek.c + +EXTRA_libgnu_a_SOURCES += lseek.c + +## end gnulib module lseek + +## begin gnulib module lstat + + +EXTRA_DIST += lstat.c + +EXTRA_libgnu_a_SOURCES += lstat.c + +## end gnulib module lstat + +## 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 malloca.valgrind + +## end gnulib module malloca + +## begin gnulib module mbchar + +libgnu_a_SOURCES += mbchar.c + +EXTRA_DIST += mbchar.h + +## end gnulib module mbchar + +## begin gnulib module mbrtowc + + +EXTRA_DIST += mbrtowc.c + +EXTRA_libgnu_a_SOURCES += mbrtowc.c + +## end gnulib module mbrtowc + +## begin gnulib module mbscasecmp + +libgnu_a_SOURCES += mbscasecmp.c + +## end gnulib module mbscasecmp + +## begin gnulib module mbsinit + + +EXTRA_DIST += mbsinit.c + +EXTRA_libgnu_a_SOURCES += mbsinit.c + +## end gnulib module mbsinit + +## begin gnulib module mbsrtowcs + + +EXTRA_DIST += mbsrtowcs-impl.h mbsrtowcs-state.c mbsrtowcs.c + +EXTRA_libgnu_a_SOURCES += mbsrtowcs-state.c mbsrtowcs.c + +## end gnulib module mbsrtowcs + +## begin gnulib module mbtowc + + +EXTRA_DIST += mbtowc-impl.h mbtowc.c + +EXTRA_libgnu_a_SOURCES += mbtowc.c + +## end gnulib module mbtowc + +## begin gnulib module mbuiter + +libgnu_a_SOURCES += mbuiter.h + +## end gnulib module mbuiter + +## begin gnulib module memchr + + +EXTRA_DIST += memchr.c memchr.valgrind + +EXTRA_libgnu_a_SOURCES += memchr.c + +## end gnulib module memchr + +## begin gnulib module mempcpy + + +EXTRA_DIST += mempcpy.c + +EXTRA_libgnu_a_SOURCES += mempcpy.c + +## end gnulib module mempcpy + +## begin gnulib module memrchr + + +EXTRA_DIST += memrchr.c + +EXTRA_libgnu_a_SOURCES += memrchr.c + +## end gnulib module memrchr + +## begin gnulib module mkdtemp + + +EXTRA_DIST += mkdtemp.c + +EXTRA_libgnu_a_SOURCES += mkdtemp.c + +## end gnulib module mkdtemp + +## begin gnulib module mkfifo + + +EXTRA_DIST += mkfifo.c + +EXTRA_libgnu_a_SOURCES += mkfifo.c + +## end gnulib module mkfifo + +## begin gnulib module mkfifoat + + +EXTRA_DIST += at-func.c mkfifoat.c mknodat.c + +EXTRA_libgnu_a_SOURCES += at-func.c mkfifoat.c mknodat.c + +## end gnulib module mkfifoat + +## begin gnulib module mknod + + +EXTRA_DIST += mknod.c + +EXTRA_libgnu_a_SOURCES += mknod.c + +## end gnulib module mknod + +## begin gnulib module mktime + + +EXTRA_DIST += mktime-internal.h mktime.c + +EXTRA_libgnu_a_SOURCES += mktime.c + +## end gnulib module mktime + +## begin gnulib module modechange + +libgnu_a_SOURCES += modechange.c + +EXTRA_DIST += modechange.h + +## end gnulib module modechange + +## begin gnulib module msvc-inval + + +EXTRA_DIST += msvc-inval.c msvc-inval.h + +EXTRA_libgnu_a_SOURCES += msvc-inval.c + +## end gnulib module msvc-inval + +## begin gnulib module msvc-nothrow + + +EXTRA_DIST += msvc-nothrow.c msvc-nothrow.h + +EXTRA_libgnu_a_SOURCES += msvc-nothrow.c + +## end gnulib module msvc-nothrow + +## begin gnulib module nl_langinfo + + +EXTRA_DIST += nl_langinfo.c + +EXTRA_libgnu_a_SOURCES += nl_langinfo.c + +## end gnulib module nl_langinfo + +## begin gnulib module obstack + + +EXTRA_DIST += obstack.c obstack.h + +EXTRA_libgnu_a_SOURCES += obstack.c + +## end gnulib module obstack + +## begin gnulib module open + + +EXTRA_DIST += open.c + +EXTRA_libgnu_a_SOURCES += open.c + +## end gnulib module open + +## begin gnulib module openat + + +EXTRA_DIST += openat-priv.h openat.c + +EXTRA_libgnu_a_SOURCES += openat.c + +## 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 + + +EXTRA_DIST += dirent-private.h opendir.c + +EXTRA_libgnu_a_SOURCES += opendir.c + +## end gnulib module opendir + +## begin gnulib module parse-datetime + +# This rule overrides the Automake generated .y.c rule, to ensure that the +# parse-datetime.c file gets generated in the source directory, not in the +# build directory. +parse-datetime.c: parse-datetime.y + $(AM_V_GEN)$(SHELL) $(YLWRAP) $(srcdir)/parse-datetime.y \ + y.tab.c parse-datetime.c \ + y.tab.h parse-datetime.h \ + y.output parse-datetime.output \ + -- $(YACC) $(YFLAGS) $(AM_YFLAGS) && \ + mv parse-datetime.c parse-datetime.c-t && \ + mv parse-datetime.c-t $(srcdir)/parse-datetime.c +libgnu_a_SOURCES += parse-datetime.y +BUILT_SOURCES += parse-datetime.c +MOSTLYCLEANFILES += parse-datetime.c-t +MAINTAINERCLEANFILES += parse-datetime.c +EXTRA_DIST += parse-datetime.c + +EXTRA_DIST += parse-datetime.h + +## end gnulib module parse-datetime + +## begin gnulib module pathmax + + +EXTRA_DIST += pathmax.h + +## end gnulib module pathmax + +## begin gnulib module priv-set + +libgnu_a_SOURCES += priv-set.c + +EXTRA_DIST += priv-set.h + +## end gnulib module priv-set + +## begin gnulib module progname + +libgnu_a_SOURCES += progname.h progname.c + +## end gnulib module progname + +## begin gnulib module quote + +libgnu_a_SOURCES += quote.c + +EXTRA_DIST += quote.h + +## end gnulib module quote + +## begin gnulib module quotearg + +libgnu_a_SOURCES += quotearg.c + +EXTRA_DIST += quotearg.h + +## end gnulib module quotearg + +## begin gnulib module raise + + +EXTRA_DIST += raise.c + +EXTRA_libgnu_a_SOURCES += raise.c + +## end gnulib module raise + +## begin gnulib module rawmemchr + + +EXTRA_DIST += rawmemchr.c rawmemchr.valgrind + +EXTRA_libgnu_a_SOURCES += rawmemchr.c + +## end gnulib module rawmemchr + +## begin gnulib module read + + +EXTRA_DIST += read.c + +EXTRA_libgnu_a_SOURCES += read.c + +## end gnulib module read + +## begin gnulib module readdir + + +EXTRA_DIST += dirent-private.h readdir.c + +EXTRA_libgnu_a_SOURCES += readdir.c + +## end gnulib module readdir + +## begin gnulib module readlink + + +EXTRA_DIST += readlink.c + +EXTRA_libgnu_a_SOURCES += readlink.c + +## end gnulib module readlink + +## begin gnulib module readlinkat + + +EXTRA_DIST += at-func.c readlinkat.c + +EXTRA_libgnu_a_SOURCES += at-func.c readlinkat.c + +## end gnulib module readlinkat + +## begin gnulib module realloc-posix + + +EXTRA_DIST += realloc.c + +EXTRA_libgnu_a_SOURCES += realloc.c + +## end gnulib module realloc-posix + +## begin gnulib module regex + + +EXTRA_DIST += regcomp.c regex.c regex.h regex_internal.c regex_internal.h regexec.c + +EXTRA_libgnu_a_SOURCES += regcomp.c regex.c regex_internal.c regexec.c + +## end gnulib module regex + +## begin gnulib module rename + + +EXTRA_DIST += rename.c + +EXTRA_libgnu_a_SOURCES += rename.c + +## end gnulib module rename + +## begin gnulib module renameat + + +EXTRA_DIST += at-func2.c renameat.c + +EXTRA_libgnu_a_SOURCES += at-func2.c renameat.c + +## end gnulib module renameat + +## begin gnulib module rewinddir + + +EXTRA_DIST += dirent-private.h rewinddir.c + +EXTRA_libgnu_a_SOURCES += rewinddir.c + +## end gnulib module rewinddir + +## begin gnulib module rmdir + + +EXTRA_DIST += rmdir.c + +EXTRA_libgnu_a_SOURCES += rmdir.c + +## end gnulib module rmdir + +## begin gnulib module rpmatch + + +EXTRA_DIST += rpmatch.c + +EXTRA_libgnu_a_SOURCES += rpmatch.c + +## end gnulib module rpmatch + +## begin gnulib module safe-read + +libgnu_a_SOURCES += safe-read.c + +EXTRA_DIST += safe-read.h + +## end gnulib module safe-read + +## begin gnulib module safe-write + +libgnu_a_SOURCES += safe-write.c + +EXTRA_DIST += safe-read.c safe-write.h + +EXTRA_libgnu_a_SOURCES += safe-read.c + +## end gnulib module safe-write + +## 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 savedir + +libgnu_a_SOURCES += savedir.c + +EXTRA_DIST += savedir.h + +## end gnulib module savedir + +## begin gnulib module setenv + + +EXTRA_DIST += setenv.c + +EXTRA_libgnu_a_SOURCES += setenv.c + +## end gnulib module setenv + +## begin gnulib module signal-h + +BUILT_SOURCES += signal.h + +# We need the following in order to create <signal.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -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''@|$(GNULIB_PTHREAD_SIGMASK)|g' \ + -e 's|@''GNULIB_RAISE''@|$(GNULIB_RAISE)|g' \ + -e 's/@''GNULIB_SIGNAL_H_SIGPIPE''@/$(GNULIB_SIGNAL_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_SIGPROCMASK''@/$(GNULIB_SIGPROCMASK)/g' \ + -e 's/@''GNULIB_SIGACTION''@/$(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 && \ + mv $@-t $@ +MOSTLYCLEANFILES += signal.h signal.h-t + +EXTRA_DIST += signal.in.h + +## end gnulib module signal-h + +## begin gnulib module size_max + +libgnu_a_SOURCES += size_max.h + +## end gnulib module size_max + +## begin gnulib module sleep + + +EXTRA_DIST += sleep.c + +EXTRA_libgnu_a_SOURCES += sleep.c + +## end gnulib module sleep + +## begin gnulib module snippet/_Noreturn + +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all Makefile.am that +# need it. This is ensured by the applicability 'all' defined above. + +_NORETURN_H=$(top_srcdir)/build-aux/snippet/_Noreturn.h + +EXTRA_DIST += $(top_srcdir)/build-aux/snippet/_Noreturn.h + +## end gnulib module snippet/_Noreturn + +## begin gnulib module snippet/arg-nonnull + +# The BUILT_SOURCES created by this Makefile snippet are not used via #include +# statements but through direct file reference. Therefore this snippet must be +# present in all Makefile.am that need it. This is ensured by the applicability +# 'all' defined above. + +BUILT_SOURCES += arg-nonnull.h +# The arg-nonnull.h that gets inserted into generated .h files is the same as +# build-aux/snippet/arg-nonnull.h, except that it has the copyright header cut +# off. +arg-nonnull.h: $(top_srcdir)/build-aux/snippet/arg-nonnull.h + $(AM_V_GEN)rm -f $@-t $@ && \ + sed -n -e '/GL_ARG_NONNULL/,$$p' \ + < $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ + > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += arg-nonnull.h arg-nonnull.h-t + +ARG_NONNULL_H=arg-nonnull.h + +EXTRA_DIST += $(top_srcdir)/build-aux/snippet/arg-nonnull.h + +## end gnulib module snippet/arg-nonnull + +## begin gnulib module snippet/c++defs + +# The BUILT_SOURCES created by this Makefile snippet are not used via #include +# statements but through direct file reference. Therefore this snippet must be +# present in all Makefile.am that need it. This is ensured by the applicability +# 'all' defined above. + +BUILT_SOURCES += c++defs.h +# The c++defs.h that gets inserted into generated .h files is the same as +# build-aux/snippet/c++defs.h, except that it has the copyright header cut off. +c++defs.h: $(top_srcdir)/build-aux/snippet/c++defs.h + $(AM_V_GEN)rm -f $@-t $@ && \ + sed -n -e '/_GL_CXXDEFS/,$$p' \ + < $(top_srcdir)/build-aux/snippet/c++defs.h \ + > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += c++defs.h c++defs.h-t + +CXXDEFS_H=c++defs.h + +EXTRA_DIST += $(top_srcdir)/build-aux/snippet/c++defs.h + +## end gnulib module snippet/c++defs + +## begin gnulib module snippet/warn-on-use + +BUILT_SOURCES += warn-on-use.h +# The warn-on-use.h that gets inserted into generated .h files is the same as +# build-aux/snippet/warn-on-use.h, except that it has the copyright header cut +# off. +warn-on-use.h: $(top_srcdir)/build-aux/snippet/warn-on-use.h + $(AM_V_GEN)rm -f $@-t $@ && \ + sed -n -e '/^.ifndef/,$$p' \ + < $(top_srcdir)/build-aux/snippet/warn-on-use.h \ + > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += warn-on-use.h warn-on-use.h-t + +WARN_ON_USE_H=warn-on-use.h + +EXTRA_DIST += $(top_srcdir)/build-aux/snippet/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 stat + + +EXTRA_DIST += stat.c + +EXTRA_libgnu_a_SOURCES += stat.c + +## end gnulib module stat + +## begin gnulib module stat-macros + + +EXTRA_DIST += stat-macros.h + +## end gnulib module stat-macros + +## begin gnulib module stat-time + + +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 <stdalign.h> when the system +# doesn't have one that works. +if GL_GENERATE_STDALIGN_H +stdalign.h: stdalign.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/stdalign.in.h; \ + } > $@-t && \ + mv $@-t $@ +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 stdarg + +BUILT_SOURCES += $(STDARG_H) + +# We need the following in order to create <stdarg.h> when the system +# doesn't have one that works with the given compiler. +if GL_GENERATE_STDARG_H +stdarg.h: stdarg.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -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_STDARG_H''@|$(NEXT_STDARG_H)|g' \ + < $(srcdir)/stdarg.in.h; \ + } > $@-t && \ + mv $@-t $@ +else +stdarg.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stdarg.h stdarg.h-t + +EXTRA_DIST += stdarg.in.h + +## end gnulib module stdarg + +## begin gnulib module stdbool + +BUILT_SOURCES += $(STDBOOL_H) + +# We need the following in order to create <stdbool.h> when the system +# doesn't have one that works. +if GL_GENERATE_STDBOOL_H +stdbool.h: stdbool.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \ + } > $@-t && \ + mv $@-t $@ +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 <stddef.h> 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 + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -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_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \ + -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ + < $(srcdir)/stddef.in.h; \ + } > $@-t && \ + 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 <stdint.h> 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 + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ + -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ + -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ + -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ + -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ + -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ + -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ + -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ + -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' \ + < $(srcdir)/stdint.in.h; \ + } > $@-t && \ + 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 <stdio.h> when the system +# doesn't have one that works with the given compiler. +stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ + -e 's/@''GNULIB_DPRINTF''@/$(GNULIB_DPRINTF)/g' \ + -e 's/@''GNULIB_FCLOSE''@/$(GNULIB_FCLOSE)/g' \ + -e 's/@''GNULIB_FDOPEN''@/$(GNULIB_FDOPEN)/g' \ + -e 's/@''GNULIB_FFLUSH''@/$(GNULIB_FFLUSH)/g' \ + -e 's/@''GNULIB_FGETC''@/$(GNULIB_FGETC)/g' \ + -e 's/@''GNULIB_FGETS''@/$(GNULIB_FGETS)/g' \ + -e 's/@''GNULIB_FOPEN''@/$(GNULIB_FOPEN)/g' \ + -e 's/@''GNULIB_FPRINTF''@/$(GNULIB_FPRINTF)/g' \ + -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GNULIB_FPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_FPURGE''@/$(GNULIB_FPURGE)/g' \ + -e 's/@''GNULIB_FPUTC''@/$(GNULIB_FPUTC)/g' \ + -e 's/@''GNULIB_FPUTS''@/$(GNULIB_FPUTS)/g' \ + -e 's/@''GNULIB_FREAD''@/$(GNULIB_FREAD)/g' \ + -e 's/@''GNULIB_FREOPEN''@/$(GNULIB_FREOPEN)/g' \ + -e 's/@''GNULIB_FSCANF''@/$(GNULIB_FSCANF)/g' \ + -e 's/@''GNULIB_FSEEK''@/$(GNULIB_FSEEK)/g' \ + -e 's/@''GNULIB_FSEEKO''@/$(GNULIB_FSEEKO)/g' \ + -e 's/@''GNULIB_FTELL''@/$(GNULIB_FTELL)/g' \ + -e 's/@''GNULIB_FTELLO''@/$(GNULIB_FTELLO)/g' \ + -e 's/@''GNULIB_FWRITE''@/$(GNULIB_FWRITE)/g' \ + -e 's/@''GNULIB_GETC''@/$(GNULIB_GETC)/g' \ + -e 's/@''GNULIB_GETCHAR''@/$(GNULIB_GETCHAR)/g' \ + -e 's/@''GNULIB_GETDELIM''@/$(GNULIB_GETDELIM)/g' \ + -e 's/@''GNULIB_GETLINE''@/$(GNULIB_GETLINE)/g' \ + -e 's/@''GNULIB_GETS''@/$(GNULIB_GETS)/g' \ + -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GNULIB_OBSTACK_PRINTF)/g' \ + -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GNULIB_OBSTACK_PRINTF_POSIX)/g' \ + -e 's/@''GNULIB_PCLOSE''@/$(GNULIB_PCLOSE)/g' \ + -e 's/@''GNULIB_PERROR''@/$(GNULIB_PERROR)/g' \ + -e 's/@''GNULIB_POPEN''@/$(GNULIB_POPEN)/g' \ + -e 's/@''GNULIB_PRINTF''@/$(GNULIB_PRINTF)/g' \ + -e 's/@''GNULIB_PRINTF_POSIX''@/$(GNULIB_PRINTF_POSIX)/g' \ + -e 's/@''GNULIB_PUTC''@/$(GNULIB_PUTC)/g' \ + -e 's/@''GNULIB_PUTCHAR''@/$(GNULIB_PUTCHAR)/g' \ + -e 's/@''GNULIB_PUTS''@/$(GNULIB_PUTS)/g' \ + -e 's/@''GNULIB_REMOVE''@/$(GNULIB_REMOVE)/g' \ + -e 's/@''GNULIB_RENAME''@/$(GNULIB_RENAME)/g' \ + -e 's/@''GNULIB_RENAMEAT''@/$(GNULIB_RENAMEAT)/g' \ + -e 's/@''GNULIB_SCANF''@/$(GNULIB_SCANF)/g' \ + -e 's/@''GNULIB_SNPRINTF''@/$(GNULIB_SNPRINTF)/g' \ + -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GNULIB_SPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GNULIB_STDIO_H_NONBLOCKING)/g' \ + -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \ + -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \ + -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \ + -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \ + -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_VFSCANF''@/$(GNULIB_VFSCANF)/g' \ + -e 's/@''GNULIB_VSCANF''@/$(GNULIB_VSCANF)/g' \ + -e 's/@''GNULIB_VPRINTF''@/$(GNULIB_VPRINTF)/g' \ + -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \ + -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ + < $(srcdir)/stdio.in.h | \ + sed -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_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 && \ + mv $@-t $@ +MOSTLYCLEANFILES += stdio.h stdio.h-t + +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 <stdlib.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ + -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \ + -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \ + -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \ + -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ + -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \ + -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \ + -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \ + -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \ + -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \ + -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \ + -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \ + -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \ + -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \ + -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ + -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \ + -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ + -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \ + -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ + -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ + -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \ + -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ + -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \ + -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ + -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \ + -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \ + -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \ + -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ + -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ + -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ + < $(srcdir)/stdlib.in.h | \ + sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ + -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ + -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|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_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_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \ + -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \ + -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_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_REALPATH''@|$(HAVE_REALPATH)|g' \ + -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ + -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \ + -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ + -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ + -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ + -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \ + -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ + -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \ + -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \ + -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \ + -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \ + -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \ + -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ + -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \ + -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ + -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ + -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ + -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ + -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \ + -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ + -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ + -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _Noreturn/r $(_NORETURN_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += stdlib.h stdlib.h-t + +EXTRA_DIST += stdlib.in.h + +## end gnulib module stdlib + +## begin gnulib module stpcpy + + +EXTRA_DIST += stpcpy.c + +EXTRA_libgnu_a_SOURCES += stpcpy.c + +## end gnulib module stpcpy + +## begin gnulib module strcase + + +EXTRA_DIST += strcasecmp.c strncasecmp.c + +EXTRA_libgnu_a_SOURCES += strcasecmp.c strncasecmp.c + +## end gnulib module strcase + +## begin gnulib module strchrnul + + +EXTRA_DIST += strchrnul.c strchrnul.valgrind + +EXTRA_libgnu_a_SOURCES += strchrnul.c + +## end gnulib module strchrnul + +## begin gnulib module strdup-posix + + +EXTRA_DIST += strdup.c + +EXTRA_libgnu_a_SOURCES += strdup.c + +## end gnulib module strdup-posix + +## begin gnulib module streq + + +EXTRA_DIST += streq.h + +## end gnulib module streq + +## begin gnulib module strerror + + +EXTRA_DIST += strerror.c + +EXTRA_libgnu_a_SOURCES += strerror.c + +## end gnulib module strerror + +## begin gnulib module strerror-override + + +EXTRA_DIST += strerror-override.c strerror-override.h + +EXTRA_libgnu_a_SOURCES += strerror-override.c + +## end gnulib module strerror-override + +## begin gnulib module string + +BUILT_SOURCES += string.h + +# We need the following in order to create <string.h> when the system +# doesn't have one that works with the given compiler. +string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \ + -e 's/@''GNULIB_FFSL''@/$(GNULIB_FFSL)/g' \ + -e 's/@''GNULIB_FFSLL''@/$(GNULIB_FFSLL)/g' \ + -e 's/@''GNULIB_MBSLEN''@/$(GNULIB_MBSLEN)/g' \ + -e 's/@''GNULIB_MBSNLEN''@/$(GNULIB_MBSNLEN)/g' \ + -e 's/@''GNULIB_MBSCHR''@/$(GNULIB_MBSCHR)/g' \ + -e 's/@''GNULIB_MBSRCHR''@/$(GNULIB_MBSRCHR)/g' \ + -e 's/@''GNULIB_MBSSTR''@/$(GNULIB_MBSSTR)/g' \ + -e 's/@''GNULIB_MBSCASECMP''@/$(GNULIB_MBSCASECMP)/g' \ + -e 's/@''GNULIB_MBSNCASECMP''@/$(GNULIB_MBSNCASECMP)/g' \ + -e 's/@''GNULIB_MBSPCASECMP''@/$(GNULIB_MBSPCASECMP)/g' \ + -e 's/@''GNULIB_MBSCASESTR''@/$(GNULIB_MBSCASESTR)/g' \ + -e 's/@''GNULIB_MBSCSPN''@/$(GNULIB_MBSCSPN)/g' \ + -e 's/@''GNULIB_MBSPBRK''@/$(GNULIB_MBSPBRK)/g' \ + -e 's/@''GNULIB_MBSSPN''@/$(GNULIB_MBSSPN)/g' \ + -e 's/@''GNULIB_MBSSEP''@/$(GNULIB_MBSSEP)/g' \ + -e 's/@''GNULIB_MBSTOK_R''@/$(GNULIB_MBSTOK_R)/g' \ + -e 's/@''GNULIB_MEMCHR''@/$(GNULIB_MEMCHR)/g' \ + -e 's/@''GNULIB_MEMMEM''@/$(GNULIB_MEMMEM)/g' \ + -e 's/@''GNULIB_MEMPCPY''@/$(GNULIB_MEMPCPY)/g' \ + -e 's/@''GNULIB_MEMRCHR''@/$(GNULIB_MEMRCHR)/g' \ + -e 's/@''GNULIB_RAWMEMCHR''@/$(GNULIB_RAWMEMCHR)/g' \ + -e 's/@''GNULIB_STPCPY''@/$(GNULIB_STPCPY)/g' \ + -e 's/@''GNULIB_STPNCPY''@/$(GNULIB_STPNCPY)/g' \ + -e 's/@''GNULIB_STRCHRNUL''@/$(GNULIB_STRCHRNUL)/g' \ + -e 's/@''GNULIB_STRDUP''@/$(GNULIB_STRDUP)/g' \ + -e 's/@''GNULIB_STRNCAT''@/$(GNULIB_STRNCAT)/g' \ + -e 's/@''GNULIB_STRNDUP''@/$(GNULIB_STRNDUP)/g' \ + -e 's/@''GNULIB_STRNLEN''@/$(GNULIB_STRNLEN)/g' \ + -e 's/@''GNULIB_STRPBRK''@/$(GNULIB_STRPBRK)/g' \ + -e 's/@''GNULIB_STRSEP''@/$(GNULIB_STRSEP)/g' \ + -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \ + -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \ + -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \ + -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \ + -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \ + -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \ + -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \ + < $(srcdir)/string.in.h | \ + sed -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ + -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \ + -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \ + -e 's|@''HAVE_MEMCHR''@|$(HAVE_MEMCHR)|g' \ + -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ + -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ + -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ + -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_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ + -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ + -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \ + -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ + -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ + -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ + -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \ + -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ + -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ + -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ + -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ + -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ + -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ + -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \ + -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ + -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \ + -e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + < $(srcdir)/string.in.h; \ + } > $@-t && \ + mv $@-t $@ +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 <strings.h> when the system +# doesn't have one that works with the given compiler. +strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_STRINGS_H''@|$(HAVE_STRINGS_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \ + -e 's|@''GNULIB_FFS''@|$(GNULIB_FFS)|g' \ + -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \ + -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ + -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/strings.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += strings.h strings.h-t + +EXTRA_DIST += strings.in.h + +## end gnulib module strings + +## begin gnulib module strndup + + +EXTRA_DIST += strndup.c + +EXTRA_libgnu_a_SOURCES += strndup.c + +## end gnulib module strndup + +## begin gnulib module strnlen + + +EXTRA_DIST += strnlen.c + +EXTRA_libgnu_a_SOURCES += strnlen.c + +## end gnulib module strnlen + +## begin gnulib module strnlen1 + +libgnu_a_SOURCES += strnlen1.h strnlen1.c + +## end gnulib module strnlen1 + +## begin gnulib module strtol + + +EXTRA_DIST += strtol.c + +EXTRA_libgnu_a_SOURCES += strtol.c + +## end gnulib module strtol + +## begin gnulib module strtoul + + +EXTRA_DIST += strtol.c strtoul.c + +EXTRA_libgnu_a_SOURCES += strtol.c strtoul.c + +## end gnulib module strtoul + +## begin gnulib module strtoull + + +EXTRA_DIST += strtol.c strtoul.c strtoull.c + +EXTRA_libgnu_a_SOURCES += strtol.c strtoul.c strtoull.c + +## end gnulib module strtoull + +## begin gnulib module strtoumax + + +EXTRA_DIST += strtoimax.c strtoumax.c + +EXTRA_libgnu_a_SOURCES += strtoimax.c strtoumax.c + +## end gnulib module strtoumax + +## begin gnulib module symlink + + +EXTRA_DIST += symlink.c + +EXTRA_libgnu_a_SOURCES += symlink.c + +## end gnulib module symlink + +## begin gnulib module symlinkat + + +EXTRA_DIST += at-func.c symlinkat.c + +EXTRA_libgnu_a_SOURCES += at-func.c symlinkat.c + +## end gnulib module symlinkat + +## begin gnulib module sys_stat + +BUILT_SOURCES += sys/stat.h + +# We need the following in order to create <sys/stat.h> 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_at)$(MKDIR_P) sys + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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/@''GNULIB_FCHMODAT''@/$(GNULIB_FCHMODAT)/g' \ + -e 's/@''GNULIB_FSTAT''@/$(GNULIB_FSTAT)/g' \ + -e 's/@''GNULIB_FSTATAT''@/$(GNULIB_FSTATAT)/g' \ + -e 's/@''GNULIB_FUTIMENS''@/$(GNULIB_FUTIMENS)/g' \ + -e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \ + -e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \ + -e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \ + -e 's/@''GNULIB_MKFIFO''@/$(GNULIB_MKFIFO)/g' \ + -e 's/@''GNULIB_MKFIFOAT''@/$(GNULIB_MKFIFOAT)/g' \ + -e 's/@''GNULIB_MKNOD''@/$(GNULIB_MKNOD)/g' \ + -e 's/@''GNULIB_MKNODAT''@/$(GNULIB_MKNODAT)/g' \ + -e 's/@''GNULIB_STAT''@/$(GNULIB_STAT)/g' \ + -e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/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_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_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_MKNOD''@|$(REPLACE_MKNOD)|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 && \ + 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 <sys/time.h> 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_at)$(MKDIR_P) sys + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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''@/$(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 '/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 && \ + 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 <sys/types.h> when the system +# doesn't have one that works with the given compiler. +sys/types.h: sys_types.in.h $(top_builddir)/config.status + $(AM_V_at)$(MKDIR_P) sys + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -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' \ + < $(srcdir)/sys_types.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += sys/types.h sys/types.h-t + +EXTRA_DIST += sys_types.in.h + +## end gnulib module sys_types + +## begin gnulib module sysexits + +BUILT_SOURCES += $(SYSEXITS_H) + +# We need the following in order to create <sysexits.h> when the system +# doesn't have one that works with the given compiler. +if GL_GENERATE_SYSEXITS_H +sysexits.h: sysexits.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_SYSEXITS_H''@|$(HAVE_SYSEXITS_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_SYSEXITS_H''@|$(NEXT_SYSEXITS_H)|g' \ + < $(srcdir)/sysexits.in.h; \ + } > $@-t && \ + mv -f $@-t $@ +else +sysexits.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += sysexits.h sysexits.h-t + +EXTRA_DIST += sysexits.in.h + +## end gnulib module sysexits + +## begin gnulib module tempname + +libgnu_a_SOURCES += tempname.c + +EXTRA_DIST += tempname.h + +## end gnulib module tempname + +## begin gnulib module time + +BUILT_SOURCES += time.h + +# We need the following in order to create <time.h> when the system +# doesn't have one that works with the given compiler. +time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \ + -e 's/@''GNULIB_MKTIME''@/$(GNULIB_MKTIME)/g' \ + -e 's/@''GNULIB_NANOSLEEP''@/$(GNULIB_NANOSLEEP)/g' \ + -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \ + -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \ + -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \ + -e 's|@''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|@''REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \ + -e 's|@''REPLACE_MKTIME''@|$(REPLACE_MKTIME)|g' \ + -e 's|@''REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \ + -e 's|@''REPLACE_TIMEGM''@|$(REPLACE_TIMEGM)|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 '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/time.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += time.h time.h-t + +EXTRA_DIST += time.in.h + +## end gnulib module time + +## begin gnulib module time_r + + +EXTRA_DIST += time_r.c + +EXTRA_libgnu_a_SOURCES += time_r.c + +## end gnulib module time_r + +## begin gnulib module timespec + + +EXTRA_DIST += timespec.h + +## end gnulib module timespec + +## begin gnulib module unistd + +BUILT_SOURCES += unistd.h + +# We need the following in order to create an empty placeholder for +# <unistd.h> when the system doesn't have one. +unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -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/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \ + -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \ + -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \ + -e 's/@''GNULIB_DUP''@/$(GNULIB_DUP)/g' \ + -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \ + -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \ + -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \ + -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \ + -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \ + -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \ + -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \ + -e 's/@''GNULIB_FDATASYNC''@/$(GNULIB_FDATASYNC)/g' \ + -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \ + -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \ + -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \ + -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \ + -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \ + -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \ + -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \ + -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \ + -e 's/@''GNULIB_GETLOGIN_R''@/$(GNULIB_GETLOGIN_R)/g' \ + -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \ + -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \ + -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \ + -e 's/@''GNULIB_ISATTY''@/$(GNULIB_ISATTY)/g' \ + -e 's/@''GNULIB_LCHOWN''@/$(GNULIB_LCHOWN)/g' \ + -e 's/@''GNULIB_LINK''@/$(GNULIB_LINK)/g' \ + -e 's/@''GNULIB_LINKAT''@/$(GNULIB_LINKAT)/g' \ + -e 's/@''GNULIB_LSEEK''@/$(GNULIB_LSEEK)/g' \ + -e 's/@''GNULIB_PIPE''@/$(GNULIB_PIPE)/g' \ + -e 's/@''GNULIB_PIPE2''@/$(GNULIB_PIPE2)/g' \ + -e 's/@''GNULIB_PREAD''@/$(GNULIB_PREAD)/g' \ + -e 's/@''GNULIB_PWRITE''@/$(GNULIB_PWRITE)/g' \ + -e 's/@''GNULIB_READ''@/$(GNULIB_READ)/g' \ + -e 's/@''GNULIB_READLINK''@/$(GNULIB_READLINK)/g' \ + -e 's/@''GNULIB_READLINKAT''@/$(GNULIB_READLINKAT)/g' \ + -e 's/@''GNULIB_RMDIR''@/$(GNULIB_RMDIR)/g' \ + -e 's/@''GNULIB_SETHOSTNAME''@/$(GNULIB_SETHOSTNAME)/g' \ + -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \ + -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \ + -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \ + -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \ + -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GNULIB_GL_UNISTD_H_GETOPT)/g' \ + -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \ + -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GNULIB_UNISTD_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_UNLINK''@/$(GNULIB_UNLINK)/g' \ + -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \ + -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \ + -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \ + < $(srcdir)/unistd.in.h | \ + sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ + -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ + -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \ + -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|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_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \ + -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ + -e 's|@''HAVE_GETLOGIN''@|$(HAVE_GETLOGIN)|g' \ + -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ + -e 's|@''HAVE_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_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_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_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \ + -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \ + -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \ + | \ + sed -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ + -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \ + -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \ + -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ + -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ + -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ + -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|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_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_RMDIR''@|$(REPLACE_RMDIR)|g' \ + -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \ + -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|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_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \ + -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ +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 unitypes + +BUILT_SOURCES += $(LIBUNISTRING_UNITYPES_H) + +unitypes.h: unitypes.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/unitypes.in.h; \ + } > $@-t && \ + mv -f $@-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 + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/uniwidth.in.h; \ + } > $@-t && \ + mv -f $@-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 += uniwidth/cjk.h + +## end gnulib module uniwidth/width + +## begin gnulib module unlinkdir + +libgnu_a_SOURCES += unlinkdir.c + +EXTRA_DIST += unlinkdir.h + +## end gnulib module unlinkdir + +## begin gnulib module unlocked-io + + +EXTRA_DIST += unlocked-io.h + +## end gnulib module unlocked-io + +## begin gnulib module unsetenv + + +EXTRA_DIST += unsetenv.c + +EXTRA_libgnu_a_SOURCES += unsetenv.c + +## end gnulib module unsetenv + +## begin gnulib module utimens + +libgnu_a_SOURCES += utimens.c + +EXTRA_DIST += utimens.h + +## end gnulib module utimens + +## begin gnulib module utimensat + + +EXTRA_DIST += at-func.c utimensat.c + +EXTRA_libgnu_a_SOURCES += at-func.c utimensat.c + +## end gnulib module utimensat + +## 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 verify + + +EXTRA_DIST += verify.h + +## end gnulib module verify + +## begin gnulib module version-etc + +libgnu_a_SOURCES += version-etc.h version-etc.c + +## end gnulib module version-etc + +## begin gnulib module version-etc-fsf + +libgnu_a_SOURCES += version-etc-fsf.c + +## end gnulib module version-etc-fsf + +## begin gnulib module vsnprintf + + +EXTRA_DIST += vsnprintf.c + +EXTRA_libgnu_a_SOURCES += vsnprintf.c + +## end gnulib module vsnprintf + +## begin gnulib module wchar + +BUILT_SOURCES += wchar.h + +# We need the following in order to create <wchar.h> when the system +# version does not work standalone. +wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \ + -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ + -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \ + -e 's/@''GNULIB_BTOWC''@/$(GNULIB_BTOWC)/g' \ + -e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \ + -e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \ + -e 's/@''GNULIB_MBRTOWC''@/$(GNULIB_MBRTOWC)/g' \ + -e 's/@''GNULIB_MBRLEN''@/$(GNULIB_MBRLEN)/g' \ + -e 's/@''GNULIB_MBSRTOWCS''@/$(GNULIB_MBSRTOWCS)/g' \ + -e 's/@''GNULIB_MBSNRTOWCS''@/$(GNULIB_MBSNRTOWCS)/g' \ + -e 's/@''GNULIB_WCRTOMB''@/$(GNULIB_WCRTOMB)/g' \ + -e 's/@''GNULIB_WCSRTOMBS''@/$(GNULIB_WCSRTOMBS)/g' \ + -e 's/@''GNULIB_WCSNRTOMBS''@/$(GNULIB_WCSNRTOMBS)/g' \ + -e 's/@''GNULIB_WCWIDTH''@/$(GNULIB_WCWIDTH)/g' \ + -e 's/@''GNULIB_WMEMCHR''@/$(GNULIB_WMEMCHR)/g' \ + -e 's/@''GNULIB_WMEMCMP''@/$(GNULIB_WMEMCMP)/g' \ + -e 's/@''GNULIB_WMEMCPY''@/$(GNULIB_WMEMCPY)/g' \ + -e 's/@''GNULIB_WMEMMOVE''@/$(GNULIB_WMEMMOVE)/g' \ + -e 's/@''GNULIB_WMEMSET''@/$(GNULIB_WMEMSET)/g' \ + -e 's/@''GNULIB_WCSLEN''@/$(GNULIB_WCSLEN)/g' \ + -e 's/@''GNULIB_WCSNLEN''@/$(GNULIB_WCSNLEN)/g' \ + -e 's/@''GNULIB_WCSCPY''@/$(GNULIB_WCSCPY)/g' \ + -e 's/@''GNULIB_WCPCPY''@/$(GNULIB_WCPCPY)/g' \ + -e 's/@''GNULIB_WCSNCPY''@/$(GNULIB_WCSNCPY)/g' \ + -e 's/@''GNULIB_WCPNCPY''@/$(GNULIB_WCPNCPY)/g' \ + -e 's/@''GNULIB_WCSCAT''@/$(GNULIB_WCSCAT)/g' \ + -e 's/@''GNULIB_WCSNCAT''@/$(GNULIB_WCSNCAT)/g' \ + -e 's/@''GNULIB_WCSCMP''@/$(GNULIB_WCSCMP)/g' \ + -e 's/@''GNULIB_WCSNCMP''@/$(GNULIB_WCSNCMP)/g' \ + -e 's/@''GNULIB_WCSCASECMP''@/$(GNULIB_WCSCASECMP)/g' \ + -e 's/@''GNULIB_WCSNCASECMP''@/$(GNULIB_WCSNCASECMP)/g' \ + -e 's/@''GNULIB_WCSCOLL''@/$(GNULIB_WCSCOLL)/g' \ + -e 's/@''GNULIB_WCSXFRM''@/$(GNULIB_WCSXFRM)/g' \ + -e 's/@''GNULIB_WCSDUP''@/$(GNULIB_WCSDUP)/g' \ + -e 's/@''GNULIB_WCSCHR''@/$(GNULIB_WCSCHR)/g' \ + -e 's/@''GNULIB_WCSRCHR''@/$(GNULIB_WCSRCHR)/g' \ + -e 's/@''GNULIB_WCSCSPN''@/$(GNULIB_WCSCSPN)/g' \ + -e 's/@''GNULIB_WCSSPN''@/$(GNULIB_WCSSPN)/g' \ + -e 's/@''GNULIB_WCSPBRK''@/$(GNULIB_WCSPBRK)/g' \ + -e 's/@''GNULIB_WCSSTR''@/$(GNULIB_WCSSTR)/g' \ + -e 's/@''GNULIB_WCSTOK''@/$(GNULIB_WCSTOK)/g' \ + -e 's/@''GNULIB_WCSWIDTH''@/$(GNULIB_WCSWIDTH)/g' \ + < $(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_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_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|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_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 '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += wchar.h wchar.h-t + +EXTRA_DIST += wchar.in.h + +## end gnulib module wchar + +## begin gnulib module wcrtomb + + +EXTRA_DIST += wcrtomb.c + +EXTRA_libgnu_a_SOURCES += wcrtomb.c + +## end gnulib module wcrtomb + +## begin gnulib module wctype-h + +BUILT_SOURCES += wctype.h + +# We need the following in order to create <wctype.h> when the system +# doesn't have one that works with the given compiler. +wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ + -e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \ + -e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \ + -e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \ + -e 's/@''GNULIB_WCTRANS''@/$(GNULIB_WCTRANS)/g' \ + -e 's/@''GNULIB_TOWCTRANS''@/$(GNULIB_TOWCTRANS)/g' \ + -e 's/@''HAVE_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_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \ + -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/wctype.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += wctype.h wctype.h-t + +EXTRA_DIST += wctype.in.h + +## end gnulib module wctype-h + +## begin gnulib module wcwidth + + +EXTRA_DIST += wcwidth.c + +EXTRA_libgnu_a_SOURCES += wcwidth.c + +## end gnulib module wcwidth + +## begin gnulib module write + + +EXTRA_DIST += write.c + +EXTRA_libgnu_a_SOURCES += write.c + +## 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 + +## end gnulib module xalloc-die + +## begin gnulib module xalloc-oversized + + +EXTRA_DIST += xalloc-oversized.h + +## end gnulib module xalloc-oversized + +## begin gnulib module xgetcwd + +libgnu_a_SOURCES += xgetcwd.c + +EXTRA_DIST += xgetcwd.h + +## end gnulib module xgetcwd + +## begin gnulib module xsize + +libgnu_a_SOURCES += xsize.h + +## end gnulib module xsize + +## begin gnulib module xstrndup + +libgnu_a_SOURCES += xstrndup.h xstrndup.c + +## end gnulib module xstrndup + +## begin gnulib module xstrtol + +libgnu_a_SOURCES += xstrtol.c xstrtoul.c xstrtol-error.c + +EXTRA_DIST += xstrtol.h + +## end gnulib module xstrtol + +## begin gnulib module xstrtoumax + +libgnu_a_SOURCES += xstrtoumax.c + +## end gnulib module xstrtoumax + +## begin gnulib module xvasprintf + +libgnu_a_SOURCES += xvasprintf.h xvasprintf.c xasprintf.c + +EXTRA_DIST += xalloc.h + +## end gnulib module xvasprintf + + +mostlyclean-local: mostlyclean-generic + @for dir in '' $(MOSTLYCLEANDIRS); do \ + if test -n "$$dir" && test -d $$dir; then \ + echo "rmdir $$dir"; rmdir $$dir; \ + fi; \ + done; \ + : diff --git a/gnu/Makefile.in b/gnu/Makefile.in new file mode 100644 index 00000000..9d0c4481 --- /dev/null +++ b/gnu/Makefile.in @@ -0,0 +1,3171 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ + +# -*- buffer-read-only: t -*- vi: set ro: +# DO NOT EDIT! GENERATED AUTOMATICALLY! +# Copyright (C) 2002-2012 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 <http://www.gnu.org/licenses/>. +# +# 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 --dir=. --local-dir=gl --lib=libgnu --source-base=gnu --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=lock --no-conditional-dependencies --no-libtool --macro-prefix=gl alloca argmatch argp argp-version-etc backupfile closeout configmake dirname error exclude exitfail fdopendir fdutimensat fileblocks fnmatch-gnu fseeko full-write futimens getline getopt-gnu getpagesize gettext gettime gitlog-to-changelog hash human inttostr inttypes lchown linkat localcharset mkdtemp mkfifoat modechange obstack openat parse-datetime priv-set progname quote quotearg readlinkat renameat rpmatch safe-read savedir setenv snprintf stat-time stdbool stdint stpcpy strdup-posix strerror strtol strtoul symlinkat timespec unlinkdir unlocked-io utimensat version-etc-fsf xalloc xalloc-die xgetcwd xstrtoumax xvasprintf + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@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@ +@LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE@am__append_1 = uniwidth/width.c +subdir = gnu +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in alloca.c parse-datetime.c +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ + $(top_srcdir)/m4/alloca.m4 $(top_srcdir)/m4/argp.m4 \ + $(top_srcdir)/m4/backupfile.m4 $(top_srcdir)/m4/bison.m4 \ + $(top_srcdir)/m4/btowc.m4 $(top_srcdir)/m4/canonicalize.m4 \ + $(top_srcdir)/m4/chdir-long.m4 $(top_srcdir)/m4/chown.m4 \ + $(top_srcdir)/m4/clock_time.m4 \ + $(top_srcdir)/m4/close-stream.m4 $(top_srcdir)/m4/close.m4 \ + $(top_srcdir)/m4/closedir.m4 $(top_srcdir)/m4/closeout.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/configmake.m4 \ + $(top_srcdir)/m4/d-ino.m4 $(top_srcdir)/m4/dirent-safer.m4 \ + $(top_srcdir)/m4/dirent_h.m4 $(top_srcdir)/m4/dirfd.m4 \ + $(top_srcdir)/m4/dirname.m4 \ + $(top_srcdir)/m4/double-slash-root.m4 $(top_srcdir)/m4/dup.m4 \ + $(top_srcdir)/m4/dup2.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/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/fileblocks.m4 $(top_srcdir)/m4/filenamecat.m4 \ + $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/fnmatch.m4 \ + $(top_srcdir)/m4/fpending.m4 $(top_srcdir)/m4/fseek.m4 \ + $(top_srcdir)/m4/fseeko.m4 $(top_srcdir)/m4/fstat.m4 \ + $(top_srcdir)/m4/fstatat.m4 $(top_srcdir)/m4/futimens.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/getline.m4 $(top_srcdir)/m4/getopt.m4 \ + $(top_srcdir)/m4/getpagesize.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gettime.m4 $(top_srcdir)/m4/gettimeofday.m4 \ + $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/gnulib-common.m4 \ + $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/human.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/include_next.m4 \ + $(top_srcdir)/m4/inline.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttostr.m4 \ + $(top_srcdir)/m4/inttypes-pri.m4 $(top_srcdir)/m4/inttypes.m4 \ + $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/iswblank.m4 \ + $(top_srcdir)/m4/langinfo_h.m4 $(top_srcdir)/m4/largefile.m4 \ + $(top_srcdir)/m4/lchown.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/link-follow.m4 $(top_srcdir)/m4/link.m4 \ + $(top_srcdir)/m4/linkat.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/longlong.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/memchr.m4 \ + $(top_srcdir)/m4/mempcpy.m4 $(top_srcdir)/m4/memrchr.m4 \ + $(top_srcdir)/m4/mkdtemp.m4 $(top_srcdir)/m4/mkfifo.m4 \ + $(top_srcdir)/m4/mkfifoat.m4 $(top_srcdir)/m4/mknod.m4 \ + $(top_srcdir)/m4/mktime.m4 $(top_srcdir)/m4/mmap-anon.m4 \ + $(top_srcdir)/m4/mode_t.m4 $(top_srcdir)/m4/modechange.m4 \ + $(top_srcdir)/m4/msvc-inval.m4 \ + $(top_srcdir)/m4/msvc-nothrow.m4 $(top_srcdir)/m4/multiarch.m4 \ + $(top_srcdir)/m4/nl_langinfo.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/nocrash.m4 $(top_srcdir)/m4/open.m4 \ + $(top_srcdir)/m4/openat.m4 $(top_srcdir)/m4/opendir.m4 \ + $(top_srcdir)/m4/parse-datetime.m4 $(top_srcdir)/m4/pathmax.m4 \ + $(top_srcdir)/m4/paxutils.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/printf.m4 $(top_srcdir)/m4/priv-set.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/quote.m4 \ + $(top_srcdir)/m4/quotearg.m4 $(top_srcdir)/m4/raise.m4 \ + $(top_srcdir)/m4/rawmemchr.m4 $(top_srcdir)/m4/read.m4 \ + $(top_srcdir)/m4/readdir.m4 $(top_srcdir)/m4/readlink.m4 \ + $(top_srcdir)/m4/readlinkat.m4 $(top_srcdir)/m4/realloc.m4 \ + $(top_srcdir)/m4/regex.m4 $(top_srcdir)/m4/rename.m4 \ + $(top_srcdir)/m4/renameat.m4 $(top_srcdir)/m4/rewinddir.m4 \ + $(top_srcdir)/m4/rmdir.m4 $(top_srcdir)/m4/rmt.m4 \ + $(top_srcdir)/m4/rpmatch.m4 $(top_srcdir)/m4/rtapelib.m4 \ + $(top_srcdir)/m4/safe-read.m4 $(top_srcdir)/m4/safe-write.m4 \ + $(top_srcdir)/m4/save-cwd.m4 $(top_srcdir)/m4/savedir.m4 \ + $(top_srcdir)/m4/setenv.m4 $(top_srcdir)/m4/signal_h.m4 \ + $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/sleep.m4 \ + $(top_srcdir)/m4/snprintf.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/stdarg.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/string_h.m4 \ + $(top_srcdir)/m4/strings_h.m4 $(top_srcdir)/m4/strndup.m4 \ + $(top_srcdir)/m4/strnlen.m4 $(top_srcdir)/m4/strtol.m4 \ + $(top_srcdir)/m4/strtoul.m4 $(top_srcdir)/m4/strtoull.m4 \ + $(top_srcdir)/m4/strtoumax.m4 $(top_srcdir)/m4/symlink.m4 \ + $(top_srcdir)/m4/symlinkat.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/sysexits.m4 \ + $(top_srcdir)/m4/system.m4 $(top_srcdir)/m4/tempname.m4 \ + $(top_srcdir)/m4/time_h.m4 $(top_srcdir)/m4/time_r.m4 \ + $(top_srcdir)/m4/timespec.m4 $(top_srcdir)/m4/tm_gmtoff.m4 \ + $(top_srcdir)/m4/unistd-safer.m4 $(top_srcdir)/m4/unistd_h.m4 \ + $(top_srcdir)/m4/unlinkdir.m4 $(top_srcdir)/m4/unlocked-io.m4 \ + $(top_srcdir)/m4/utimbuf.m4 $(top_srcdir)/m4/utimens.m4 \ + $(top_srcdir)/m4/utimensat.m4 $(top_srcdir)/m4/utimes.m4 \ + $(top_srcdir)/m4/vasnprintf.m4 $(top_srcdir)/m4/vasprintf.m4 \ + $(top_srcdir)/m4/version-etc.m4 $(top_srcdir)/m4/vsnprintf.m4 \ + $(top_srcdir)/m4/warn-on-use.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/wint_t.m4 $(top_srcdir)/m4/write.m4 \ + $(top_srcdir)/m4/xalloc.m4 $(top_srcdir)/m4/xgetcwd.m4 \ + $(top_srcdir)/m4/xsize.m4 $(top_srcdir)/m4/xstrndup.m4 \ + $(top_srcdir)/m4/xstrtol.m4 $(top_srcdir)/m4/xvasprintf.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AM_V_AR = $(am__v_AR_$(V)) +am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY)) +am__v_AR_0 = @echo " AR " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +libgnu_a_AR = $(AR) $(ARFLAGS) +am__DEPENDENCIES_1 = +am__libgnu_a_SOURCES_DIST = allocator.c areadlink.c areadlinkat.c \ + argmatch.c argp.h argp-ba.c argp-eexst.c argp-fmtstream.c \ + argp-fmtstream.h argp-fs-xinl.c argp-help.c argp-namefrob.h \ + argp-parse.c argp-pin.c argp-pv.c argp-pvh.c argp-xinl.c \ + argp-version-etc.h argp-version-etc.c backupfile.c bitrotate.h \ + c-ctype.h c-ctype.c c-strcase.h c-strcasecmp.c c-strncasecmp.c \ + careadlinkat.c cloexec.c close-stream.c closeout.c \ + opendir-safer.c dirname.c basename.c dirname-lgpl.c \ + basename-lgpl.c stripslash.c exclude.c exitfail.c fd-hook.c \ + fdutimensat.c filenamecat-lgpl.c full-write.h full-write.c \ + gettext.h gettime.c hash.c human.c imaxtostr.c inttostr.c \ + offtostr.c uinttostr.c umaxtostr.c localcharset.h \ + localcharset.c malloca.c mbchar.c mbscasecmp.c mbuiter.h \ + modechange.c openat-die.c parse-datetime.y priv-set.c \ + progname.h progname.c quote.c quotearg.c safe-read.c \ + safe-write.c save-cwd.c savedir.c size_max.h strnlen1.h \ + strnlen1.c tempname.c dup-safer.c fd-safer.c pipe-safer.c \ + uniwidth/width.c unlinkdir.c utimens.c version-etc.h \ + version-etc.c version-etc-fsf.c xmalloc.c xalloc-die.c \ + xgetcwd.c xsize.h xstrndup.h xstrndup.c xstrtol.c xstrtoul.c \ + xstrtol-error.c xstrtoumax.c xvasprintf.h xvasprintf.c \ + xasprintf.c +am__dirstamp = $(am__leading_dot)dirstamp +@LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE@am__objects_1 = uniwidth/width.$(OBJEXT) +am_libgnu_a_OBJECTS = allocator.$(OBJEXT) areadlink.$(OBJEXT) \ + areadlinkat.$(OBJEXT) argmatch.$(OBJEXT) argp-ba.$(OBJEXT) \ + argp-eexst.$(OBJEXT) argp-fmtstream.$(OBJEXT) \ + argp-fs-xinl.$(OBJEXT) argp-help.$(OBJEXT) \ + argp-parse.$(OBJEXT) argp-pin.$(OBJEXT) argp-pv.$(OBJEXT) \ + argp-pvh.$(OBJEXT) argp-xinl.$(OBJEXT) \ + argp-version-etc.$(OBJEXT) backupfile.$(OBJEXT) \ + c-ctype.$(OBJEXT) c-strcasecmp.$(OBJEXT) \ + c-strncasecmp.$(OBJEXT) careadlinkat.$(OBJEXT) \ + cloexec.$(OBJEXT) close-stream.$(OBJEXT) closeout.$(OBJEXT) \ + opendir-safer.$(OBJEXT) dirname.$(OBJEXT) basename.$(OBJEXT) \ + dirname-lgpl.$(OBJEXT) basename-lgpl.$(OBJEXT) \ + stripslash.$(OBJEXT) exclude.$(OBJEXT) exitfail.$(OBJEXT) \ + fd-hook.$(OBJEXT) fdutimensat.$(OBJEXT) \ + filenamecat-lgpl.$(OBJEXT) full-write.$(OBJEXT) \ + gettime.$(OBJEXT) hash.$(OBJEXT) human.$(OBJEXT) \ + imaxtostr.$(OBJEXT) inttostr.$(OBJEXT) offtostr.$(OBJEXT) \ + uinttostr.$(OBJEXT) umaxtostr.$(OBJEXT) localcharset.$(OBJEXT) \ + malloca.$(OBJEXT) mbchar.$(OBJEXT) mbscasecmp.$(OBJEXT) \ + modechange.$(OBJEXT) openat-die.$(OBJEXT) \ + parse-datetime.$(OBJEXT) priv-set.$(OBJEXT) progname.$(OBJEXT) \ + quote.$(OBJEXT) quotearg.$(OBJEXT) safe-read.$(OBJEXT) \ + safe-write.$(OBJEXT) save-cwd.$(OBJEXT) savedir.$(OBJEXT) \ + strnlen1.$(OBJEXT) tempname.$(OBJEXT) dup-safer.$(OBJEXT) \ + fd-safer.$(OBJEXT) pipe-safer.$(OBJEXT) $(am__objects_1) \ + unlinkdir.$(OBJEXT) utimens.$(OBJEXT) version-etc.$(OBJEXT) \ + version-etc-fsf.$(OBJEXT) xmalloc.$(OBJEXT) \ + xalloc-die.$(OBJEXT) xgetcwd.$(OBJEXT) xstrndup.$(OBJEXT) \ + xstrtol.$(OBJEXT) xstrtoul.$(OBJEXT) xstrtol-error.$(OBJEXT) \ + xstrtoumax.$(OBJEXT) xvasprintf.$(OBJEXT) xasprintf.$(OBJEXT) +libgnu_a_OBJECTS = $(am_libgnu_a_OBJECTS) +LTLIBRARIES = $(noinst_LTLIBRARIES) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS) +AM_V_YACC = $(am__v_YACC_$(V)) +am__v_YACC_ = $(am__v_YACC_$(AM_DEFAULT_VERBOSITY)) +am__v_YACC_0 = @echo " YACC " $@; +YLWRAP = $(top_srcdir)/build-aux/ylwrap +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libgnu_a_SOURCES) $(EXTRA_libgnu_a_SOURCES) +DIST_SOURCES = $(am__libgnu_a_SOURCES_DIST) $(EXTRA_libgnu_a_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +HEADERS = $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +pkglibexecdir = @pkglibexecdir@ +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@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOM4TE = @AUTOM4TE@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BACKUP_LIBEXEC_SCRIPTS = @BACKUP_LIBEXEC_SCRIPTS@ +BACKUP_SBIN_SCRIPTS = @BACKUP_SBIN_SCRIPTS@ +BACKUP_SED_COND = @BACKUP_SED_COND@ +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@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_ARCHIVE = @DEFAULT_ARCHIVE@ +DEFAULT_ARCHIVE_FORMAT = @DEFAULT_ARCHIVE_FORMAT@ +DEFAULT_BLOCKING = @DEFAULT_BLOCKING@ +DEFAULT_QUOTING_STYLE = @DEFAULT_QUOTING_STYLE@ +DEFAULT_RMT_COMMAND = @DEFAULT_RMT_COMMAND@ +DEFAULT_RMT_DIR = @DEFAULT_RMT_DIR@ +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@ +EXEEXT = @EXEEXT@ +FLOAT_H = @FLOAT_H@ +FNMATCH_H = @FNMATCH_H@ +GETOPT_H = @GETOPT_H@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GLIBC21 = @GLIBC21@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNULIB_ALPHASORT = @GNULIB_ALPHASORT@ +GNULIB_ATOLL = @GNULIB_ATOLL@ +GNULIB_BTOWC = @GNULIB_BTOWC@ +GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@ +GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@ +GNULIB_CHDIR = @GNULIB_CHDIR@ +GNULIB_CHOWN = @GNULIB_CHOWN@ +GNULIB_CLOSE = @GNULIB_CLOSE@ +GNULIB_CLOSEDIR = @GNULIB_CLOSEDIR@ +GNULIB_DIRFD = @GNULIB_DIRFD@ +GNULIB_DPRINTF = @GNULIB_DPRINTF@ +GNULIB_DUP = @GNULIB_DUP@ +GNULIB_DUP2 = @GNULIB_DUP2@ +GNULIB_DUP3 = @GNULIB_DUP3@ +GNULIB_ENVIRON = @GNULIB_ENVIRON@ +GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@ +GNULIB_FACCESSAT = @GNULIB_FACCESSAT@ +GNULIB_FCHDIR = @GNULIB_FCHDIR@ +GNULIB_FCHMODAT = @GNULIB_FCHMODAT@ +GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@ +GNULIB_FCLOSE = @GNULIB_FCLOSE@ +GNULIB_FCNTL = @GNULIB_FCNTL@ +GNULIB_FDATASYNC = @GNULIB_FDATASYNC@ +GNULIB_FDOPEN = @GNULIB_FDOPEN@ +GNULIB_FDOPENDIR = @GNULIB_FDOPENDIR@ +GNULIB_FFLUSH = @GNULIB_FFLUSH@ +GNULIB_FFS = @GNULIB_FFS@ +GNULIB_FFSL = @GNULIB_FFSL@ +GNULIB_FFSLL = @GNULIB_FFSLL@ +GNULIB_FGETC = @GNULIB_FGETC@ +GNULIB_FGETS = @GNULIB_FGETS@ +GNULIB_FOPEN = @GNULIB_FOPEN@ +GNULIB_FPRINTF = @GNULIB_FPRINTF@ +GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@ +GNULIB_FPURGE = @GNULIB_FPURGE@ +GNULIB_FPUTC = @GNULIB_FPUTC@ +GNULIB_FPUTS = @GNULIB_FPUTS@ +GNULIB_FREAD = @GNULIB_FREAD@ +GNULIB_FREOPEN = @GNULIB_FREOPEN@ +GNULIB_FSCANF = @GNULIB_FSCANF@ +GNULIB_FSEEK = @GNULIB_FSEEK@ +GNULIB_FSEEKO = @GNULIB_FSEEKO@ +GNULIB_FSTAT = @GNULIB_FSTAT@ +GNULIB_FSTATAT = @GNULIB_FSTATAT@ +GNULIB_FSYNC = @GNULIB_FSYNC@ +GNULIB_FTELL = @GNULIB_FTELL@ +GNULIB_FTELLO = @GNULIB_FTELLO@ +GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@ +GNULIB_FUTIMENS = @GNULIB_FUTIMENS@ +GNULIB_FWRITE = @GNULIB_FWRITE@ +GNULIB_GETC = @GNULIB_GETC@ +GNULIB_GETCHAR = @GNULIB_GETCHAR@ +GNULIB_GETCWD = @GNULIB_GETCWD@ +GNULIB_GETDELIM = @GNULIB_GETDELIM@ +GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@ +GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@ +GNULIB_GETGROUPS = @GNULIB_GETGROUPS@ +GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@ +GNULIB_GETLINE = @GNULIB_GETLINE@ +GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@ +GNULIB_GETLOGIN = @GNULIB_GETLOGIN@ +GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@ +GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@ +GNULIB_GETS = @GNULIB_GETS@ +GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@ +GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@ +GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@ +GNULIB_GL_UNISTD_H_GETOPT = @GNULIB_GL_UNISTD_H_GETOPT@ +GNULIB_GRANTPT = @GNULIB_GRANTPT@ +GNULIB_GROUP_MEMBER = @GNULIB_GROUP_MEMBER@ +GNULIB_IMAXABS = @GNULIB_IMAXABS@ +GNULIB_IMAXDIV = @GNULIB_IMAXDIV@ +GNULIB_ISATTY = @GNULIB_ISATTY@ +GNULIB_ISWBLANK = @GNULIB_ISWBLANK@ +GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@ +GNULIB_LCHMOD = @GNULIB_LCHMOD@ +GNULIB_LCHOWN = @GNULIB_LCHOWN@ +GNULIB_LINK = @GNULIB_LINK@ +GNULIB_LINKAT = @GNULIB_LINKAT@ +GNULIB_LSEEK = @GNULIB_LSEEK@ +GNULIB_LSTAT = @GNULIB_LSTAT@ +GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@ +GNULIB_MBRLEN = @GNULIB_MBRLEN@ +GNULIB_MBRTOWC = @GNULIB_MBRTOWC@ +GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@ +GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@ +GNULIB_MBSCHR = @GNULIB_MBSCHR@ +GNULIB_MBSCSPN = @GNULIB_MBSCSPN@ +GNULIB_MBSINIT = @GNULIB_MBSINIT@ +GNULIB_MBSLEN = @GNULIB_MBSLEN@ +GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@ +GNULIB_MBSNLEN = @GNULIB_MBSNLEN@ +GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@ +GNULIB_MBSPBRK = @GNULIB_MBSPBRK@ +GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@ +GNULIB_MBSRCHR = @GNULIB_MBSRCHR@ +GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@ +GNULIB_MBSSEP = @GNULIB_MBSSEP@ +GNULIB_MBSSPN = @GNULIB_MBSSPN@ +GNULIB_MBSSTR = @GNULIB_MBSSTR@ +GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@ +GNULIB_MBTOWC = @GNULIB_MBTOWC@ +GNULIB_MEMCHR = @GNULIB_MEMCHR@ +GNULIB_MEMMEM = @GNULIB_MEMMEM@ +GNULIB_MEMPCPY = @GNULIB_MEMPCPY@ +GNULIB_MEMRCHR = @GNULIB_MEMRCHR@ +GNULIB_MKDIRAT = @GNULIB_MKDIRAT@ +GNULIB_MKDTEMP = @GNULIB_MKDTEMP@ +GNULIB_MKFIFO = @GNULIB_MKFIFO@ +GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@ +GNULIB_MKNOD = @GNULIB_MKNOD@ +GNULIB_MKNODAT = @GNULIB_MKNODAT@ +GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@ +GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@ +GNULIB_MKSTEMP = @GNULIB_MKSTEMP@ +GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@ +GNULIB_MKTIME = @GNULIB_MKTIME@ +GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@ +GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@ +GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@ +GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@ +GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@ +GNULIB_OPEN = @GNULIB_OPEN@ +GNULIB_OPENAT = @GNULIB_OPENAT@ +GNULIB_OPENDIR = @GNULIB_OPENDIR@ +GNULIB_PCLOSE = @GNULIB_PCLOSE@ +GNULIB_PERROR = @GNULIB_PERROR@ +GNULIB_PIPE = @GNULIB_PIPE@ +GNULIB_PIPE2 = @GNULIB_PIPE2@ +GNULIB_POPEN = @GNULIB_POPEN@ +GNULIB_POSIX_OPENPT = @GNULIB_POSIX_OPENPT@ +GNULIB_PREAD = @GNULIB_PREAD@ +GNULIB_PRINTF = @GNULIB_PRINTF@ +GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@ +GNULIB_PTHREAD_SIGMASK = @GNULIB_PTHREAD_SIGMASK@ +GNULIB_PTSNAME = @GNULIB_PTSNAME@ +GNULIB_PTSNAME_R = @GNULIB_PTSNAME_R@ +GNULIB_PUTC = @GNULIB_PUTC@ +GNULIB_PUTCHAR = @GNULIB_PUTCHAR@ +GNULIB_PUTENV = @GNULIB_PUTENV@ +GNULIB_PUTS = @GNULIB_PUTS@ +GNULIB_PWRITE = @GNULIB_PWRITE@ +GNULIB_RAISE = @GNULIB_RAISE@ +GNULIB_RANDOM = @GNULIB_RANDOM@ +GNULIB_RANDOM_R = @GNULIB_RANDOM_R@ +GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@ +GNULIB_READ = @GNULIB_READ@ +GNULIB_READDIR = @GNULIB_READDIR@ +GNULIB_READLINK = @GNULIB_READLINK@ +GNULIB_READLINKAT = @GNULIB_READLINKAT@ +GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@ +GNULIB_REALPATH = @GNULIB_REALPATH@ +GNULIB_REMOVE = @GNULIB_REMOVE@ +GNULIB_RENAME = @GNULIB_RENAME@ +GNULIB_RENAMEAT = @GNULIB_RENAMEAT@ +GNULIB_REWINDDIR = @GNULIB_REWINDDIR@ +GNULIB_RMDIR = @GNULIB_RMDIR@ +GNULIB_RPMATCH = @GNULIB_RPMATCH@ +GNULIB_SCANDIR = @GNULIB_SCANDIR@ +GNULIB_SCANF = @GNULIB_SCANF@ +GNULIB_SETENV = @GNULIB_SETENV@ +GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@ +GNULIB_SIGACTION = @GNULIB_SIGACTION@ +GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@ +GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@ +GNULIB_SLEEP = @GNULIB_SLEEP@ +GNULIB_SNPRINTF = @GNULIB_SNPRINTF@ +GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@ +GNULIB_STAT = @GNULIB_STAT@ +GNULIB_STDIO_H_NONBLOCKING = @GNULIB_STDIO_H_NONBLOCKING@ +GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@ +GNULIB_STPCPY = @GNULIB_STPCPY@ +GNULIB_STPNCPY = @GNULIB_STPNCPY@ +GNULIB_STRCASESTR = @GNULIB_STRCASESTR@ +GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@ +GNULIB_STRDUP = @GNULIB_STRDUP@ +GNULIB_STRERROR = @GNULIB_STRERROR@ +GNULIB_STRERROR_R = @GNULIB_STRERROR_R@ +GNULIB_STRNCAT = @GNULIB_STRNCAT@ +GNULIB_STRNDUP = @GNULIB_STRNDUP@ +GNULIB_STRNLEN = @GNULIB_STRNLEN@ +GNULIB_STRPBRK = @GNULIB_STRPBRK@ +GNULIB_STRPTIME = @GNULIB_STRPTIME@ +GNULIB_STRSEP = @GNULIB_STRSEP@ +GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@ +GNULIB_STRSTR = @GNULIB_STRSTR@ +GNULIB_STRTOD = @GNULIB_STRTOD@ +GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@ +GNULIB_STRTOK_R = @GNULIB_STRTOK_R@ +GNULIB_STRTOLL = @GNULIB_STRTOLL@ +GNULIB_STRTOULL = @GNULIB_STRTOULL@ +GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@ +GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@ +GNULIB_SYMLINK = @GNULIB_SYMLINK@ +GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@ +GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@ +GNULIB_TIMEGM = @GNULIB_TIMEGM@ +GNULIB_TIME_R = @GNULIB_TIME_R@ +GNULIB_TMPFILE = @GNULIB_TMPFILE@ +GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@ +GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@ +GNULIB_UNISTD_H_NONBLOCKING = @GNULIB_UNISTD_H_NONBLOCKING@ +GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@ +GNULIB_UNLINK = @GNULIB_UNLINK@ +GNULIB_UNLINKAT = @GNULIB_UNLINKAT@ +GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@ +GNULIB_UNSETENV = @GNULIB_UNSETENV@ +GNULIB_USLEEP = @GNULIB_USLEEP@ +GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@ +GNULIB_VASPRINTF = @GNULIB_VASPRINTF@ +GNULIB_VDPRINTF = @GNULIB_VDPRINTF@ +GNULIB_VFPRINTF = @GNULIB_VFPRINTF@ +GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@ +GNULIB_VFSCANF = @GNULIB_VFSCANF@ +GNULIB_VPRINTF = @GNULIB_VPRINTF@ +GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@ +GNULIB_VSCANF = @GNULIB_VSCANF@ +GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@ +GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@ +GNULIB_WCPCPY = @GNULIB_WCPCPY@ +GNULIB_WCPNCPY = @GNULIB_WCPNCPY@ +GNULIB_WCRTOMB = @GNULIB_WCRTOMB@ +GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@ +GNULIB_WCSCAT = @GNULIB_WCSCAT@ +GNULIB_WCSCHR = @GNULIB_WCSCHR@ +GNULIB_WCSCMP = @GNULIB_WCSCMP@ +GNULIB_WCSCOLL = @GNULIB_WCSCOLL@ +GNULIB_WCSCPY = @GNULIB_WCSCPY@ +GNULIB_WCSCSPN = @GNULIB_WCSCSPN@ +GNULIB_WCSDUP = @GNULIB_WCSDUP@ +GNULIB_WCSLEN = @GNULIB_WCSLEN@ +GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@ +GNULIB_WCSNCAT = @GNULIB_WCSNCAT@ +GNULIB_WCSNCMP = @GNULIB_WCSNCMP@ +GNULIB_WCSNCPY = @GNULIB_WCSNCPY@ +GNULIB_WCSNLEN = @GNULIB_WCSNLEN@ +GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@ +GNULIB_WCSPBRK = @GNULIB_WCSPBRK@ +GNULIB_WCSRCHR = @GNULIB_WCSRCHR@ +GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@ +GNULIB_WCSSPN = @GNULIB_WCSSPN@ +GNULIB_WCSSTR = @GNULIB_WCSSTR@ +GNULIB_WCSTOK = @GNULIB_WCSTOK@ +GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@ +GNULIB_WCSXFRM = @GNULIB_WCSXFRM@ +GNULIB_WCTOB = @GNULIB_WCTOB@ +GNULIB_WCTOMB = @GNULIB_WCTOMB@ +GNULIB_WCTRANS = @GNULIB_WCTRANS@ +GNULIB_WCTYPE = @GNULIB_WCTYPE@ +GNULIB_WCWIDTH = @GNULIB_WCWIDTH@ +GNULIB_WMEMCHR = @GNULIB_WMEMCHR@ +GNULIB_WMEMCMP = @GNULIB_WMEMCMP@ +GNULIB_WMEMCPY = @GNULIB_WMEMCPY@ +GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@ +GNULIB_WMEMSET = @GNULIB_WMEMSET@ +GNULIB_WRITE = @GNULIB_WRITE@ +GNULIB__EXIT = @GNULIB__EXIT@ +GREP = @GREP@ +HAVE_ALPHASORT = @HAVE_ALPHASORT@ +HAVE_ATOLL = @HAVE_ATOLL@ +HAVE_BTOWC = @HAVE_BTOWC@ +HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@ +HAVE_CHOWN = @HAVE_CHOWN@ +HAVE_CLOSEDIR = @HAVE_CLOSEDIR@ +HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@ +HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@ +HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@ +HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@ +HAVE_DECL_FDOPENDIR = @HAVE_DECL_FDOPENDIR@ +HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@ +HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@ +HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@ +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_R = @HAVE_DECL_GETLOGIN_R@ +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_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_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_TTYNAME_R = @HAVE_DECL_TTYNAME_R@ +HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@ +HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@ +HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@ +HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@ +HAVE_DIRENT_H = @HAVE_DIRENT_H@ +HAVE_DPRINTF = @HAVE_DPRINTF@ +HAVE_DUP2 = @HAVE_DUP2@ +HAVE_DUP3 = @HAVE_DUP3@ +HAVE_EUIDACCESS = @HAVE_EUIDACCESS@ +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_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_GETGROUPS = @HAVE_GETGROUPS@ +HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@ +HAVE_GETLOGIN = @HAVE_GETLOGIN@ +HAVE_GETOPT_H = @HAVE_GETOPT_H@ +HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@ +HAVE_GETSUBOPT = @HAVE_GETSUBOPT@ +HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@ +HAVE_GRANTPT = @HAVE_GRANTPT@ +HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_ISWBLANK = @HAVE_ISWBLANK@ +HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ +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_LINK = @HAVE_LINK@ +HAVE_LINKAT = @HAVE_LINKAT@ +HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +HAVE_LSTAT = @HAVE_LSTAT@ +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_MEMCHR = @HAVE_MEMCHR@ +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_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_OPENPT = @HAVE_POSIX_OPENPT@ +HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@ +HAVE_PREAD = @HAVE_PREAD@ +HAVE_PTHREAD_SIGMASK = @HAVE_PTHREAD_SIGMASK@ +HAVE_PTSNAME = @HAVE_PTSNAME@ +HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ +HAVE_PWRITE = @HAVE_PWRITE@ +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_REALPATH = @HAVE_REALPATH@ +HAVE_RENAMEAT = @HAVE_RENAMEAT@ +HAVE_REWINDDIR = @HAVE_REWINDDIR@ +HAVE_RPMATCH = @HAVE_RPMATCH@ +HAVE_SCANDIR = @HAVE_SCANDIR@ +HAVE_SETENV = @HAVE_SETENV@ +HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@ +HAVE_SIGACTION = @HAVE_SIGACTION@ +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_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_STRINGS_H = @HAVE_STRINGS_H@ +HAVE_STRPBRK = @HAVE_STRPBRK@ +HAVE_STRPTIME = @HAVE_STRPTIME@ +HAVE_STRSEP = @HAVE_STRSEP@ +HAVE_STRTOD = @HAVE_STRTOD@ +HAVE_STRTOLL = @HAVE_STRTOLL@ +HAVE_STRTOULL = @HAVE_STRTOULL@ +HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@ +HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@ +HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@ +HAVE_STRVERSCMP = @HAVE_STRVERSCMP@ +HAVE_SYMLINK = @HAVE_SYMLINK@ +HAVE_SYMLINKAT = @HAVE_SYMLINKAT@ +HAVE_SYSEXITS_H = @HAVE_SYSEXITS_H@ +HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@ +HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@ +HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_TIMEGM = @HAVE_TIMEGM@ +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_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +HAVE_USLEEP = @HAVE_USLEEP@ +HAVE_UTIMENSAT = @HAVE_UTIMENSAT@ +HAVE_VASPRINTF = @HAVE_VASPRINTF@ +HAVE_VDPRINTF = @HAVE_VDPRINTF@ +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_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_WMEMSET = @HAVE_WMEMSET@ +HAVE__BOOL = @HAVE__BOOL@ +HAVE__EXIT = @HAVE__EXIT@ +INCLUDE_NEXT = @INCLUDE_NEXT@ +INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ +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@ +LDFLAGS = @LDFLAGS@ +LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@ +LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIB_SETSOCKOPT = @LIB_SETSOCKOPT@ +LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ +LOCALE_FR = @LOCALE_FR@ +LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@ +LOCALE_JA = @LOCALE_JA@ +LOCALE_ZH_CN = @LOCALE_ZH_CN@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +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_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_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_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@ +NEXT_AS_FIRST_DIRECTIVE_STDARG_H = @NEXT_AS_FIRST_DIRECTIVE_STDARG_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_SYSEXITS_H = @NEXT_AS_FIRST_DIRECTIVE_SYSEXITS_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_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@ +NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_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_DIRENT_H = @NEXT_DIRENT_H@ +NEXT_ERRNO_H = @NEXT_ERRNO_H@ +NEXT_FCNTL_H = @NEXT_FCNTL_H@ +NEXT_FLOAT_H = @NEXT_FLOAT_H@ +NEXT_GETOPT_H = @NEXT_GETOPT_H@ +NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ +NEXT_LANGINFO_H = @NEXT_LANGINFO_H@ +NEXT_SIGNAL_H = @NEXT_SIGNAL_H@ +NEXT_STDARG_H = @NEXT_STDARG_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_SYSEXITS_H = @NEXT_SYSEXITS_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_TIME_H = @NEXT_TIME_H@ +NEXT_UNISTD_H = @NEXT_UNISTD_H@ +NEXT_WCHAR_H = @NEXT_WCHAR_H@ +NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ +OBJEXT = @OBJEXT@ +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@ +POSUB = @POSUB@ +PRAGMA_COLUMNS = @PRAGMA_COLUMNS@ +PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ +PRIPTR_PREFIX = @PRIPTR_PREFIX@ +PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ +PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@ +PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +PU_RMT_PROG = @PU_RMT_PROG@ +RANLIB = @RANLIB@ +REPLACE_BTOWC = @REPLACE_BTOWC@ +REPLACE_CALLOC = @REPLACE_CALLOC@ +REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@ +REPLACE_CHOWN = @REPLACE_CHOWN@ +REPLACE_CLOSE = @REPLACE_CLOSE@ +REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@ +REPLACE_DIRFD = @REPLACE_DIRFD@ +REPLACE_DPRINTF = @REPLACE_DPRINTF@ +REPLACE_DUP = @REPLACE_DUP@ +REPLACE_DUP2 = @REPLACE_DUP2@ +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_FOPEN = @REPLACE_FOPEN@ +REPLACE_FPRINTF = @REPLACE_FPRINTF@ +REPLACE_FPURGE = @REPLACE_FPURGE@ +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_FUTIMENS = @REPLACE_FUTIMENS@ +REPLACE_GETCWD = @REPLACE_GETCWD@ +REPLACE_GETDELIM = @REPLACE_GETDELIM@ +REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@ +REPLACE_GETGROUPS = @REPLACE_GETGROUPS@ +REPLACE_GETLINE = @REPLACE_GETLINE@ +REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@ +REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@ +REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_ISATTY = @REPLACE_ISATTY@ +REPLACE_ISWBLANK = @REPLACE_ISWBLANK@ +REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@ +REPLACE_ITOLD = @REPLACE_ITOLD@ +REPLACE_LCHOWN = @REPLACE_LCHOWN@ +REPLACE_LINK = @REPLACE_LINK@ +REPLACE_LINKAT = @REPLACE_LINKAT@ +REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@ +REPLACE_LSEEK = @REPLACE_LSEEK@ +REPLACE_LSTAT = @REPLACE_LSTAT@ +REPLACE_MALLOC = @REPLACE_MALLOC@ +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_MKNOD = @REPLACE_MKNOD@ +REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ +REPLACE_MKTIME = @REPLACE_MKTIME@ +REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ +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_PREAD = @REPLACE_PREAD@ +REPLACE_PRINTF = @REPLACE_PRINTF@ +REPLACE_PTHREAD_SIGMASK = @REPLACE_PTHREAD_SIGMASK@ +REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@ +REPLACE_PUTENV = @REPLACE_PUTENV@ +REPLACE_PWRITE = @REPLACE_PWRITE@ +REPLACE_RAISE = @REPLACE_RAISE@ +REPLACE_RANDOM_R = @REPLACE_RANDOM_R@ +REPLACE_READ = @REPLACE_READ@ +REPLACE_READLINK = @REPLACE_READLINK@ +REPLACE_REALLOC = @REPLACE_REALLOC@ +REPLACE_REALPATH = @REPLACE_REALPATH@ +REPLACE_REMOVE = @REPLACE_REMOVE@ +REPLACE_RENAME = @REPLACE_RENAME@ +REPLACE_RENAMEAT = @REPLACE_RENAMEAT@ +REPLACE_RMDIR = @REPLACE_RMDIR@ +REPLACE_SETENV = @REPLACE_SETENV@ +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_STRERROR_R = @REPLACE_STRERROR_R@ +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_SYMLINK = @REPLACE_SYMLINK@ +REPLACE_TIMEGM = @REPLACE_TIMEGM@ +REPLACE_TMPFILE = @REPLACE_TMPFILE@ +REPLACE_TOWLOWER = @REPLACE_TOWLOWER@ +REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@ +REPLACE_UNLINK = @REPLACE_UNLINK@ +REPLACE_UNLINKAT = @REPLACE_UNLINKAT@ +REPLACE_UNSETENV = @REPLACE_UNSETENV@ +REPLACE_USLEEP = @REPLACE_USLEEP@ +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_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@ +REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@ +REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@ +REPLACE_WCTOB = @REPLACE_WCTOB@ +REPLACE_WCTOMB = @REPLACE_WCTOMB@ +REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ +REPLACE_WRITE = @REPLACE_WRITE@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDALIGN_H = @STDALIGN_H@ +STDARG_H = @STDARG_H@ +STDBOOL_H = @STDBOOL_H@ +STDDEF_H = @STDDEF_H@ +STDINT_H = @STDINT_H@ +STRIP = @STRIP@ +SYSEXITS_H = @SYSEXITS_H@ +SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ +TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ +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_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@ +VERSION = @VERSION@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +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_LIBOBJS = @gl_LIBOBJS@ +gl_LTLIBOBJS = @gl_LTLIBOBJS@ +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@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +lispdir = @lispdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +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@ +AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects +SUBDIRS = +noinst_HEADERS = +noinst_LIBRARIES = libgnu.a +noinst_LTLIBRARIES = +EXTRA_DIST = alloca.c alloca.in.h allocator.h areadlink.h areadlink.h \ + at-func.c argmatch.h openat-priv.h openat-proc.c backupfile.h \ + btowc.c c-strcaseeq.h canonicalize-lgpl.c careadlinkat.h \ + chdir-long.c chdir-long.h chown.c fchown-stub.c cloexec.h \ + close.c close-stream.h closedir.c dirent-private.h closeout.h \ + dirent.in.h dirent--.h dirent-safer.h dirfd.c stripslash.c \ + dirname.h dosname.h dup.c dup2.c errno.in.h error.c error.h \ + exclude.h exitfail.h fchdir.c fcntl.c fcntl.in.h fd-hook.h \ + fdopendir.c utimens.h fileblocks.c filename.h filenamecat.h \ + float.c float.in.h itold.c fnmatch.c fnmatch.in.h \ + fnmatch_loop.c fpending.c fpending.h fseek.c fseeko.c \ + stdio-impl.h fstat.c at-func.c fstatat.c openat-priv.h \ + futimens.c getcwd.c getcwd-lgpl.c getdelim.c getdtablesize.c \ + getline.c getopt.c getopt.in.h getopt1.c getopt_int.h \ + getpagesize.c $(top_srcdir)/build-aux/config.rpath \ + gettimeofday.c $(top_srcdir)/build-aux/gitlog-to-changelog \ + hash.h $(top_srcdir)/build-aux/config.rpath human.h intprops.h \ + anytostr.c inttostr.h inttypes.in.h iswblank.c langinfo.in.h \ + lchown.c link.c at-func2.c linkat.c config.charset ref-add.sin \ + ref-del.sin lseek.c lstat.c malloc.c malloc.c malloca.h \ + malloca.valgrind mbchar.h mbrtowc.c mbsinit.c mbsrtowcs-impl.h \ + mbsrtowcs-state.c mbsrtowcs.c mbtowc-impl.h mbtowc.c memchr.c \ + memchr.valgrind mempcpy.c memrchr.c mkdtemp.c mkfifo.c \ + at-func.c mkfifoat.c mknodat.c mknod.c mktime-internal.h \ + mktime.c modechange.h msvc-inval.c msvc-inval.h msvc-nothrow.c \ + msvc-nothrow.h nl_langinfo.c obstack.c obstack.h open.c \ + openat-priv.h openat.c openat.h dirent-private.h opendir.c \ + parse-datetime.c parse-datetime.h pathmax.h priv-set.h quote.h \ + quotearg.h raise.c rawmemchr.c rawmemchr.valgrind read.c \ + dirent-private.h readdir.c readlink.c at-func.c readlinkat.c \ + realloc.c regcomp.c regex.c regex.h regex_internal.c \ + regex_internal.h regexec.c rename.c at-func2.c renameat.c \ + dirent-private.h rewinddir.c rmdir.c rpmatch.c safe-read.h \ + safe-read.c safe-write.h same-inode.h save-cwd.h savedir.h \ + setenv.c signal.in.h sleep.c \ + $(top_srcdir)/build-aux/snippet/_Noreturn.h \ + $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ + $(top_srcdir)/build-aux/snippet/c++defs.h \ + $(top_srcdir)/build-aux/snippet/warn-on-use.h snprintf.c \ + stat.c stat-macros.h stat-time.h stdalign.in.h stdarg.in.h \ + stdbool.in.h stddef.in.h stdint.in.h stdio.in.h stdlib.in.h \ + stpcpy.c strcasecmp.c strncasecmp.c strchrnul.c \ + strchrnul.valgrind strdup.c streq.h strerror.c \ + strerror-override.c strerror-override.h string.in.h \ + strings.in.h strndup.c strnlen.c strtol.c strtol.c strtoul.c \ + strtol.c strtoul.c strtoull.c strtoimax.c strtoumax.c \ + symlink.c at-func.c symlinkat.c sys_stat.in.h sys_time.in.h \ + sys_types.in.h sysexits.in.h tempname.h time.in.h time_r.c \ + timespec.h unistd.in.h unistd--.h unistd-safer.h unitypes.in.h \ + localcharset.h uniwidth.in.h uniwidth/cjk.h unlinkdir.h \ + unlocked-io.h unsetenv.c utimens.h at-func.c utimensat.c \ + asnprintf.c float+.h printf-args.c printf-args.h \ + printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h \ + asprintf.c vasprintf.c verify.h vsnprintf.c wchar.in.h \ + wcrtomb.c wctype.in.h wcwidth.c write.c xalloc.h \ + xalloc-oversized.h xgetcwd.h xstrtol.h xalloc.h + +# The BUILT_SOURCES created by this Makefile snippet are not used via #include +# statements but through direct file reference. Therefore this snippet must be +# present in all Makefile.am that need it. This is ensured by the applicability +# 'all' defined above. + +# The BUILT_SOURCES created by this Makefile snippet are not used via #include +# statements but through direct file reference. Therefore this snippet must be +# present in all Makefile.am that need it. This is ensured by the applicability +# 'all' defined above. +BUILT_SOURCES = $(ALLOCA_H) configmake.h dirent.h $(ERRNO_H) fcntl.h \ + $(FLOAT_H) $(FNMATCH_H) $(GETOPT_H) inttypes.h langinfo.h \ + parse-datetime.c signal.h arg-nonnull.h c++defs.h \ + warn-on-use.h $(STDALIGN_H) $(STDARG_H) $(STDBOOL_H) \ + $(STDDEF_H) $(STDINT_H) stdio.h stdlib.h string.h strings.h \ + sys/stat.h sys/time.h sys/types.h $(SYSEXITS_H) time.h \ + unistd.h $(LIBUNISTRING_UNITYPES_H) $(LIBUNISTRING_UNIWIDTH_H) \ + wchar.h wctype.h +SUFFIXES = .sed .sin +MOSTLYCLEANFILES = core *.stackdump alloca.h alloca.h-t dirent.h \ + dirent.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 inttypes.h \ + inttypes.h-t langinfo.h langinfo.h-t parse-datetime.c-t \ + signal.h signal.h-t arg-nonnull.h arg-nonnull.h-t c++defs.h \ + c++defs.h-t warn-on-use.h warn-on-use.h-t stdalign.h \ + stdalign.h-t stdarg.h stdarg.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/stat.h sys/stat.h-t sys/time.h sys/time.h-t sys/types.h \ + sys/types.h-t sysexits.h sysexits.h-t time.h time.h-t unistd.h \ + unistd.h-t unitypes.h unitypes.h-t uniwidth.h uniwidth.h-t \ + wchar.h wchar.h-t wctype.h wctype.h-t +MOSTLYCLEANDIRS = sys +CLEANFILES = configmake.h configmake.h-t charset.alias ref-add.sed \ + ref-del.sed +DISTCLEANFILES = +MAINTAINERCLEANFILES = parse-datetime.c + +# This is for those projects which use "gettextize --intl" to put a source-code +# copy of libintl into their package. In such projects, every Makefile.am needs +# -I$(top_builddir)/intl, so that <libintl.h> can be found in this directory. +# For the Makefile.ams in other directories it is the maintainer's +# responsibility; for the one from gnulib we do it here. +# This option has no effect when the user disables NLS (because then the intl +# directory contains no libintl.h file) or when the project does not use +# "gettextize --intl". +AM_CPPFLAGS = -I$(top_builddir)/intl +AM_CFLAGS = +libgnu_a_SOURCES = allocator.c areadlink.c areadlinkat.c argmatch.c \ + argp.h argp-ba.c argp-eexst.c argp-fmtstream.c \ + argp-fmtstream.h argp-fs-xinl.c argp-help.c argp-namefrob.h \ + argp-parse.c argp-pin.c argp-pv.c argp-pvh.c argp-xinl.c \ + argp-version-etc.h argp-version-etc.c backupfile.c bitrotate.h \ + c-ctype.h c-ctype.c c-strcase.h c-strcasecmp.c c-strncasecmp.c \ + careadlinkat.c cloexec.c close-stream.c closeout.c \ + opendir-safer.c dirname.c basename.c dirname-lgpl.c \ + basename-lgpl.c stripslash.c exclude.c exitfail.c fd-hook.c \ + fdutimensat.c filenamecat-lgpl.c full-write.h full-write.c \ + gettext.h gettime.c hash.c human.c imaxtostr.c inttostr.c \ + offtostr.c uinttostr.c umaxtostr.c localcharset.h \ + localcharset.c malloca.c mbchar.c mbscasecmp.c mbuiter.h \ + modechange.c openat-die.c parse-datetime.y priv-set.c \ + progname.h progname.c quote.c quotearg.c safe-read.c \ + safe-write.c save-cwd.c savedir.c size_max.h strnlen1.h \ + strnlen1.c tempname.c dup-safer.c fd-safer.c pipe-safer.c \ + $(am__append_1) unlinkdir.c utimens.c version-etc.h \ + version-etc.c version-etc-fsf.c xmalloc.c xalloc-die.c \ + xgetcwd.c xsize.h xstrndup.h xstrndup.c xstrtol.c xstrtoul.c \ + xstrtol-error.c xstrtoumax.c xvasprintf.h xvasprintf.c \ + xasprintf.c +libgnu_a_LIBADD = $(gl_LIBOBJS) @ALLOCA@ +libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) @ALLOCA@ +EXTRA_libgnu_a_SOURCES = alloca.c at-func.c openat-proc.c btowc.c \ + canonicalize-lgpl.c chdir-long.c chown.c fchown-stub.c close.c \ + closedir.c dirfd.c stripslash.c dup.c dup2.c error.c fchdir.c \ + fcntl.c fdopendir.c fileblocks.c float.c itold.c fnmatch.c \ + fnmatch_loop.c fpending.c fseek.c fseeko.c fstat.c at-func.c \ + fstatat.c futimens.c getcwd.c getcwd-lgpl.c getdelim.c \ + getdtablesize.c getline.c getopt.c getopt1.c getpagesize.c \ + gettimeofday.c anytostr.c iswblank.c lchown.c link.c \ + at-func2.c linkat.c lseek.c lstat.c malloc.c malloc.c \ + mbrtowc.c mbsinit.c mbsrtowcs-state.c mbsrtowcs.c mbtowc.c \ + memchr.c mempcpy.c memrchr.c mkdtemp.c mkfifo.c at-func.c \ + mkfifoat.c mknodat.c mknod.c mktime.c msvc-inval.c \ + msvc-nothrow.c nl_langinfo.c obstack.c open.c openat.c \ + opendir.c raise.c rawmemchr.c read.c readdir.c readlink.c \ + at-func.c readlinkat.c realloc.c regcomp.c regex.c \ + regex_internal.c regexec.c rename.c at-func2.c renameat.c \ + rewinddir.c rmdir.c rpmatch.c safe-read.c setenv.c sleep.c \ + snprintf.c stat.c stpcpy.c strcasecmp.c strncasecmp.c \ + strchrnul.c strdup.c strerror.c strerror-override.c strndup.c \ + strnlen.c strtol.c strtol.c strtoul.c strtol.c strtoul.c \ + strtoull.c strtoimax.c strtoumax.c symlink.c at-func.c \ + symlinkat.c time_r.c unsetenv.c at-func.c utimensat.c \ + asnprintf.c printf-args.c printf-parse.c vasnprintf.c \ + asprintf.c vasprintf.c vsnprintf.c wcrtomb.c wcwidth.c write.c +charset_alias = $(DESTDIR)$(libdir)/charset.alias +charset_tmp = $(DESTDIR)$(libdir)/charset.tmp + +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all Makefile.am that +# need it. This is ensured by the applicability 'all' defined above. +_NORETURN_H = $(top_srcdir)/build-aux/snippet/_Noreturn.h +ARG_NONNULL_H = arg-nonnull.h +CXXDEFS_H = c++defs.h +WARN_ON_USE_H = warn-on-use.h +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .sed .sin .c .o .obj .y +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --gnits gnu/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnits gnu/Makefile +.PRECIOUS: 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__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(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) +uniwidth/$(am__dirstamp): + @$(MKDIR_P) uniwidth + @: > uniwidth/$(am__dirstamp) +uniwidth/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) uniwidth/$(DEPDIR) + @: > uniwidth/$(DEPDIR)/$(am__dirstamp) +uniwidth/width.$(OBJEXT): uniwidth/$(am__dirstamp) \ + uniwidth/$(DEPDIR)/$(am__dirstamp) +libgnu.a: $(libgnu_a_OBJECTS) $(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 + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f uniwidth/width.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/alloca.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloca.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allocator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anytostr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/areadlink.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/areadlinkat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argmatch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-ba.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-eexst.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-fmtstream.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-fs-xinl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-help.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-parse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-pin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-pv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-pvh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-version-etc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-xinl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asnprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/at-func.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/at-func2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backupfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basename-lgpl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basename.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btowc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-ctype.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-strcasecmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-strncasecmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/canonicalize-lgpl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/careadlinkat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chdir-long.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chown.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cloexec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/close-stream.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/close.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closedir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closeout.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirfd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirname-lgpl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dup-safer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dup2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exclude.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exitfail.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fchdir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fchown-stub.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcntl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd-hook.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd-safer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdopendir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdutimensat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileblocks.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filenamecat-lgpl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/float.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnmatch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnmatch_loop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fpending.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fseek.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fseeko.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstatat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/full-write.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/futimens.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcwd-lgpl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcwd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdelim.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdtablesize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getpagesize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettimeofday.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/human.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imaxtostr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inttostr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iswblank.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/itold.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lchown.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linkat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localcharset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lseek.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloca.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbchar.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbrtowc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbscasecmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbsinit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbsrtowcs-state.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbsrtowcs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbtowc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memchr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mempcpy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memrchr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkdtemp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkfifo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkfifoat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mknod.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mknodat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mktime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modechange.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msvc-inval.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msvc-nothrow.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl_langinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/obstack.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/offtostr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openat-die.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openat-proc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opendir-safer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opendir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse-datetime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipe-safer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf-args.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf-parse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/priv-set.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/progname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quote.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quotearg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raise.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rawmemchr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readdir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readlink.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readlinkat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realloc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regcomp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex_internal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regexec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rename.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/renameat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rewinddir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmdir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpmatch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safe-read.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safe-write.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/save-cwd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/savedir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setenv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sleep.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stpcpy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strcasecmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strchrnul.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strdup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strerror-override.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strerror.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stripslash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strncasecmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strndup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnlen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnlen1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoimax.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtol.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoul.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoull.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoumax.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symlink.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symlinkat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tempname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_r.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uinttostr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/umaxtostr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unlinkdir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unsetenv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utimens.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utimensat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vasnprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vasprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version-etc-fsf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version-etc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsnprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcrtomb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcwidth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/write.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xalloc-die.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xasprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetcwd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmalloc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrndup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrtol-error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrtol.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrtoul.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrtoumax.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xvasprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@uniwidth/$(DEPDIR)/width.Po@am__quote@ + +.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 +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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 +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.y.c: + $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(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 + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS) all-local +installdirs: installdirs-recursive +installdirs-am: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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 uniwidth/$(DEPDIR)/$(am__dirstamp) + -rm -f uniwidth/$(am__dirstamp) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f parse-datetime.c + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-noinstLIBRARIES clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf $(DEPDIR) ./$(DEPDIR) uniwidth/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-exec-local + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf $(DEPDIR) ./$(DEPDIR) uniwidth/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-local + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-local + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ + ctags-recursive install install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am all-local check check-am clean clean-generic \ + clean-noinstLIBRARIES clean-noinstLTLIBRARIES ctags \ + ctags-recursive distclean distclean-compile distclean-generic \ + 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-exec-local \ + 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 installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-local pdf pdf-am ps ps-am tags \ + tags-recursive uninstall uninstall-am uninstall-local + + +# We need the following in order to create <alloca.h> 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@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_ALLOCA_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +@GL_GENERATE_ALLOCA_H_TRUE@ cat $(srcdir)/alloca.in.h; \ +@GL_GENERATE_ALLOCA_H_TRUE@ } > $@-t && \ +@GL_GENERATE_ALLOCA_H_TRUE@ mv -f $@-t $@ +@GL_GENERATE_ALLOCA_H_FALSE@alloca.h: $(top_builddir)/config.status +@GL_GENERATE_ALLOCA_H_FALSE@ rm -f $@ + +# Listed in the same order as the GNU makefile conventions, and +# provided by autoconf 2.59c+. +# The Automake-defined pkg* macros are appended, in the order +# listed in the Automake 1.10a+ documentation. +configmake.h: Makefile + $(AM_V_GEN)rm -f $@-t && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + echo '#define PREFIX "$(prefix)"'; \ + echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ + echo '#define BINDIR "$(bindir)"'; \ + echo '#define SBINDIR "$(sbindir)"'; \ + echo '#define LIBEXECDIR "$(libexecdir)"'; \ + echo '#define DATAROOTDIR "$(datarootdir)"'; \ + echo '#define DATADIR "$(datadir)"'; \ + echo '#define SYSCONFDIR "$(sysconfdir)"'; \ + echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \ + echo '#define LOCALSTATEDIR "$(localstatedir)"'; \ + echo '#define INCLUDEDIR "$(includedir)"'; \ + echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \ + echo '#define DOCDIR "$(docdir)"'; \ + echo '#define INFODIR "$(infodir)"'; \ + echo '#define HTMLDIR "$(htmldir)"'; \ + echo '#define DVIDIR "$(dvidir)"'; \ + echo '#define PDFDIR "$(pdfdir)"'; \ + echo '#define PSDIR "$(psdir)"'; \ + echo '#define LIBDIR "$(libdir)"'; \ + echo '#define LISPDIR "$(lispdir)"'; \ + echo '#define LOCALEDIR "$(localedir)"'; \ + echo '#define MANDIR "$(mandir)"'; \ + echo '#define MANEXT "$(manext)"'; \ + echo '#define PKGDATADIR "$(pkgdatadir)"'; \ + echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \ + echo '#define PKGLIBDIR "$(pkglibdir)"'; \ + echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ + } | sed '/""/d' > $@-t + mv -f $@-t $@ + +# We need the following in order to create <dirent.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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''@/$(GNULIB_OPENDIR)/g' \ + -e 's/@''GNULIB_READDIR''@/$(GNULIB_READDIR)/g' \ + -e 's/@''GNULIB_REWINDDIR''@/$(GNULIB_REWINDDIR)/g' \ + -e 's/@''GNULIB_CLOSEDIR''@/$(GNULIB_CLOSEDIR)/g' \ + -e 's/@''GNULIB_DIRFD''@/$(GNULIB_DIRFD)/g' \ + -e 's/@''GNULIB_FDOPENDIR''@/$(GNULIB_FDOPENDIR)/g' \ + -e 's/@''GNULIB_SCANDIR''@/$(GNULIB_SCANDIR)/g' \ + -e 's/@''GNULIB_ALPHASORT''@/$(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 && \ + mv $@-t $@ + +# We need the following in order to create <errno.h> 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@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_ERRNO_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +@GL_GENERATE_ERRNO_H_TRUE@ sed -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; \ +@GL_GENERATE_ERRNO_H_TRUE@ } > $@-t && \ +@GL_GENERATE_ERRNO_H_TRUE@ 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 <fcntl.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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_FCNTL''@/$(GNULIB_FCNTL)/g' \ + -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \ + -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \ + -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \ + -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \ + -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|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 && \ + mv $@-t $@ + +# We need the following in order to create <float.h> 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@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_FLOAT_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +@GL_GENERATE_FLOAT_H_TRUE@ sed -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; \ +@GL_GENERATE_FLOAT_H_TRUE@ } > $@-t && \ +@GL_GENERATE_FLOAT_H_TRUE@ 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 <fnmatch.h> when the system +# doesn't have one that supports the required API. +@GL_GENERATE_FNMATCH_H_TRUE@fnmatch.h: fnmatch.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) +@GL_GENERATE_FNMATCH_H_TRUE@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_FNMATCH_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +@GL_GENERATE_FNMATCH_H_TRUE@ sed -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ +@GL_GENERATE_FNMATCH_H_TRUE@ < $(srcdir)/fnmatch.in.h; \ +@GL_GENERATE_FNMATCH_H_TRUE@ } > $@-t && \ +@GL_GENERATE_FNMATCH_H_TRUE@ mv -f $@-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 <getopt.h> when the system +# doesn't have one that works with the given compiler. +getopt.h: getopt.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_GETOPT_H''@|$(HAVE_GETOPT_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_GETOPT_H''@|$(NEXT_GETOPT_H)|g' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + < $(srcdir)/getopt.in.h; \ + } > $@-t && \ + mv -f $@-t $@ + +# We need the following in order to create <inttypes.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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/@''PRI_MACROS_BROKEN''@/$(PRI_MACROS_BROKEN)/g' \ + -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ + -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ + -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ + -e 's/@''PRIPTR_PREFIX''@/$(PRIPTR_PREFIX)/g' \ + -e 's/@''GNULIB_IMAXABS''@/$(GNULIB_IMAXABS)/g' \ + -e 's/@''GNULIB_IMAXDIV''@/$(GNULIB_IMAXDIV)/g' \ + -e 's/@''GNULIB_STRTOIMAX''@/$(GNULIB_STRTOIMAX)/g' \ + -e 's/@''GNULIB_STRTOUMAX''@/$(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/@''REPLACE_STRTOIMAX''@/$(REPLACE_STRTOIMAX)/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 && \ + mv $@-t $@ + +# We need the following in order to create an empty placeholder for +# <langinfo.h> when the system doesn't have one. +langinfo.h: langinfo.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_LANGINFO_H''@|$(NEXT_LANGINFO_H)|g' \ + -e 's/@''GNULIB_NL_LANGINFO''@/$(GNULIB_NL_LANGINFO)/g' \ + -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \ + -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \ + -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \ + -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \ + -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \ + -e 's|@''REPLACE_NL_LANGINFO''@|$(REPLACE_NL_LANGINFO)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/langinfo.in.h; \ + } > $@-t && \ + mv $@-t $@ + +# We need the following in order to install a simple file in $(libdir) +# which is shared with other installed packages. We use a list of referencing +# packages so that "make uninstall" will remove the file if and only if it +# is not used by another installed package. +# On systems with glibc-2.1 or newer, the file is redundant, therefore we +# avoid installing it. + +all-local: charset.alias ref-add.sed ref-del.sed +install-exec-local: install-exec-localcharset +install-exec-localcharset: all-local + if test $(GLIBC21) = no; then \ + case '$(host_os)' in \ + darwin[56]*) \ + need_charset_alias=true ;; \ + darwin* | cygwin* | mingw* | pw32* | cegcc*) \ + need_charset_alias=false ;; \ + *) \ + need_charset_alias=true ;; \ + esac ; \ + else \ + need_charset_alias=false ; \ + fi ; \ + if $$need_charset_alias; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ + fi ; \ + if test -f $(charset_alias); then \ + sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + else \ + if $$need_charset_alias; then \ + sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + fi ; \ + fi + +uninstall-local: uninstall-localcharset +uninstall-localcharset: all-local + if test -f $(charset_alias); then \ + sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ + if grep '^# Packages using this file: $$' $(charset_tmp) \ + > /dev/null; then \ + rm -f $(charset_alias); \ + else \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ + fi; \ + rm -f $(charset_tmp); \ + fi + +charset.alias: config.charset + $(AM_V_GEN)rm -f t-$@ $@ && \ + $(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \ + mv t-$@ $@ +.sin.sed: + $(AM_V_GEN)rm -f t-$@ $@ && \ + sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \ + mv t-$@ $@ + +# This rule overrides the Automake generated .y.c rule, to ensure that the +# parse-datetime.c file gets generated in the source directory, not in the +# build directory. +parse-datetime.c: parse-datetime.y + $(AM_V_GEN)$(SHELL) $(YLWRAP) $(srcdir)/parse-datetime.y \ + y.tab.c parse-datetime.c \ + y.tab.h parse-datetime.h \ + y.output parse-datetime.output \ + -- $(YACC) $(YFLAGS) $(AM_YFLAGS) && \ + mv parse-datetime.c parse-datetime.c-t && \ + mv parse-datetime.c-t $(srcdir)/parse-datetime.c + +# We need the following in order to create <signal.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -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''@|$(GNULIB_PTHREAD_SIGMASK)|g' \ + -e 's|@''GNULIB_RAISE''@|$(GNULIB_RAISE)|g' \ + -e 's/@''GNULIB_SIGNAL_H_SIGPIPE''@/$(GNULIB_SIGNAL_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_SIGPROCMASK''@/$(GNULIB_SIGPROCMASK)/g' \ + -e 's/@''GNULIB_SIGACTION''@/$(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 && \ + mv $@-t $@ +# The arg-nonnull.h that gets inserted into generated .h files is the same as +# build-aux/snippet/arg-nonnull.h, except that it has the copyright header cut +# off. +arg-nonnull.h: $(top_srcdir)/build-aux/snippet/arg-nonnull.h + $(AM_V_GEN)rm -f $@-t $@ && \ + sed -n -e '/GL_ARG_NONNULL/,$$p' \ + < $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ + > $@-t && \ + mv $@-t $@ +# The c++defs.h that gets inserted into generated .h files is the same as +# build-aux/snippet/c++defs.h, except that it has the copyright header cut off. +c++defs.h: $(top_srcdir)/build-aux/snippet/c++defs.h + $(AM_V_GEN)rm -f $@-t $@ && \ + sed -n -e '/_GL_CXXDEFS/,$$p' \ + < $(top_srcdir)/build-aux/snippet/c++defs.h \ + > $@-t && \ + mv $@-t $@ +# The warn-on-use.h that gets inserted into generated .h files is the same as +# build-aux/snippet/warn-on-use.h, except that it has the copyright header cut +# off. +warn-on-use.h: $(top_srcdir)/build-aux/snippet/warn-on-use.h + $(AM_V_GEN)rm -f $@-t $@ && \ + sed -n -e '/^.ifndef/,$$p' \ + < $(top_srcdir)/build-aux/snippet/warn-on-use.h \ + > $@-t && \ + mv $@-t $@ + +# We need the following in order to create <stdalign.h> 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@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_STDALIGN_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +@GL_GENERATE_STDALIGN_H_TRUE@ cat $(srcdir)/stdalign.in.h; \ +@GL_GENERATE_STDALIGN_H_TRUE@ } > $@-t && \ +@GL_GENERATE_STDALIGN_H_TRUE@ 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 <stdarg.h> when the system +# doesn't have one that works with the given compiler. +@GL_GENERATE_STDARG_H_TRUE@stdarg.h: stdarg.in.h $(top_builddir)/config.status +@GL_GENERATE_STDARG_H_TRUE@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_STDARG_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +@GL_GENERATE_STDARG_H_TRUE@ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_STDARG_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_STDARG_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_STDARG_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_STDARG_H_TRUE@ -e 's|@''NEXT_STDARG_H''@|$(NEXT_STDARG_H)|g' \ +@GL_GENERATE_STDARG_H_TRUE@ < $(srcdir)/stdarg.in.h; \ +@GL_GENERATE_STDARG_H_TRUE@ } > $@-t && \ +@GL_GENERATE_STDARG_H_TRUE@ mv $@-t $@ +@GL_GENERATE_STDARG_H_FALSE@stdarg.h: $(top_builddir)/config.status +@GL_GENERATE_STDARG_H_FALSE@ rm -f $@ + +# We need the following in order to create <stdbool.h> 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@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_STDBOOL_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +@GL_GENERATE_STDBOOL_H_TRUE@ sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \ +@GL_GENERATE_STDBOOL_H_TRUE@ } > $@-t && \ +@GL_GENERATE_STDBOOL_H_TRUE@ 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 <stddef.h> 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@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_STDDEF_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +@GL_GENERATE_STDDEF_H_TRUE@ sed -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_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; \ +@GL_GENERATE_STDDEF_H_TRUE@ } > $@-t && \ +@GL_GENERATE_STDDEF_H_TRUE@ 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 <stdint.h> 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@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_STDINT_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +@GL_GENERATE_STDINT_H_TRUE@ sed -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_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/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/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@ < $(srcdir)/stdint.in.h; \ +@GL_GENERATE_STDINT_H_TRUE@ } > $@-t && \ +@GL_GENERATE_STDINT_H_TRUE@ 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 <stdio.h> when the system +# doesn't have one that works with the given compiler. +stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ + -e 's/@''GNULIB_DPRINTF''@/$(GNULIB_DPRINTF)/g' \ + -e 's/@''GNULIB_FCLOSE''@/$(GNULIB_FCLOSE)/g' \ + -e 's/@''GNULIB_FDOPEN''@/$(GNULIB_FDOPEN)/g' \ + -e 's/@''GNULIB_FFLUSH''@/$(GNULIB_FFLUSH)/g' \ + -e 's/@''GNULIB_FGETC''@/$(GNULIB_FGETC)/g' \ + -e 's/@''GNULIB_FGETS''@/$(GNULIB_FGETS)/g' \ + -e 's/@''GNULIB_FOPEN''@/$(GNULIB_FOPEN)/g' \ + -e 's/@''GNULIB_FPRINTF''@/$(GNULIB_FPRINTF)/g' \ + -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GNULIB_FPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_FPURGE''@/$(GNULIB_FPURGE)/g' \ + -e 's/@''GNULIB_FPUTC''@/$(GNULIB_FPUTC)/g' \ + -e 's/@''GNULIB_FPUTS''@/$(GNULIB_FPUTS)/g' \ + -e 's/@''GNULIB_FREAD''@/$(GNULIB_FREAD)/g' \ + -e 's/@''GNULIB_FREOPEN''@/$(GNULIB_FREOPEN)/g' \ + -e 's/@''GNULIB_FSCANF''@/$(GNULIB_FSCANF)/g' \ + -e 's/@''GNULIB_FSEEK''@/$(GNULIB_FSEEK)/g' \ + -e 's/@''GNULIB_FSEEKO''@/$(GNULIB_FSEEKO)/g' \ + -e 's/@''GNULIB_FTELL''@/$(GNULIB_FTELL)/g' \ + -e 's/@''GNULIB_FTELLO''@/$(GNULIB_FTELLO)/g' \ + -e 's/@''GNULIB_FWRITE''@/$(GNULIB_FWRITE)/g' \ + -e 's/@''GNULIB_GETC''@/$(GNULIB_GETC)/g' \ + -e 's/@''GNULIB_GETCHAR''@/$(GNULIB_GETCHAR)/g' \ + -e 's/@''GNULIB_GETDELIM''@/$(GNULIB_GETDELIM)/g' \ + -e 's/@''GNULIB_GETLINE''@/$(GNULIB_GETLINE)/g' \ + -e 's/@''GNULIB_GETS''@/$(GNULIB_GETS)/g' \ + -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GNULIB_OBSTACK_PRINTF)/g' \ + -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GNULIB_OBSTACK_PRINTF_POSIX)/g' \ + -e 's/@''GNULIB_PCLOSE''@/$(GNULIB_PCLOSE)/g' \ + -e 's/@''GNULIB_PERROR''@/$(GNULIB_PERROR)/g' \ + -e 's/@''GNULIB_POPEN''@/$(GNULIB_POPEN)/g' \ + -e 's/@''GNULIB_PRINTF''@/$(GNULIB_PRINTF)/g' \ + -e 's/@''GNULIB_PRINTF_POSIX''@/$(GNULIB_PRINTF_POSIX)/g' \ + -e 's/@''GNULIB_PUTC''@/$(GNULIB_PUTC)/g' \ + -e 's/@''GNULIB_PUTCHAR''@/$(GNULIB_PUTCHAR)/g' \ + -e 's/@''GNULIB_PUTS''@/$(GNULIB_PUTS)/g' \ + -e 's/@''GNULIB_REMOVE''@/$(GNULIB_REMOVE)/g' \ + -e 's/@''GNULIB_RENAME''@/$(GNULIB_RENAME)/g' \ + -e 's/@''GNULIB_RENAMEAT''@/$(GNULIB_RENAMEAT)/g' \ + -e 's/@''GNULIB_SCANF''@/$(GNULIB_SCANF)/g' \ + -e 's/@''GNULIB_SNPRINTF''@/$(GNULIB_SNPRINTF)/g' \ + -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GNULIB_SPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GNULIB_STDIO_H_NONBLOCKING)/g' \ + -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \ + -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \ + -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \ + -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \ + -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_VFSCANF''@/$(GNULIB_VFSCANF)/g' \ + -e 's/@''GNULIB_VSCANF''@/$(GNULIB_VSCANF)/g' \ + -e 's/@''GNULIB_VPRINTF''@/$(GNULIB_VPRINTF)/g' \ + -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \ + -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ + < $(srcdir)/stdio.in.h | \ + sed -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_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 && \ + mv $@-t $@ + +# We need the following in order to create <stdlib.h> 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) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ + -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \ + -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \ + -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \ + -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ + -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \ + -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \ + -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \ + -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \ + -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \ + -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \ + -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \ + -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \ + -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \ + -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ + -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \ + -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ + -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \ + -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ + -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ + -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \ + -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ + -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \ + -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ + -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \ + -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \ + -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \ + -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ + -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ + -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ + < $(srcdir)/stdlib.in.h | \ + sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ + -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ + -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|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_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_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \ + -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \ + -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_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_REALPATH''@|$(HAVE_REALPATH)|g' \ + -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ + -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \ + -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ + -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ + -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ + -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \ + -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ + -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \ + -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \ + -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \ + -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \ + -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \ + -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ + -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \ + -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ + -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ + -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ + -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ + -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \ + -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ + -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ + -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _Noreturn/r $(_NORETURN_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ + +# We need the following in order to create <string.h> when the system +# doesn't have one that works with the given compiler. +string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \ + -e 's/@''GNULIB_FFSL''@/$(GNULIB_FFSL)/g' \ + -e 's/@''GNULIB_FFSLL''@/$(GNULIB_FFSLL)/g' \ + -e 's/@''GNULIB_MBSLEN''@/$(GNULIB_MBSLEN)/g' \ + -e 's/@''GNULIB_MBSNLEN''@/$(GNULIB_MBSNLEN)/g' \ + -e 's/@''GNULIB_MBSCHR''@/$(GNULIB_MBSCHR)/g' \ + -e 's/@''GNULIB_MBSRCHR''@/$(GNULIB_MBSRCHR)/g' \ + -e 's/@''GNULIB_MBSSTR''@/$(GNULIB_MBSSTR)/g' \ + -e 's/@''GNULIB_MBSCASECMP''@/$(GNULIB_MBSCASECMP)/g' \ + -e 's/@''GNULIB_MBSNCASECMP''@/$(GNULIB_MBSNCASECMP)/g' \ + -e 's/@''GNULIB_MBSPCASECMP''@/$(GNULIB_MBSPCASECMP)/g' \ + -e 's/@''GNULIB_MBSCASESTR''@/$(GNULIB_MBSCASESTR)/g' \ + -e 's/@''GNULIB_MBSCSPN''@/$(GNULIB_MBSCSPN)/g' \ + -e 's/@''GNULIB_MBSPBRK''@/$(GNULIB_MBSPBRK)/g' \ + -e 's/@''GNULIB_MBSSPN''@/$(GNULIB_MBSSPN)/g' \ + -e 's/@''GNULIB_MBSSEP''@/$(GNULIB_MBSSEP)/g' \ + -e 's/@''GNULIB_MBSTOK_R''@/$(GNULIB_MBSTOK_R)/g' \ + -e 's/@''GNULIB_MEMCHR''@/$(GNULIB_MEMCHR)/g' \ + -e 's/@''GNULIB_MEMMEM''@/$(GNULIB_MEMMEM)/g' \ + -e 's/@''GNULIB_MEMPCPY''@/$(GNULIB_MEMPCPY)/g' \ + -e 's/@''GNULIB_MEMRCHR''@/$(GNULIB_MEMRCHR)/g' \ + -e 's/@''GNULIB_RAWMEMCHR''@/$(GNULIB_RAWMEMCHR)/g' \ + -e 's/@''GNULIB_STPCPY''@/$(GNULIB_STPCPY)/g' \ + -e 's/@''GNULIB_STPNCPY''@/$(GNULIB_STPNCPY)/g' \ + -e 's/@''GNULIB_STRCHRNUL''@/$(GNULIB_STRCHRNUL)/g' \ + -e 's/@''GNULIB_STRDUP''@/$(GNULIB_STRDUP)/g' \ + -e 's/@''GNULIB_STRNCAT''@/$(GNULIB_STRNCAT)/g' \ + -e 's/@''GNULIB_STRNDUP''@/$(GNULIB_STRNDUP)/g' \ + -e 's/@''GNULIB_STRNLEN''@/$(GNULIB_STRNLEN)/g' \ + -e 's/@''GNULIB_STRPBRK''@/$(GNULIB_STRPBRK)/g' \ + -e 's/@''GNULIB_STRSEP''@/$(GNULIB_STRSEP)/g' \ + -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \ + -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \ + -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \ + -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \ + -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \ + -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \ + -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \ + < $(srcdir)/string.in.h | \ + sed -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ + -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \ + -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \ + -e 's|@''HAVE_MEMCHR''@|$(HAVE_MEMCHR)|g' \ + -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ + -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ + -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ + -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_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ + -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ + -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \ + -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ + -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ + -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ + -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \ + -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ + -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ + -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ + -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ + -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ + -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ + -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \ + -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ + -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \ + -e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + < $(srcdir)/string.in.h; \ + } > $@-t && \ + mv $@-t $@ + +# We need the following in order to create <strings.h> when the system +# doesn't have one that works with the given compiler. +strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_STRINGS_H''@|$(HAVE_STRINGS_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \ + -e 's|@''GNULIB_FFS''@|$(GNULIB_FFS)|g' \ + -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \ + -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ + -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/strings.in.h; \ + } > $@-t && \ + mv $@-t $@ + +# We need the following in order to create <sys/stat.h> 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_at)$(MKDIR_P) sys + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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/@''GNULIB_FCHMODAT''@/$(GNULIB_FCHMODAT)/g' \ + -e 's/@''GNULIB_FSTAT''@/$(GNULIB_FSTAT)/g' \ + -e 's/@''GNULIB_FSTATAT''@/$(GNULIB_FSTATAT)/g' \ + -e 's/@''GNULIB_FUTIMENS''@/$(GNULIB_FUTIMENS)/g' \ + -e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \ + -e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \ + -e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \ + -e 's/@''GNULIB_MKFIFO''@/$(GNULIB_MKFIFO)/g' \ + -e 's/@''GNULIB_MKFIFOAT''@/$(GNULIB_MKFIFOAT)/g' \ + -e 's/@''GNULIB_MKNOD''@/$(GNULIB_MKNOD)/g' \ + -e 's/@''GNULIB_MKNODAT''@/$(GNULIB_MKNODAT)/g' \ + -e 's/@''GNULIB_STAT''@/$(GNULIB_STAT)/g' \ + -e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/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_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_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_MKNOD''@|$(REPLACE_MKNOD)|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 && \ + mv $@-t $@ + +# We need the following in order to create <sys/time.h> 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_at)$(MKDIR_P) sys + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -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''@/$(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 '/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 && \ + mv $@-t $@ + +# We need the following in order to create <sys/types.h> when the system +# doesn't have one that works with the given compiler. +sys/types.h: sys_types.in.h $(top_builddir)/config.status + $(AM_V_at)$(MKDIR_P) sys + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -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' \ + < $(srcdir)/sys_types.in.h; \ + } > $@-t && \ + mv $@-t $@ + +# We need the following in order to create <sysexits.h> when the system +# doesn't have one that works with the given compiler. +@GL_GENERATE_SYSEXITS_H_TRUE@sysexits.h: sysexits.in.h $(top_builddir)/config.status +@GL_GENERATE_SYSEXITS_H_TRUE@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_SYSEXITS_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +@GL_GENERATE_SYSEXITS_H_TRUE@ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_SYSEXITS_H_TRUE@ -e 's|@''HAVE_SYSEXITS_H''@|$(HAVE_SYSEXITS_H)|g' \ +@GL_GENERATE_SYSEXITS_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_SYSEXITS_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_SYSEXITS_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_SYSEXITS_H_TRUE@ -e 's|@''NEXT_SYSEXITS_H''@|$(NEXT_SYSEXITS_H)|g' \ +@GL_GENERATE_SYSEXITS_H_TRUE@ < $(srcdir)/sysexits.in.h; \ +@GL_GENERATE_SYSEXITS_H_TRUE@ } > $@-t && \ +@GL_GENERATE_SYSEXITS_H_TRUE@ mv -f $@-t $@ +@GL_GENERATE_SYSEXITS_H_FALSE@sysexits.h: $(top_builddir)/config.status +@GL_GENERATE_SYSEXITS_H_FALSE@ rm -f $@ + +# We need the following in order to create <time.h> when the system +# doesn't have one that works with the given compiler. +time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \ + -e 's/@''GNULIB_MKTIME''@/$(GNULIB_MKTIME)/g' \ + -e 's/@''GNULIB_NANOSLEEP''@/$(GNULIB_NANOSLEEP)/g' \ + -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \ + -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \ + -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \ + -e 's|@''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|@''REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \ + -e 's|@''REPLACE_MKTIME''@|$(REPLACE_MKTIME)|g' \ + -e 's|@''REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \ + -e 's|@''REPLACE_TIMEGM''@|$(REPLACE_TIMEGM)|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 '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/time.in.h; \ + } > $@-t && \ + mv $@-t $@ + +# We need the following in order to create an empty placeholder for +# <unistd.h> when the system doesn't have one. +unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -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/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \ + -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \ + -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \ + -e 's/@''GNULIB_DUP''@/$(GNULIB_DUP)/g' \ + -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \ + -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \ + -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \ + -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \ + -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \ + -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \ + -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \ + -e 's/@''GNULIB_FDATASYNC''@/$(GNULIB_FDATASYNC)/g' \ + -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \ + -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \ + -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \ + -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \ + -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \ + -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \ + -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \ + -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \ + -e 's/@''GNULIB_GETLOGIN_R''@/$(GNULIB_GETLOGIN_R)/g' \ + -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \ + -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \ + -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \ + -e 's/@''GNULIB_ISATTY''@/$(GNULIB_ISATTY)/g' \ + -e 's/@''GNULIB_LCHOWN''@/$(GNULIB_LCHOWN)/g' \ + -e 's/@''GNULIB_LINK''@/$(GNULIB_LINK)/g' \ + -e 's/@''GNULIB_LINKAT''@/$(GNULIB_LINKAT)/g' \ + -e 's/@''GNULIB_LSEEK''@/$(GNULIB_LSEEK)/g' \ + -e 's/@''GNULIB_PIPE''@/$(GNULIB_PIPE)/g' \ + -e 's/@''GNULIB_PIPE2''@/$(GNULIB_PIPE2)/g' \ + -e 's/@''GNULIB_PREAD''@/$(GNULIB_PREAD)/g' \ + -e 's/@''GNULIB_PWRITE''@/$(GNULIB_PWRITE)/g' \ + -e 's/@''GNULIB_READ''@/$(GNULIB_READ)/g' \ + -e 's/@''GNULIB_READLINK''@/$(GNULIB_READLINK)/g' \ + -e 's/@''GNULIB_READLINKAT''@/$(GNULIB_READLINKAT)/g' \ + -e 's/@''GNULIB_RMDIR''@/$(GNULIB_RMDIR)/g' \ + -e 's/@''GNULIB_SETHOSTNAME''@/$(GNULIB_SETHOSTNAME)/g' \ + -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \ + -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \ + -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \ + -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \ + -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GNULIB_GL_UNISTD_H_GETOPT)/g' \ + -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \ + -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GNULIB_UNISTD_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_UNLINK''@/$(GNULIB_UNLINK)/g' \ + -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \ + -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \ + -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \ + < $(srcdir)/unistd.in.h | \ + sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ + -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ + -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \ + -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|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_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \ + -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ + -e 's|@''HAVE_GETLOGIN''@|$(HAVE_GETLOGIN)|g' \ + -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ + -e 's|@''HAVE_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_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_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_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \ + -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \ + -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \ + | \ + sed -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ + -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \ + -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \ + -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ + -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ + -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ + -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|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_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_RMDIR''@|$(REPLACE_RMDIR)|g' \ + -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \ + -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|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_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \ + -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ + +unitypes.h: unitypes.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/unitypes.in.h; \ + } > $@-t && \ + mv -f $@-t $@ + +uniwidth.h: uniwidth.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/uniwidth.in.h; \ + } > $@-t && \ + mv -f $@-t $@ + +# We need the following in order to create <wchar.h> when the system +# version does not work standalone. +wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \ + -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ + -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \ + -e 's/@''GNULIB_BTOWC''@/$(GNULIB_BTOWC)/g' \ + -e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \ + -e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \ + -e 's/@''GNULIB_MBRTOWC''@/$(GNULIB_MBRTOWC)/g' \ + -e 's/@''GNULIB_MBRLEN''@/$(GNULIB_MBRLEN)/g' \ + -e 's/@''GNULIB_MBSRTOWCS''@/$(GNULIB_MBSRTOWCS)/g' \ + -e 's/@''GNULIB_MBSNRTOWCS''@/$(GNULIB_MBSNRTOWCS)/g' \ + -e 's/@''GNULIB_WCRTOMB''@/$(GNULIB_WCRTOMB)/g' \ + -e 's/@''GNULIB_WCSRTOMBS''@/$(GNULIB_WCSRTOMBS)/g' \ + -e 's/@''GNULIB_WCSNRTOMBS''@/$(GNULIB_WCSNRTOMBS)/g' \ + -e 's/@''GNULIB_WCWIDTH''@/$(GNULIB_WCWIDTH)/g' \ + -e 's/@''GNULIB_WMEMCHR''@/$(GNULIB_WMEMCHR)/g' \ + -e 's/@''GNULIB_WMEMCMP''@/$(GNULIB_WMEMCMP)/g' \ + -e 's/@''GNULIB_WMEMCPY''@/$(GNULIB_WMEMCPY)/g' \ + -e 's/@''GNULIB_WMEMMOVE''@/$(GNULIB_WMEMMOVE)/g' \ + -e 's/@''GNULIB_WMEMSET''@/$(GNULIB_WMEMSET)/g' \ + -e 's/@''GNULIB_WCSLEN''@/$(GNULIB_WCSLEN)/g' \ + -e 's/@''GNULIB_WCSNLEN''@/$(GNULIB_WCSNLEN)/g' \ + -e 's/@''GNULIB_WCSCPY''@/$(GNULIB_WCSCPY)/g' \ + -e 's/@''GNULIB_WCPCPY''@/$(GNULIB_WCPCPY)/g' \ + -e 's/@''GNULIB_WCSNCPY''@/$(GNULIB_WCSNCPY)/g' \ + -e 's/@''GNULIB_WCPNCPY''@/$(GNULIB_WCPNCPY)/g' \ + -e 's/@''GNULIB_WCSCAT''@/$(GNULIB_WCSCAT)/g' \ + -e 's/@''GNULIB_WCSNCAT''@/$(GNULIB_WCSNCAT)/g' \ + -e 's/@''GNULIB_WCSCMP''@/$(GNULIB_WCSCMP)/g' \ + -e 's/@''GNULIB_WCSNCMP''@/$(GNULIB_WCSNCMP)/g' \ + -e 's/@''GNULIB_WCSCASECMP''@/$(GNULIB_WCSCASECMP)/g' \ + -e 's/@''GNULIB_WCSNCASECMP''@/$(GNULIB_WCSNCASECMP)/g' \ + -e 's/@''GNULIB_WCSCOLL''@/$(GNULIB_WCSCOLL)/g' \ + -e 's/@''GNULIB_WCSXFRM''@/$(GNULIB_WCSXFRM)/g' \ + -e 's/@''GNULIB_WCSDUP''@/$(GNULIB_WCSDUP)/g' \ + -e 's/@''GNULIB_WCSCHR''@/$(GNULIB_WCSCHR)/g' \ + -e 's/@''GNULIB_WCSRCHR''@/$(GNULIB_WCSRCHR)/g' \ + -e 's/@''GNULIB_WCSCSPN''@/$(GNULIB_WCSCSPN)/g' \ + -e 's/@''GNULIB_WCSSPN''@/$(GNULIB_WCSSPN)/g' \ + -e 's/@''GNULIB_WCSPBRK''@/$(GNULIB_WCSPBRK)/g' \ + -e 's/@''GNULIB_WCSSTR''@/$(GNULIB_WCSSTR)/g' \ + -e 's/@''GNULIB_WCSTOK''@/$(GNULIB_WCSTOK)/g' \ + -e 's/@''GNULIB_WCSWIDTH''@/$(GNULIB_WCSWIDTH)/g' \ + < $(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_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_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|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_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 '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ + +# We need the following in order to create <wctype.h> when the system +# doesn't have one that works with the given compiler. +wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ + -e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \ + -e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \ + -e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \ + -e 's/@''GNULIB_WCTRANS''@/$(GNULIB_WCTRANS)/g' \ + -e 's/@''GNULIB_TOWCTRANS''@/$(GNULIB_TOWCTRANS)/g' \ + -e 's/@''HAVE_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_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \ + -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/wctype.in.h; \ + } > $@-t && \ + mv $@-t $@ + +mostlyclean-local: mostlyclean-generic + @for dir in '' $(MOSTLYCLEANDIRS); do \ + if test -n "$$dir" && test -d $$dir; then \ + echo "rmdir $$dir"; rmdir $$dir; \ + fi; \ + done; \ + : + +# 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/gnu/alloca.c b/gnu/alloca.c new file mode 100644 index 00000000..b14bba75 --- /dev/null +++ b/gnu/alloca.c @@ -0,0 +1,480 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* alloca.c -- allocate automatically reclaimed memory + (Mostly) portable public-domain 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 <jot@cray.com> 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 <config.h> + +#include <alloca.h> + +#include <string.h> +#include <stdlib.h> + +#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 2, this file's not needed. */ +#if !defined (__GNUC__) || __GNUC__ < 2 + +/* 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 */ + +/* If your stack is a linked list of frames, you have to + provide an "address metric" ADDRESS_FUNCTION macro. */ + +# if defined (CRAY) && defined (CRAY_STACKSEG_END) +long i00afunc (); +# define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) +# else +# define ADDRESS_FUNCTION(arg) &(arg) +# endif + +/* 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 = ADDRESS_FUNCTION (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); + } +} + +# if defined (CRAY) && defined (CRAY_STACKSEG_END) + +# ifdef DEBUG_I00AFUNC +# include <stdio.h> +# endif + +# ifndef CRAY_STACK +# define CRAY_STACK +# ifndef CRAY2 +/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ +struct stack_control_header + { + long shgrow:32; /* Number of times stack has grown. */ + long shaseg:32; /* Size of increments to stack. */ + long shhwm:32; /* High water mark of stack. */ + long shsize:32; /* Current size of stack (all segments). */ + }; + +/* The stack segment linkage control information occurs at + the high-address end of a stack segment. (The stack + grows from low addresses to high addresses.) The initial + part of the stack segment linkage control information is + 0200 (octal) words. This provides for register storage + for the routine which overflows the stack. */ + +struct stack_segment_linkage + { + long ss[0200]; /* 0200 overflow words. */ + long sssize:32; /* Number of words in this segment. */ + long ssbase:32; /* Offset to stack base. */ + long:32; + long sspseg:32; /* Offset to linkage control of previous + segment of stack. */ + long:32; + long sstcpt:32; /* Pointer to task common address block. */ + long sscsnm; /* Private control structure number for + microtasking. */ + long ssusr1; /* Reserved for user. */ + long ssusr2; /* Reserved for user. */ + long sstpid; /* Process ID for pid based multi-tasking. */ + long ssgvup; /* Pointer to multitasking thread giveup. */ + long sscray[7]; /* Reserved for Cray Research. */ + long ssa0; + long ssa1; + long ssa2; + long ssa3; + long ssa4; + long ssa5; + long ssa6; + long ssa7; + long sss0; + long sss1; + long sss2; + long sss3; + long sss4; + long sss5; + long sss6; + long sss7; + }; + +# else /* CRAY2 */ +/* The following structure defines the vector of words + returned by the STKSTAT library routine. */ +struct stk_stat + { + long now; /* Current total stack size. */ + long maxc; /* Amount of contiguous space which would + be required to satisfy the maximum + stack demand to date. */ + long high_water; /* Stack high-water mark. */ + long overflows; /* Number of stack overflow ($STKOFEN) calls. */ + long hits; /* Number of internal buffer hits. */ + long extends; /* Number of block extensions. */ + long stko_mallocs; /* Block allocations by $STKOFEN. */ + long underflows; /* Number of stack underflow calls ($STKRETN). */ + long stko_free; /* Number of deallocations by $STKRETN. */ + long stkm_free; /* Number of deallocations by $STKMRET. */ + long segments; /* Current number of stack segments. */ + long maxs; /* Maximum number of stack segments so far. */ + long pad_size; /* Stack pad size. */ + long current_address; /* Current stack segment address. */ + long current_size; /* Current stack segment size. This + number is actually corrupted by STKSTAT to + include the fifteen word trailer area. */ + long initial_address; /* Address of initial segment. */ + long initial_size; /* Size of initial segment. */ + }; + +/* The following structure describes the data structure which trails + any stack segment. I think that the description in 'asdef' is + out of date. I only describe the parts that I am sure about. */ + +struct stk_trailer + { + long this_address; /* Address of this block. */ + long this_size; /* Size of this block (does not include + this trailer). */ + long unknown2; + long unknown3; + long link; /* Address of trailer block of previous + segment. */ + long unknown5; + long unknown6; + long unknown7; + long unknown8; + long unknown9; + long unknown10; + long unknown11; + long unknown12; + long unknown13; + long unknown14; + }; + +# endif /* CRAY2 */ +# endif /* not CRAY_STACK */ + +# ifdef CRAY2 +/* Determine a "stack measure" for an arbitrary ADDRESS. + I doubt that "lint" will like this much. */ + +static long +i00afunc (long *address) +{ + struct stk_stat status; + struct stk_trailer *trailer; + long *block, size; + long result = 0; + + /* We want to iterate through all of the segments. The first + step is to get the stack status structure. We could do this + more quickly and more directly, perhaps, by referencing the + $LM00 common block, but I know that this works. */ + + STKSTAT (&status); + + /* Set up the iteration. */ + + trailer = (struct stk_trailer *) (status.current_address + + status.current_size + - 15); + + /* There must be at least one stack segment. Therefore it is + a fatal error if "trailer" is null. */ + + if (trailer == 0) + abort (); + + /* Discard segments that do not contain our argument address. */ + + while (trailer != 0) + { + block = (long *) trailer->this_address; + size = trailer->this_size; + if (block == 0 || size == 0) + abort (); + trailer = (struct stk_trailer *) trailer->link; + if ((block <= address) && (address < (block + size))) + break; + } + + /* Set the result to the offset in this segment and add the sizes + of all predecessor segments. */ + + result = address - block; + + if (trailer == 0) + { + return result; + } + + do + { + if (trailer->this_size <= 0) + abort (); + result += trailer->this_size; + trailer = (struct stk_trailer *) trailer->link; + } + while (trailer != 0); + + /* We are done. Note that if you present a bogus address (one + not in any segment), you will get a different number back, formed + from subtracting the address of the first block. This is probably + not what you want. */ + + return (result); +} + +# else /* not CRAY2 */ +/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. + Determine the number of the cell within the stack, + given the address of the cell. The purpose of this + routine is to linearize, in some sense, stack addresses + for alloca. */ + +static long +i00afunc (long address) +{ + long stkl = 0; + + long size, pseg, this_segment, stack; + long result = 0; + + struct stack_segment_linkage *ssptr; + + /* Register B67 contains the address of the end of the + current stack segment. If you (as a subprogram) store + your registers on the stack and find that you are past + the contents of B67, you have overflowed the segment. + + B67 also points to the stack segment linkage control + area, which is what we are really interested in. */ + + stkl = CRAY_STACKSEG_END (); + ssptr = (struct stack_segment_linkage *) stkl; + + /* If one subtracts 'size' from the end of the segment, + one has the address of the first word of the segment. + + If this is not the first segment, 'pseg' will be + nonzero. */ + + pseg = ssptr->sspseg; + size = ssptr->sssize; + + this_segment = stkl - size; + + /* It is possible that calling this routine itself caused + a stack overflow. Discard stack segments which do not + contain the target address. */ + + while (!(this_segment <= address && address <= stkl)) + { +# ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); +# endif + if (pseg == 0) + break; + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + this_segment = stkl - size; + } + + result = address - this_segment; + + /* If you subtract pseg from the current end of the stack, + you get the address of the previous stack segment's end. + This seems a little convoluted to me, but I'll bet you save + a cycle somewhere. */ + + while (pseg != 0) + { +# ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o\n", pseg, size); +# endif + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + result += size; + } + return (result); +} + +# endif /* not CRAY2 */ +# endif /* CRAY */ + +# endif /* no alloca */ +#endif /* not GCC 2 */ diff --git a/gnu/alloca.in.h b/gnu/alloca.in.h new file mode 100644 index 00000000..9967338b --- /dev/null +++ b/gnu/alloca.in.h @@ -0,0 +1,58 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Memory allocation on the stack. + + Copyright (C) 1995, 1999, 2001-2004, 2006-2012 Free Software Foundation, + Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +/* 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 +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include <malloc.h> +# define alloca _alloca +# elif defined __DECC && defined __VMS +# define alloca __ALLOCA +# else +# include <stddef.h> +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#endif /* _GL_ALLOCA_H */ diff --git a/gnu/allocator.c b/gnu/allocator.c new file mode 100644 index 00000000..c512d4bb --- /dev/null +++ b/gnu/allocator.c @@ -0,0 +1,7 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define _GL_USE_STDLIB_ALLOC 1 +#include <config.h> +#include "allocator.h" +#include <stdlib.h> +struct allocator const stdlib_allocator = { malloc, realloc, free, NULL }; diff --git a/gnu/allocator.h b/gnu/allocator.h new file mode 100644 index 00000000..7e176637 --- /dev/null +++ b/gnu/allocator.h @@ -0,0 +1,60 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Memory allocators such as malloc+free. + + Copyright (C) 2011-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#ifndef _GL_ALLOCATOR_H +#define _GL_ALLOCATOR_H + +#include <stddef.h> + +/* An object describing a memory allocator family. */ + +struct allocator +{ + /* Do not use GCC attributes such as __attribute__ ((malloc)) with + the function types pointed at by these members, because these + attributes do not work with pointers to functions. See + <http://lists.gnu.org/archive/html/bug-gnulib/2011-04/msg00007.html>. */ + + /* Call ALLOCATE to allocate memory, like 'malloc'. On failure ALLOCATE + should return NULL, though not necessarily set errno. When given + a zero size it may return NULL even if successful. */ + void *(*allocate) (size_t); + + /* If nonnull, call REALLOCATE to reallocate memory, like 'realloc'. + On failure REALLOCATE should return NULL, though not necessarily set + errno. When given a zero size it may return NULL even if + successful. */ + void *(*reallocate) (void *, size_t); + + /* Call FREE to free memory, like 'free'. */ + void (*free) (void *); + + /* If nonnull, call DIE (SIZE) if MALLOC (SIZE) or REALLOC (..., + SIZE) fails. DIE should not return. SIZE should equal SIZE_MAX + if size_t overflow was detected while calculating sizes to be + passed to MALLOC or REALLOC. */ + void (*die) (size_t); +}; + +/* An allocator using the stdlib functions and a null DIE function. */ +extern struct allocator const stdlib_allocator; + +#endif /* _GL_ALLOCATOR_H */ diff --git a/gnu/anytostr.c b/gnu/anytostr.c new file mode 100644 index 00000000..ef6b9f19 --- /dev/null +++ b/gnu/anytostr.c @@ -0,0 +1,57 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* anytostr.c -- convert integers to printable strings + + Copyright (C) 2001, 2006, 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert */ + +/* Tell gcc not to warn about the (i < 0) test, below. */ +#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__ +# pragma GCC diagnostic ignored "-Wtype-limits" +#endif + +#include <config.h> + +#include "inttostr.h" + +/* Convert I to a printable string in BUF, which must be at least + INT_BUFSIZE_BOUND (INTTYPE) bytes long. Return the address of the + printable string, which need not start at BUF. */ + +char * __attribute_warn_unused_result__ +anytostr (inttype i, char *buf) +{ + char *p = buf + INT_STRLEN_BOUND (inttype); + *p = 0; + + if (i < 0) + { + do + *--p = '0' - i % 10; + while ((i /= 10) != 0); + + *--p = '-'; + } + else + { + do + *--p = '0' + i % 10; + while ((i /= 10) != 0); + } + + return p; +} diff --git a/gnu/areadlink.c b/gnu/areadlink.c new file mode 100644 index 00000000..233611e2 --- /dev/null +++ b/gnu/areadlink.c @@ -0,0 +1,41 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* areadlink.c -- readlink wrapper to return the link name in malloc'd storage + Unlike xreadlink and xreadlink_with_size, don't ever call exit. + + Copyright (C) 2001, 2003-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering <jim@meyering.net> + and Bruno Haible <bruno@clisp.org>. */ + +#include <config.h> + +/* Specification. */ +#include "areadlink.h" + +#include "careadlinkat.h" + +/* Call readlink to get the symbolic link value of FILENAME. + Return a pointer to that NUL-terminated string in malloc'd storage. + If readlink fails, return NULL and set errno. + If allocation fails, or if the link value is longer than SIZE_MAX :-), + return NULL and set errno to ENOMEM. */ + +char * +areadlink (char const *filename) +{ + return careadlinkat (AT_FDCWD, filename, NULL, 0, NULL, careadlinkatcwd); +} diff --git a/gnu/areadlink.h b/gnu/areadlink.h new file mode 100644 index 00000000..000ace87 --- /dev/null +++ b/gnu/areadlink.h @@ -0,0 +1,35 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Read symbolic links without size limitation. + + Copyright (C) 2001, 2003-2004, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering <jim@meyering.net> */ + +#include <stddef.h> + +extern char *areadlink (char const *filename); +extern char *areadlink_with_size (char const *filename, size_t size_hint); + +#if GNULIB_AREADLINKAT +extern char *areadlinkat (int fd, char const *filename); +#endif + +#if GNULIB_AREADLINKAT_WITH_SIZE +extern char *areadlinkat_with_size (int fd, char const *filename, + size_t size_hint); +#endif diff --git a/gnu/areadlinkat.c b/gnu/areadlinkat.c new file mode 100644 index 00000000..de311080 --- /dev/null +++ b/gnu/areadlinkat.c @@ -0,0 +1,67 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* areadlinkat.c -- readlinkat wrapper to return malloc'd link name + Unlike xreadlinkat, only call exit on failure to change directory. + + Copyright (C) 2001, 2003-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering <jim@meyering.net>, + and Bruno Haible <bruno@clisp.org>, + and Eric Blake <ebb9@byu.net>. */ + +#include <config.h> + +/* Specification. */ +#include "areadlink.h" + +#include "careadlinkat.h" + +#if HAVE_READLINKAT + +/* Call readlinkat to get the symbolic link value of FILENAME relative to FD. + Return a pointer to that NUL-terminated string in malloc'd storage. + If readlinkat fails, return NULL and set errno (although failure to + change directory will issue a diagnostic and exit). + If allocation fails, or if the link value is longer than SIZE_MAX :-), + return NULL and set errno to ENOMEM. */ + +char * +areadlinkat (int fd, char const *filename) +{ + return careadlinkat (fd, filename, NULL, 0, NULL, readlinkat); +} + +#else /* !HAVE_READLINKAT */ + +/* It is more efficient to change directories only once and call + areadlink, rather than repeatedly call the replacement + readlinkat. */ + +# define AT_FUNC_NAME areadlinkat +# define AT_FUNC_F1 areadlink +# define AT_FUNC_POST_FILE_PARAM_DECLS /* empty */ +# define AT_FUNC_POST_FILE_ARGS /* empty */ +# define AT_FUNC_RESULT char * +# define AT_FUNC_FAIL NULL +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS +# undef AT_FUNC_RESULT +# undef AT_FUNC_FAIL + +#endif /* !HAVE_READLINKAT */ diff --git a/gnu/argmatch.c b/gnu/argmatch.c new file mode 100644 index 00000000..306348b4 --- /dev/null +++ b/gnu/argmatch.c @@ -0,0 +1,279 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* argmatch.c -- find a match for a string in an array + + Copyright (C) 1990, 1998-1999, 2001-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by David MacKenzie <djm@ai.mit.edu> + Modified by Akim Demaille <demaille@inf.enst.fr> */ + +#include <config.h> + +/* Specification. */ +#include "argmatch.h" + +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "gettext.h" +#define _(msgid) gettext (msgid) + +#include "error.h" +#include "quotearg.h" +#include "quote.h" + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +/* When reporting an invalid argument, show nonprinting characters + by using the quoting style ARGMATCH_QUOTING_STYLE. Do not use + literal_quoting_style. */ +#ifndef ARGMATCH_QUOTING_STYLE +# define ARGMATCH_QUOTING_STYLE locale_quoting_style +#endif + +/* Non failing version of argmatch call this function after failing. */ +#ifndef ARGMATCH_DIE +# include "exitfail.h" +# define ARGMATCH_DIE exit (exit_failure) +#endif + +#ifdef ARGMATCH_DIE_DECL +ARGMATCH_DIE_DECL; +#endif + +static void +__argmatch_die (void) +{ + ARGMATCH_DIE; +} + +/* Used by XARGMATCH and XARGCASEMATCH. See description in argmatch.h. + Default to __argmatch_die, but allow caller to change this at run-time. */ +argmatch_exit_fn argmatch_die = __argmatch_die; + + +/* If ARG is an unambiguous match for an element of the + NULL-terminated array ARGLIST, return the index in ARGLIST + of the matched element, else -1 if it does not match any element + or -2 if it is ambiguous (is a prefix of more than one element). + + If VALLIST is none null, use it to resolve ambiguities limited to + synonyms, i.e., for + "yes", "yop" -> 0 + "no", "nope" -> 1 + "y" is a valid argument, for 0, and "n" for 1. */ + +ptrdiff_t +argmatch (const char *arg, const char *const *arglist, + const char *vallist, size_t valsize) +{ + size_t i; /* Temporary index in ARGLIST. */ + size_t arglen; /* Length of ARG. */ + ptrdiff_t matchind = -1; /* Index of first nonexact match. */ + bool ambiguous = false; /* If true, multiple nonexact match(es). */ + + arglen = strlen (arg); + + /* Test all elements for either exact match or abbreviated matches. */ + for (i = 0; arglist[i]; i++) + { + if (!strncmp (arglist[i], arg, arglen)) + { + if (strlen (arglist[i]) == arglen) + /* Exact match found. */ + return i; + else if (matchind == -1) + /* First nonexact match found. */ + matchind = i; + else + { + /* Second nonexact match found. */ + if (vallist == NULL + || memcmp (vallist + valsize * matchind, + vallist + valsize * i, valsize)) + { + /* There is a real ambiguity, or we could not + disambiguate. */ + ambiguous = true; + } + } + } + } + if (ambiguous) + return -2; + else + return matchind; +} + +/* Error reporting for argmatch. + CONTEXT is a description of the type of entity that was being matched. + VALUE is the invalid value that was given. + PROBLEM is the return value from argmatch. */ + +void +argmatch_invalid (const char *context, const char *value, ptrdiff_t problem) +{ + char const *format = (problem == -1 + ? _("invalid argument %s for %s") + : _("ambiguous argument %s for %s")); + + error (0, 0, format, quotearg_n_style (0, ARGMATCH_QUOTING_STYLE, value), + quote_n (1, context)); +} + +/* List the valid arguments for argmatch. + ARGLIST is the same as in argmatch. + VALLIST is a pointer to an array of values. + VALSIZE is the size of the elements of VALLIST */ +void +argmatch_valid (const char *const *arglist, + const char *vallist, size_t valsize) +{ + size_t i; + const char *last_val = NULL; + + /* We try to put synonyms on the same line. The assumption is that + synonyms follow each other */ + fputs (_("Valid arguments are:"), stderr); + for (i = 0; arglist[i]; i++) + if ((i == 0) + || memcmp (last_val, vallist + valsize * i, valsize)) + { + fprintf (stderr, "\n - %s", quote (arglist[i])); + last_val = vallist + valsize * i; + } + else + { + fprintf (stderr, ", %s", quote (arglist[i])); + } + putc ('\n', stderr); +} + +/* Never failing versions of the previous functions. + + CONTEXT is the context for which argmatch is called (e.g., + "--version-control", or "$VERSION_CONTROL" etc.). Upon failure, + calls the (supposed never to return) function EXIT_FN. */ + +ptrdiff_t +__xargmatch_internal (const char *context, + const char *arg, const char *const *arglist, + const char *vallist, size_t valsize, + argmatch_exit_fn exit_fn) +{ + ptrdiff_t res = argmatch (arg, arglist, vallist, valsize); + if (res >= 0) + /* Success. */ + return res; + + /* We failed. Explain why. */ + argmatch_invalid (context, arg, res); + argmatch_valid (arglist, vallist, valsize); + (*exit_fn) (); + + return -1; /* To please the compilers. */ +} + +/* Look for VALUE in VALLIST, an array of objects of size VALSIZE and + return the first corresponding argument in ARGLIST */ +const char * +argmatch_to_argument (const char *value, + const char *const *arglist, + const char *vallist, size_t valsize) +{ + size_t i; + + for (i = 0; arglist[i]; i++) + if (!memcmp (value, vallist + valsize * i, valsize)) + return arglist[i]; + return NULL; +} + +#ifdef TEST +/* + * Based on "getversion.c" by David MacKenzie <djm@gnu.ai.mit.edu> + */ +char *program_name; + +/* When to make backup files. */ +enum backup_type +{ + /* Never make backups. */ + no_backups, + + /* Make simple backups of every file. */ + simple_backups, + + /* Make numbered backups of files that already have numbered backups, + and simple backups of the others. */ + numbered_existing_backups, + + /* Make numbered backups of every file. */ + numbered_backups +}; + +/* Two tables describing arguments (keys) and their corresponding + values */ +static const char *const backup_args[] = +{ + "no", "none", "off", + "simple", "never", + "existing", "nil", + "numbered", "t", + 0 +}; + +static const enum backup_type backup_vals[] = +{ + no_backups, no_backups, no_backups, + simple_backups, simple_backups, + numbered_existing_backups, numbered_existing_backups, + numbered_backups, numbered_backups +}; + +int +main (int argc, const char *const *argv) +{ + const char *cp; + enum backup_type backup_type = no_backups; + + program_name = (char *) argv[0]; + + if (argc > 2) + { + fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", program_name); + exit (1); + } + + if ((cp = getenv ("VERSION_CONTROL"))) + backup_type = XARGMATCH ("$VERSION_CONTROL", cp, + backup_args, backup_vals); + + if (argc == 2) + backup_type = XARGMATCH (program_name, argv[1], + backup_args, backup_vals); + + printf ("The version control is '%s'\n", + ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals)); + + return 0; +} +#endif diff --git a/gnu/argmatch.h b/gnu/argmatch.h new file mode 100644 index 00000000..61020127 --- /dev/null +++ b/gnu/argmatch.h @@ -0,0 +1,105 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* argmatch.h -- definitions and prototypes for argmatch.c + + Copyright (C) 1990, 1998-1999, 2001-2002, 2004-2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by David MacKenzie <djm@ai.mit.edu> + Modified by Akim Demaille <demaille@inf.enst.fr> */ + +#ifndef ARGMATCH_H_ +# define ARGMATCH_H_ 1 + +# include <stddef.h> + +# include "verify.h" + +# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array)) + +/* Assert there are as many real arguments as there are values + (argument list ends with a NULL guard). */ + +# define ARGMATCH_VERIFY(Arglist, Vallist) \ + verify (ARRAY_CARDINALITY (Arglist) == ARRAY_CARDINALITY (Vallist) + 1) + +/* Return the index of the element of ARGLIST (NULL terminated) that + matches with ARG. If VALLIST is not NULL, then use it to resolve + false ambiguities (i.e., different matches of ARG but corresponding + to the same values in VALLIST). */ + +ptrdiff_t argmatch (char const *arg, char const *const *arglist, + char const *vallist, size_t valsize) _GL_ATTRIBUTE_PURE; + +# define ARGMATCH(Arg, Arglist, Vallist) \ + argmatch (Arg, Arglist, (char const *) (Vallist), sizeof *(Vallist)) + +/* xargmatch calls this function when it fails. This function should not + return. By default, this is a function that calls ARGMATCH_DIE which + in turn defaults to 'exit (exit_failure)'. */ +typedef void (*argmatch_exit_fn) (void); +extern argmatch_exit_fn argmatch_die; + +/* Report on stderr why argmatch failed. Report correct values. */ + +void argmatch_invalid (char const *context, char const *value, + ptrdiff_t problem); + +/* Left for compatibility with the old name invalid_arg */ + +# define invalid_arg(Context, Value, Problem) \ + argmatch_invalid (Context, Value, Problem) + + + +/* Report on stderr the list of possible arguments. */ + +void argmatch_valid (char const *const *arglist, + char const *vallist, size_t valsize); + +# define ARGMATCH_VALID(Arglist, Vallist) \ + argmatch_valid (Arglist, (char const *) (Vallist), sizeof *(Vallist)) + + + +/* Same as argmatch, but upon failure, report an explanation of the + failure, and exit using the function EXIT_FN. */ + +ptrdiff_t __xargmatch_internal (char const *context, + char const *arg, char const *const *arglist, + char const *vallist, size_t valsize, + argmatch_exit_fn exit_fn); + +/* Programmer friendly interface to __xargmatch_internal. */ + +# define XARGMATCH(Context, Arg, Arglist, Vallist) \ + ((Vallist) [__xargmatch_internal (Context, Arg, Arglist, \ + (char const *) (Vallist), \ + sizeof *(Vallist), \ + argmatch_die)]) + +/* Convert a value into a corresponding argument. */ + +char const *argmatch_to_argument (char const *value, + char const *const *arglist, + char const *vallist, size_t valsize) + _GL_ATTRIBUTE_PURE; + +# define ARGMATCH_TO_ARGUMENT(Value, Arglist, Vallist) \ + argmatch_to_argument (Value, Arglist, \ + (char const *) (Vallist), sizeof *(Vallist)) + +#endif /* ARGMATCH_H_ */ diff --git a/gnu/argp-ba.c b/gnu/argp-ba.c new file mode 100644 index 00000000..5767cf1e --- /dev/null +++ b/gnu/argp-ba.c @@ -0,0 +1,36 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Default definition for ARGP_PROGRAM_BUG_ADDRESS. + Copyright (C) 1996-1997, 1999, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +/* If set by the user program, it should point to string that is the + bug-reporting address for the program. It will be printed by argp_help if + the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help + messages), embedded in a sentence that says something like "Report bugs to + ADDR." */ +const char *argp_program_bug_address +/* This variable should be zero-initialized. On most systems, putting it into + BSS is sufficient. Not so on MacOS X 10.3 and 10.4, see + <http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00329.html> + <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00096.html>. */ +#if defined __ELF__ + /* On ELF systems, variables in BSS behave well. */ +#else + = (const char *) 0 +#endif + ; diff --git a/gnu/argp-eexst.c b/gnu/argp-eexst.c new file mode 100644 index 00000000..ef336093 --- /dev/null +++ b/gnu/argp-eexst.c @@ -0,0 +1,32 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Default definition for ARGP_ERR_EXIT_STATUS + Copyright (C) 1997, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sysexits.h> + +#include "argp.h" + +/* The exit status that argp will use when exiting due to a parsing error. + If not defined or set by the user program, this defaults to EX_USAGE from + <sysexits.h>. */ +error_t argp_err_exit_status = EX_USAGE; diff --git a/gnu/argp-fmtstream.c b/gnu/argp-fmtstream.c new file mode 100644 index 00000000..524ff32f --- /dev/null +++ b/gnu/argp-fmtstream.c @@ -0,0 +1,437 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Word-wrapping and line-truncating streams + Copyright (C) 1997-1999, 2001-2003, 2005, 2009-2012 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +/* This package emulates glibc 'line_wrap_stream' semantics for systems that + don't have that. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <stdarg.h> +#include <ctype.h> + +#include "argp-fmtstream.h" +#include "argp-namefrob.h" + +#ifndef ARGP_FMTSTREAM_USE_LINEWRAP + +#ifndef isblank +#define isblank(ch) ((ch)==' ' || (ch)=='\t') +#endif + +#if defined _LIBC && defined USE_IN_LIBIO +# include <wchar.h> +# include <libio/libioP.h> +# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) +#endif + +#define INIT_BUF_SIZE 200 +#define PRINTF_SIZE_GUESS 150 + +/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines + written on it with LMARGIN spaces and limits them to RMARGIN columns + total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by + replacing the whitespace before them with a newline and WMARGIN spaces. + Otherwise, chars beyond RMARGIN are simply dropped until a newline. + Returns NULL if there was an error. */ +argp_fmtstream_t +__argp_make_fmtstream (FILE *stream, + size_t lmargin, size_t rmargin, ssize_t wmargin) +{ + argp_fmtstream_t fs; + + fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream)); + if (fs != NULL) + { + fs->stream = stream; + + fs->lmargin = lmargin; + fs->rmargin = rmargin; + fs->wmargin = wmargin; + fs->point_col = 0; + fs->point_offs = 0; + + fs->buf = (char *) malloc (INIT_BUF_SIZE); + if (! fs->buf) + { + free (fs); + fs = 0; + } + else + { + fs->p = fs->buf; + fs->end = fs->buf + INIT_BUF_SIZE; + } + } + + return fs; +} +#if 0 +/* Not exported. */ +#ifdef weak_alias +weak_alias (__argp_make_fmtstream, argp_make_fmtstream) +#endif +#endif + +/* Flush FS to its stream, and free it (but don't close the stream). */ +void +__argp_fmtstream_free (argp_fmtstream_t fs) +{ + __argp_fmtstream_update (fs); + if (fs->p > fs->buf) + { +#ifdef USE_IN_LIBIO + __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); +#else + fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); +#endif + } + free (fs->buf); + free (fs); +} +#if 0 +/* Not exported. */ +#ifdef weak_alias +weak_alias (__argp_fmtstream_free, argp_fmtstream_free) +#endif +#endif + +/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the + end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ +void +__argp_fmtstream_update (argp_fmtstream_t fs) +{ + char *buf, *nl; + size_t len; + + /* Scan the buffer for newlines. */ + buf = fs->buf + fs->point_offs; + while (buf < fs->p) + { + size_t r; + + if (fs->point_col == 0 && fs->lmargin != 0) + { + /* We are starting a new line. Print spaces to the left margin. */ + const size_t pad = fs->lmargin; + if (fs->p + pad < fs->end) + { + /* We can fit in them in the buffer by moving the + buffer text up and filling in the beginning. */ + memmove (buf + pad, buf, fs->p - buf); + fs->p += pad; /* Compensate for bigger buffer. */ + memset (buf, ' ', pad); /* Fill in the spaces. */ + buf += pad; /* Don't bother searching them. */ + } + else + { + /* No buffer space for spaces. Must flush. */ + size_t i; + for (i = 0; i < pad; i++) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (fs->stream, 0) > 0) + putwc_unlocked (L' ', fs->stream); + else +#endif + putc_unlocked (' ', fs->stream); + } + } + fs->point_col = pad; + } + + len = fs->p - buf; + nl = memchr (buf, '\n', len); + + if (fs->point_col < 0) + fs->point_col = 0; + + if (!nl) + { + /* The buffer ends in a partial line. */ + + if (fs->point_col + len < fs->rmargin) + { + /* The remaining buffer text is a partial line and fits + within the maximum line width. Advance point for the + characters to be written and stop scanning. */ + fs->point_col += len; + break; + } + else + /* Set the end-of-line pointer for the code below to + the end of the buffer. */ + nl = fs->p; + } + else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin) + { + /* The buffer contains a full line that fits within the maximum + line width. Reset point and scan the next line. */ + fs->point_col = 0; + buf = nl + 1; + continue; + } + + /* This line is too long. */ + r = fs->rmargin - 1; + + if (fs->wmargin < 0) + { + /* Truncate the line by overwriting the excess with the + newline and anything after it in the buffer. */ + if (nl < fs->p) + { + memmove (buf + (r - fs->point_col), nl, fs->p - nl); + fs->p -= buf + (r - fs->point_col) - nl; + /* Reset point for the next line and start scanning it. */ + fs->point_col = 0; + buf += r + 1; /* Skip full line plus \n. */ + } + else + { + /* The buffer ends with a partial line that is beyond the + maximum line width. Advance point for the characters + written, and discard those past the max from the buffer. */ + fs->point_col += len; + fs->p -= fs->point_col - r; + break; + } + } + else + { + /* Do word wrap. Go to the column just past the maximum line + width and scan back for the beginning of the word there. + Then insert a line break. */ + + char *p, *nextline; + int i; + + p = buf + (r + 1 - fs->point_col); + while (p >= buf && !isblank ((unsigned char) *p)) + --p; + nextline = p + 1; /* This will begin the next line. */ + + if (nextline > buf) + { + /* Swallow separating blanks. */ + if (p >= buf) + do + --p; + while (p >= buf && isblank ((unsigned char) *p)); + nl = p + 1; /* The newline will replace the first blank. */ + } + else + { + /* A single word that is greater than the maximum line width. + Oh well. Put it on an overlong line by itself. */ + p = buf + (r + 1 - fs->point_col); + /* Find the end of the long word. */ + if (p < nl) + do + ++p; + while (p < nl && !isblank ((unsigned char) *p)); + if (p == nl) + { + /* It already ends a line. No fussing required. */ + fs->point_col = 0; + buf = nl + 1; + continue; + } + /* We will move the newline to replace the first blank. */ + nl = p; + /* Swallow separating blanks. */ + do + ++p; + while (isblank ((unsigned char) *p)); + /* The next line will start here. */ + nextline = p; + } + + /* Note: There are a bunch of tests below for + NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall + at the end of the buffer, and NEXTLINE is in fact empty (and so + we need not be careful to maintain its contents). */ + + if ((nextline == buf + len + 1 + ? fs->end - nl < fs->wmargin + 1 + : nextline - (nl + 1) < fs->wmargin) + && fs->p > nextline) + { + /* The margin needs more blanks than we removed. */ + if (fs->end - fs->p > fs->wmargin + 1) + /* Make some space for them. */ + { + size_t mv = fs->p - nextline; + memmove (nl + 1 + fs->wmargin, nextline, mv); + nextline = nl + 1 + fs->wmargin; + len = nextline + mv - buf; + *nl++ = '\n'; + } + else + /* Output the first line so we can use the space. */ + { +#ifdef _LIBC + __fxprintf (fs->stream, "%.*s\n", + (int) (nl - fs->buf), fs->buf); +#else + if (nl > fs->buf) + fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream); + putc_unlocked ('\n', fs->stream); +#endif + + len += buf - fs->buf; + nl = buf = fs->buf; + } + } + else + /* We can fit the newline and blanks in before + the next word. */ + *nl++ = '\n'; + + if (nextline - nl >= fs->wmargin + || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin)) + /* Add blanks up to the wrap margin column. */ + for (i = 0; i < fs->wmargin; ++i) + *nl++ = ' '; + else + for (i = 0; i < fs->wmargin; ++i) +#ifdef USE_IN_LIBIO + if (_IO_fwide (fs->stream, 0) > 0) + putwc_unlocked (L' ', fs->stream); + else +#endif + putc_unlocked (' ', fs->stream); + + /* Copy the tail of the original buffer into the current buffer + position. */ + if (nl < nextline) + memmove (nl, nextline, buf + len - nextline); + len -= nextline - buf; + + /* Continue the scan on the remaining lines in the buffer. */ + buf = nl; + + /* Restore bufp to include all the remaining text. */ + fs->p = nl + len; + + /* Reset the counter of what has been output this line. If wmargin + is 0, we want to avoid the lmargin getting added, so we set + point_col to a magic value of -1 in that case. */ + fs->point_col = fs->wmargin ? fs->wmargin : -1; + } + } + + /* Remember that we've scanned as far as the end of the buffer. */ + fs->point_offs = fs->p - fs->buf; +} + +/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by + growing the buffer, or by flushing it. True is returned iff we succeed. */ +int +__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount) +{ + if ((size_t) (fs->end - fs->p) < amount) + { + ssize_t wrote; + + /* Flush FS's buffer. */ + __argp_fmtstream_update (fs); + +#ifdef _LIBC + __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); + wrote = fs->p - fs->buf; +#else + wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); +#endif + if (wrote == fs->p - fs->buf) + { + fs->p = fs->buf; + fs->point_offs = 0; + } + else + { + fs->p -= wrote; + fs->point_offs -= wrote; + memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf); + return 0; + } + + if ((size_t) (fs->end - fs->buf) < amount) + /* Gotta grow the buffer. */ + { + size_t old_size = fs->end - fs->buf; + size_t new_size = old_size + amount; + char *new_buf; + + if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size))) + { + __set_errno (ENOMEM); + return 0; + } + + fs->buf = new_buf; + fs->end = new_buf + new_size; + fs->p = fs->buf; + } + } + + return 1; +} + +ssize_t +__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) +{ + int out; + size_t avail; + size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */ + + do + { + va_list args; + + if (! __argp_fmtstream_ensure (fs, size_guess)) + return -1; + + va_start (args, fmt); + avail = fs->end - fs->p; + out = __vsnprintf (fs->p, avail, fmt, args); + va_end (args); + if ((size_t) out >= avail) + size_guess = out + 1; + } + while ((size_t) out >= avail); + + fs->p += out; + + return out; +} +#if 0 +/* Not exported. */ +#ifdef weak_alias +weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) +#endif +#endif + +#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ diff --git a/gnu/argp-fmtstream.h b/gnu/argp-fmtstream.h new file mode 100644 index 00000000..d8ff776f --- /dev/null +++ b/gnu/argp-fmtstream.h @@ -0,0 +1,356 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Word-wrapping and line-truncating streams. + Copyright (C) 1997, 2006-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +/* This package emulates glibc 'line_wrap_stream' semantics for systems that + don't have that. If the system does have it, it is just a wrapper for + that. This header file is only used internally while compiling argp, and + shouldn't be installed. */ + +#ifndef _ARGP_FMTSTREAM_H +#define _ARGP_FMTSTREAM_H + +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ +#endif + +#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \ + || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)) +/* line_wrap_stream is available, so use that. */ +#define ARGP_FMTSTREAM_USE_LINEWRAP +#endif + +#ifdef ARGP_FMTSTREAM_USE_LINEWRAP +/* Just be a simple wrapper for line_wrap_stream; the semantics are + *slightly* different, as line_wrap_stream doesn't actually make a new + object, it just modifies the given stream (reversibly) to do + line-wrapping. Since we control who uses this code, it doesn't matter. */ + +#include <linewrap.h> + +typedef FILE *argp_fmtstream_t; + +#define argp_make_fmtstream line_wrap_stream +#define __argp_make_fmtstream line_wrap_stream +#define argp_fmtstream_free line_unwrap_stream +#define __argp_fmtstream_free line_unwrap_stream + +#define __argp_fmtstream_putc(fs,ch) putc(ch,fs) +#define argp_fmtstream_putc(fs,ch) putc(ch,fs) +#define __argp_fmtstream_puts(fs,str) fputs(str,fs) +#define argp_fmtstream_puts(fs,str) fputs(str,fs) +#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) +#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) +#define __argp_fmtstream_printf fprintf +#define argp_fmtstream_printf fprintf + +#define __argp_fmtstream_lmargin line_wrap_lmargin +#define argp_fmtstream_lmargin line_wrap_lmargin +#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin +#define argp_fmtstream_set_lmargin line_wrap_set_lmargin +#define __argp_fmtstream_rmargin line_wrap_rmargin +#define argp_fmtstream_rmargin line_wrap_rmargin +#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin +#define argp_fmtstream_set_rmargin line_wrap_set_rmargin +#define __argp_fmtstream_wmargin line_wrap_wmargin +#define argp_fmtstream_wmargin line_wrap_wmargin +#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin +#define argp_fmtstream_set_wmargin line_wrap_set_wmargin +#define __argp_fmtstream_point line_wrap_point +#define argp_fmtstream_point line_wrap_point + +#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */ +/* Guess we have to define our own version. */ + +struct argp_fmtstream +{ + FILE *stream; /* The stream we're outputting to. */ + + size_t lmargin, rmargin; /* Left and right margins. */ + ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */ + + /* Point in buffer to which we've processed for wrapping, but not output. */ + size_t point_offs; + /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */ + ssize_t point_col; + + char *buf; /* Output buffer. */ + char *p; /* Current end of text in BUF. */ + char *end; /* Absolute end of BUF. */ +}; + +typedef struct argp_fmtstream *argp_fmtstream_t; + +/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines + written on it with LMARGIN spaces and limits them to RMARGIN columns + total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by + replacing the whitespace before them with a newline and WMARGIN spaces. + Otherwise, chars beyond RMARGIN are simply dropped until a newline. + Returns NULL if there was an error. */ +extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream, + size_t __lmargin, + size_t __rmargin, + ssize_t __wmargin); +extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream, + size_t __lmargin, + size_t __rmargin, + ssize_t __wmargin); + +/* Flush __FS to its stream, and free it (but don't close the stream). */ +extern void __argp_fmtstream_free (argp_fmtstream_t __fs); +extern void argp_fmtstream_free (argp_fmtstream_t __fs); + +extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs, + const char *__fmt, ...) + _GL_ATTRIBUTE_FORMAT ((printf, 2, 3)); +extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, + const char *__fmt, ...) + _GL_ATTRIBUTE_FORMAT ((printf, 2, 3)); + +#if _LIBC || !defined __OPTIMIZE__ +extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); +extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); + +extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); +extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); + +extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs, + const char *__str, size_t __len); +extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, + const char *__str, size_t __len); +#endif + +/* Access macros for various bits of state. */ +#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) +#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin) +#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin) +#define __argp_fmtstream_lmargin argp_fmtstream_lmargin +#define __argp_fmtstream_rmargin argp_fmtstream_rmargin +#define __argp_fmtstream_wmargin argp_fmtstream_wmargin + +#if _LIBC || !defined __OPTIMIZE__ +/* Set __FS's left margin to LMARGIN and return the old value. */ +extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, + size_t __lmargin); +extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, + size_t __lmargin); + +/* Set __FS's right margin to __RMARGIN and return the old value. */ +extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, + size_t __rmargin); +extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, + size_t __rmargin); + +/* Set __FS's wrap margin to __WMARGIN and return the old value. */ +extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, + size_t __wmargin); +extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, + size_t __wmargin); + +/* Return the column number of the current output point in __FS. */ +extern size_t argp_fmtstream_point (argp_fmtstream_t __fs); +extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs); +#endif + +/* Internal routines. */ +extern void _argp_fmtstream_update (argp_fmtstream_t __fs); +extern void __argp_fmtstream_update (argp_fmtstream_t __fs); +extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); +extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); + +#ifdef __OPTIMIZE__ +/* Inline versions of above routines. */ + +#if !_LIBC +#define __argp_fmtstream_putc argp_fmtstream_putc +#define __argp_fmtstream_puts argp_fmtstream_puts +#define __argp_fmtstream_write argp_fmtstream_write +#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin +#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin +#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin +#define __argp_fmtstream_point argp_fmtstream_point +#define __argp_fmtstream_update _argp_fmtstream_update +#define __argp_fmtstream_ensure _argp_fmtstream_ensure +#endif + +#ifndef ARGP_FS_EI +# ifdef __GNUC__ + /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 + inline semantics, unless -fgnu89-inline is used. It defines a macro + __GNUC_STDC_INLINE__ to indicate this situation or a macro + __GNUC_GNU_INLINE__ to indicate the opposite situation. + + GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline + semantics but warns, unless -fgnu89-inline is used: + warning: C99 inline functions are not supported; using GNU89 + warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute + It defines a macro __GNUC_GNU_INLINE__ to indicate this situation. + + Whereas Apple GCC 4.0.1 build 5479 without -std=c99 or -std=gnu99 + implements the GNU C inline semantics and defines the macro + __GNUC_GNU_INLINE__, but it does not warn and does not support + __attribute__ ((__gnu_inline__)). + + All in all, these are the possible combinations. For every compiler, + we need to choose ARGP_FS_EI so that the corresponding table cell + contains an "ok". + + \ ARGP_FS_EI inline extern extern + \ inline inline + CC \ __attribute__ + ((gnu_inline)) + + gcc 4.3.0 error ok ok + gcc 4.3.0 -std=gnu99 -fgnu89-inline error ok ok + gcc 4.3.0 -std=gnu99 ok error ok + + gcc 4.2.2 error ok ok + gcc 4.2.2 -std=gnu99 -fgnu89-inline error ok ok + gcc 4.2.2 -std=gnu99 error warning ok + + gcc 4.1.2 error ok warning + gcc 4.1.2 -std=gnu99 error ok warning + + Apple gcc 4.0.1 error ok warning + Apple gcc 4.0.1 -std=gnu99 ok error warning + */ +# if defined __GNUC_STDC_INLINE__ +# define ARGP_FS_EI inline +# elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) +# define ARGP_FS_EI extern inline __attribute__ ((__gnu_inline__)) +# else +# define ARGP_FS_EI extern inline +# endif +# else + /* With other compilers, assume the ISO C99 meaning of 'inline', if + the compiler supports 'inline' at all. */ +# define ARGP_FS_EI inline +# endif +#endif + +ARGP_FS_EI size_t +__argp_fmtstream_write (argp_fmtstream_t __fs, + const char *__str, size_t __len) +{ + if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) + { + memcpy (__fs->p, __str, __len); + __fs->p += __len; + return __len; + } + else + return 0; +} + +ARGP_FS_EI int +__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str) +{ + size_t __len = strlen (__str); + if (__len) + { + size_t __wrote = __argp_fmtstream_write (__fs, __str, __len); + return __wrote == __len ? 0 : -1; + } + else + return 0; +} + +ARGP_FS_EI int +__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch) +{ + if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1)) + return *__fs->p++ = __ch; + else + return EOF; +} + +/* Set __FS's left margin to __LMARGIN and return the old value. */ +ARGP_FS_EI size_t +__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin) +{ + size_t __old; + if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) + __argp_fmtstream_update (__fs); + __old = __fs->lmargin; + __fs->lmargin = __lmargin; + return __old; +} + +/* Set __FS's right margin to __RMARGIN and return the old value. */ +ARGP_FS_EI size_t +__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin) +{ + size_t __old; + if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) + __argp_fmtstream_update (__fs); + __old = __fs->rmargin; + __fs->rmargin = __rmargin; + return __old; +} + +/* Set FS's wrap margin to __WMARGIN and return the old value. */ +ARGP_FS_EI size_t +__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin) +{ + size_t __old; + if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) + __argp_fmtstream_update (__fs); + __old = __fs->wmargin; + __fs->wmargin = __wmargin; + return __old; +} + +/* Return the column number of the current output point in __FS. */ +ARGP_FS_EI size_t +__argp_fmtstream_point (argp_fmtstream_t __fs) +{ + if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) + __argp_fmtstream_update (__fs); + return __fs->point_col >= 0 ? __fs->point_col : 0; +} + +#if !_LIBC +#undef __argp_fmtstream_putc +#undef __argp_fmtstream_puts +#undef __argp_fmtstream_write +#undef __argp_fmtstream_set_lmargin +#undef __argp_fmtstream_set_rmargin +#undef __argp_fmtstream_set_wmargin +#undef __argp_fmtstream_point +#undef __argp_fmtstream_update +#undef __argp_fmtstream_ensure +#endif + +#endif /* __OPTIMIZE__ */ + +#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */ + +#endif /* argp-fmtstream.h */ diff --git a/gnu/argp-fs-xinl.c b/gnu/argp-fs-xinl.c new file mode 100644 index 00000000..15d1f027 --- /dev/null +++ b/gnu/argp-fs-xinl.c @@ -0,0 +1,44 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Real definitions for extern inline functions in argp-fmtstream.h + Copyright (C) 1997, 2003-2004, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#define ARGP_FS_EI +#undef __OPTIMIZE__ +#define __OPTIMIZE__ 1 +#include "argp-fmtstream.h" + +#if 0 +/* Not exported. */ +/* Add weak aliases. */ +#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias) + +weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc) +weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts) +weak_alias (__argp_fmtstream_write, argp_fmtstream_write) +weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin) +weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin) +weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin) +weak_alias (__argp_fmtstream_point, argp_fmtstream_point) + +#endif +#endif diff --git a/gnu/argp-help.c b/gnu/argp-help.c new file mode 100644 index 00000000..eea7aa1b --- /dev/null +++ b/gnu/argp-help.c @@ -0,0 +1,1956 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Hierarchial argument parsing help output + Copyright (C) 1995-2005, 2007, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <alloca.h> +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <stdarg.h> +#include <ctype.h> +#include <limits.h> +#ifdef USE_IN_LIBIO +# include <wchar.h> +#endif + +#ifdef _LIBC +# include <libintl.h> +# undef dgettext +# define dgettext(domain, msgid) \ + INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) +#else +# include "gettext.h" +#endif + +#include "argp.h" +#include "argp-fmtstream.h" +#include "argp-namefrob.h" + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + +/* User-selectable (using an environment variable) formatting parameters. + + These may be specified in an environment variable called 'ARGP_HELP_FMT', + with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2 + Where VALn must be a positive integer. The list of variables is in the + UPARAM_NAMES vector, below. */ + +/* Default parameters. */ +#define DUP_ARGS 0 /* True if option argument can be duplicated. */ +#define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */ +#define SHORT_OPT_COL 2 /* column in which short options start */ +#define LONG_OPT_COL 6 /* column in which long options start */ +#define DOC_OPT_COL 2 /* column in which doc options start */ +#define OPT_DOC_COL 29 /* column in which option text starts */ +#define HEADER_COL 1 /* column in which group headers are printed */ +#define USAGE_INDENT 12 /* indentation of wrapped usage lines */ +#define RMARGIN 79 /* right margin used for wrapping */ + +/* User-selectable (using an environment variable) formatting parameters. + They must all be of type 'int' for the parsing code to work. */ +struct uparams +{ + /* If true, arguments for an option are shown with both short and long + options, even when a given option has both, e.g. '-x ARG, --longx=ARG'. + If false, then if an option has both, the argument is only shown with + the long one, e.g., '-x, --longx=ARG', and a message indicating that + this really means both is printed below the options. */ + int dup_args; + + /* This is true if when DUP_ARGS is false, and some duplicate arguments have + been suppressed, an explanatory message should be printed. */ + int dup_args_note; + + /* Various output columns. */ + int short_opt_col; /* column in which short options start */ + int long_opt_col; /* column in which long options start */ + int doc_opt_col; /* column in which doc options start */ + int opt_doc_col; /* column in which option text starts */ + int header_col; /* column in which group headers are printed */ + int usage_indent; /* indentation of wrapped usage lines */ + int rmargin; /* right margin used for wrapping */ + + int valid; /* True when the values in here are valid. */ +}; + +/* This is a global variable, as user options are only ever read once. */ +static struct uparams uparams = { + DUP_ARGS, DUP_ARGS_NOTE, + SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL, + USAGE_INDENT, RMARGIN, + 0 +}; + +/* A particular uparam, and what the user name is. */ +struct uparam_name +{ + const char *name; /* User name. */ + int is_bool; /* Whether it's 'boolean'. */ + size_t uparams_offs; /* Location of the (int) field in UPARAMS. */ +}; + +/* The name-field mappings we know about. */ +static const struct uparam_name uparam_names[] = +{ + { "dup-args", 1, offsetof (struct uparams, dup_args) }, + { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) }, + { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) }, + { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) }, + { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) }, + { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) }, + { "header-col", 0, offsetof (struct uparams, header_col) }, + { "usage-indent", 0, offsetof (struct uparams, usage_indent) }, + { "rmargin", 0, offsetof (struct uparams, rmargin) }, + { 0 } +}; + +static void +validate_uparams (const struct argp_state *state, struct uparams *upptr) +{ + const struct uparam_name *up; + + for (up = uparam_names; up->name; up++) + { + if (up->is_bool + || up->uparams_offs == offsetof (struct uparams, rmargin)) + continue; + if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) + { + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, + "\ +ARGP_HELP_FMT: %s value is less than or equal to %s"), + "rmargin", up->name); + return; + } + } + uparams = *upptr; + uparams.valid = 1; +} + +/* Read user options from the environment, and fill in UPARAMS appropiately. */ +static void +fill_in_uparams (const struct argp_state *state) +{ + const char *var = getenv ("ARGP_HELP_FMT"); + struct uparams new_params = uparams; + +#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0); + + if (var) + { + /* Parse var. */ + while (*var) + { + SKIPWS (var); + + if (isalpha ((unsigned char) *var)) + { + size_t var_len; + const struct uparam_name *un; + int unspec = 0, val = 0; + const char *arg = var; + + while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_') + arg++; + var_len = arg - var; + + SKIPWS (arg); + + if (*arg == '\0' || *arg == ',') + unspec = 1; + else if (*arg == '=') + { + arg++; + SKIPWS (arg); + } + + if (unspec) + { + if (var[0] == 'n' && var[1] == 'o' && var[2] == '-') + { + val = 0; + var += 3; + var_len -= 3; + } + else + val = 1; + } + else if (isdigit ((unsigned char) *arg)) + { + val = atoi (arg); + while (isdigit ((unsigned char) *arg)) + arg++; + SKIPWS (arg); + } + + for (un = uparam_names; un->name; un++) + if (strlen (un->name) == var_len + && strncmp (var, un->name, var_len) == 0) + { + if (unspec && !un->is_bool) + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, + "\ +%.*s: ARGP_HELP_FMT parameter requires a value"), + (int) var_len, var); + else if (val < 0) + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, + "\ +%.*s: ARGP_HELP_FMT parameter must be positive"), + (int) var_len, var); + else + *(int *)((char *)&new_params + un->uparams_offs) = val; + break; + } + if (! un->name) + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, "\ +%.*s: Unknown ARGP_HELP_FMT parameter"), + (int) var_len, var); + + var = arg; + if (*var == ',') + var++; + } + else if (*var) + { + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, + "Garbage in ARGP_HELP_FMT: %s"), var); + break; + } + } + validate_uparams (state, &new_params); + } +} + +/* Returns true if OPT hasn't been marked invisible. Visibility only affects + whether OPT is displayed or used in sorting, not option shadowing. */ +#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN)) + +/* Returns true if OPT is an alias for an earlier option. */ +#define oalias(opt) ((opt)->flags & OPTION_ALIAS) + +/* Returns true if OPT is a documentation-only entry. */ +#define odoc(opt) ((opt)->flags & OPTION_DOC) + +/* Returns true if OPT should not be translated */ +#define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS) + +/* Returns true if OPT is the end-of-list marker for a list of options. */ +#define oend(opt) __option_is_end (opt) + +/* Returns true if OPT has a short option. */ +#define oshort(opt) __option_is_short (opt) + +/* + The help format for a particular option is like: + + -xARG, -yARG, --long1=ARG, --long2=ARG Documentation... + + Where ARG will be omitted if there's no argument, for this option, or + will be surrounded by "[" and "]" appropiately if the argument is + optional. The documentation string is word-wrapped appropiately, and if + the list of options is long enough, it will be started on a separate line. + If there are no short options for a given option, the first long option is + indented slighly in a way that's supposed to make most long options appear + to be in a separate column. + + For example, the following output (from ps): + + -p PID, --pid=PID List the process PID + --pgrp=PGRP List processes in the process group PGRP + -P, -x, --no-parent Include processes without parents + -Q, --all-fields Don't elide unusable fields (normally if there's + some reason ps can't print a field for any + process, it's removed from the output entirely) + -r, --reverse, --gratuitously-long-reverse-option + Reverse the order of any sort + --session[=SID] Add the processes from the session SID (which + defaults to the sid of the current process) + + Here are some more options: + -f ZOT, --foonly=ZOT Glork a foonly + -z, --zaza Snit a zar + + -?, --help Give this help list + --usage Give a short usage message + -V, --version Print program version + + The struct argp_option array for the above could look like: + + { + {"pid", 'p', "PID", 0, "List the process PID"}, + {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"}, + {"no-parent", 'P', 0, 0, "Include processes without parents"}, + {0, 'x', 0, OPTION_ALIAS}, + {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally" + " if there's some reason ps can't" + " print a field for any process, it's" + " removed from the output entirely)" }, + {"reverse", 'r', 0, 0, "Reverse the order of any sort"}, + {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS}, + {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL, + "Add the processes from the session" + " SID (which defaults to the sid of" + " the current process)" }, + + {0,0,0,0, "Here are some more options:"}, + {"foonly", 'f', "ZOT", 0, "Glork a foonly"}, + {"zaza", 'z', 0, 0, "Snit a zar"}, + + {0} + } + + Note that the last three options are automatically supplied by argp_parse, + unless you tell it not to with ARGP_NO_HELP. + +*/ + +/* Returns true if CH occurs between BEG and END. */ +static int +find_char (char ch, char *beg, char *end) +{ + while (beg < end) + if (*beg == ch) + return 1; + else + beg++; + return 0; +} + +struct hol_cluster; /* fwd decl */ + +struct hol_entry +{ + /* First option. */ + const struct argp_option *opt; + /* Number of options (including aliases). */ + unsigned num; + + /* A pointers into the HOL's short_options field, to the first short option + letter for this entry. The order of the characters following this point + corresponds to the order of options pointed to by OPT, and there are at + most NUM. A short option recorded in an option following OPT is only + valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's + probably been shadowed by some other entry). */ + char *short_options; + + /* Entries are sorted by their group first, in the order: + 1, 2, ..., n, 0, -m, ..., -2, -1 + and then alphabetically within each group. The default is 0. */ + int group; + + /* The cluster of options this entry belongs to, or 0 if none. */ + struct hol_cluster *cluster; + + /* The argp from which this option came. */ + const struct argp *argp; + + /* Position in the array */ + unsigned ord; +}; + +/* A cluster of entries to reflect the argp tree structure. */ +struct hol_cluster +{ + /* A descriptive header printed before options in this cluster. */ + const char *header; + + /* Used to order clusters within the same group with the same parent, + according to the order in which they occurred in the parent argp's child + list. */ + int index; + + /* How to sort this cluster with respect to options and other clusters at the + same depth (clusters always follow options in the same group). */ + int group; + + /* The cluster to which this cluster belongs, or 0 if it's at the base + level. */ + struct hol_cluster *parent; + + /* The argp from which this cluster is (eventually) derived. */ + const struct argp *argp; + + /* The distance this cluster is from the root. */ + int depth; + + /* Clusters in a given hol are kept in a linked list, to make freeing them + possible. */ + struct hol_cluster *next; +}; + +/* A list of options for help. */ +struct hol +{ + /* An array of hol_entry's. */ + struct hol_entry *entries; + /* The number of entries in this hol. If this field is zero, the others + are undefined. */ + unsigned num_entries; + + /* A string containing all short options in this HOL. Each entry contains + pointers into this string, so the order can't be messed with blindly. */ + char *short_options; + + /* Clusters of entries in this hol. */ + struct hol_cluster *clusters; +}; + +/* Create a struct hol from the options in ARGP. CLUSTER is the + hol_cluster in which these entries occur, or 0, if at the root. */ +static struct hol * +make_hol (const struct argp *argp, struct hol_cluster *cluster) +{ + char *so; + const struct argp_option *o; + const struct argp_option *opts = argp->options; + struct hol_entry *entry; + unsigned num_short_options = 0; + struct hol *hol = malloc (sizeof (struct hol)); + + assert (hol); + + hol->num_entries = 0; + hol->clusters = 0; + + if (opts) + { + int cur_group = 0; + + /* The first option must not be an alias. */ + assert (! oalias (opts)); + + /* Calculate the space needed. */ + for (o = opts; ! oend (o); o++) + { + if (! oalias (o)) + hol->num_entries++; + if (oshort (o)) + num_short_options++; /* This is an upper bound. */ + } + + hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries); + hol->short_options = malloc (num_short_options + 1); + + assert (hol->entries && hol->short_options); + if (SIZE_MAX <= UINT_MAX) + assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry)); + + /* Fill in the entries. */ + so = hol->short_options; + for (o = opts, entry = hol->entries; ! oend (o); entry++) + { + entry->opt = o; + entry->num = 0; + entry->short_options = so; + entry->group = cur_group = + o->group + ? o->group + : ((!o->name && !o->key) + ? cur_group + 1 + : cur_group); + entry->cluster = cluster; + entry->argp = argp; + + do + { + entry->num++; + if (oshort (o) && ! find_char (o->key, hol->short_options, so)) + /* O has a valid short option which hasn't already been used.*/ + *so++ = o->key; + o++; + } + while (! oend (o) && oalias (o)); + } + *so = '\0'; /* null terminated so we can find the length */ + } + + return hol; +} + +/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the + associated argp child list entry), INDEX, and PARENT, and return a pointer + to it. ARGP is the argp that this cluster results from. */ +static struct hol_cluster * +hol_add_cluster (struct hol *hol, int group, const char *header, int index, + struct hol_cluster *parent, const struct argp *argp) +{ + struct hol_cluster *cl = malloc (sizeof (struct hol_cluster)); + if (cl) + { + cl->group = group; + cl->header = header; + + cl->index = index; + cl->parent = parent; + cl->argp = argp; + cl->depth = parent ? parent->depth + 1 : 0; + + cl->next = hol->clusters; + hol->clusters = cl; + } + return cl; +} + +/* Free HOL and any resources it uses. */ +static void +hol_free (struct hol *hol) +{ + struct hol_cluster *cl = hol->clusters; + + while (cl) + { + struct hol_cluster *next = cl->next; + free (cl); + cl = next; + } + + if (hol->num_entries > 0) + { + free (hol->entries); + free (hol->short_options); + } + + free (hol); +} + +static int +hol_entry_short_iterate (const struct hol_entry *entry, + int (*func)(const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie), + const char *domain, void *cookie) +{ + unsigned nopts; + int val = 0; + const struct argp_option *opt, *real = entry->opt; + char *so = entry->short_options; + + for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) + if (oshort (opt) && *so == opt->key) + { + if (!oalias (opt)) + real = opt; + if (ovisible (opt)) + val = (*func)(opt, real, domain, cookie); + so++; + } + + return val; +} + +static inline int +#if __GNUC__ >= 3 +__attribute__ ((always_inline)) +#endif +hol_entry_long_iterate (const struct hol_entry *entry, + int (*func)(const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie), + const char *domain, void *cookie) +{ + unsigned nopts; + int val = 0; + const struct argp_option *opt, *real = entry->opt; + + for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) + if (opt->name) + { + if (!oalias (opt)) + real = opt; + if (ovisible (opt)) + val = (*func)(opt, real, domain, cookie); + } + + return val; +} + +/* Iterator that returns true for the first short option. */ +static int +until_short (const struct argp_option *opt, const struct argp_option *real, + const char *domain, void *cookie) +{ + return oshort (opt) ? opt->key : 0; +} + +/* Returns the first valid short option in ENTRY, or 0 if there is none. */ +static char +hol_entry_first_short (const struct hol_entry *entry) +{ + return hol_entry_short_iterate (entry, until_short, + entry->argp->argp_domain, 0); +} + +/* Returns the first valid long option in ENTRY, or 0 if there is none. */ +static const char * +hol_entry_first_long (const struct hol_entry *entry) +{ + const struct argp_option *opt; + unsigned num; + for (opt = entry->opt, num = entry->num; num > 0; opt++, num--) + if (opt->name && ovisible (opt)) + return opt->name; + return 0; +} + +/* Returns the entry in HOL with the long option name NAME, or 0 if there is + none. */ +static struct hol_entry * +hol_find_entry (struct hol *hol, const char *name) +{ + struct hol_entry *entry = hol->entries; + unsigned num_entries = hol->num_entries; + + while (num_entries-- > 0) + { + const struct argp_option *opt = entry->opt; + unsigned num_opts = entry->num; + + while (num_opts-- > 0) + if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0) + return entry; + else + opt++; + + entry++; + } + + return 0; +} + +/* If an entry with the long option NAME occurs in HOL, set it's special + sort position to GROUP. */ +static void +hol_set_group (struct hol *hol, const char *name, int group) +{ + struct hol_entry *entry = hol_find_entry (hol, name); + if (entry) + entry->group = group; +} + +/* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1. + EQ is what to return if GROUP1 and GROUP2 are the same. */ +static int +group_cmp (int group1, int group2, int eq) +{ + if (group1 == group2) + return eq; + else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0)) + return group1 - group2; + else + return group2 - group1; +} + +/* Compare clusters CL1 & CL2 by the order that they should appear in + output. */ +static int +hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2) +{ + /* If one cluster is deeper than the other, use its ancestor at the same + level, so that finding the common ancestor is straightforward. + + clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */ + while (cl1->depth > cl2->depth) + cl1 = cl1->parent; + while (cl2->depth > cl1->depth) + cl2 = cl2->parent; + + /* Now reduce both clusters to their ancestors at the point where both have + a common parent; these can be directly compared. */ + while (cl1->parent != cl2->parent) + cl1 = cl1->parent, cl2 = cl2->parent; + + return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index); +} + +/* Return the ancestor of CL that's just below the root (i.e., has a parent + of 0). */ +static struct hol_cluster * +hol_cluster_base (struct hol_cluster *cl) +{ + while (cl->parent) + cl = cl->parent; + return cl; +} + +/* Return true if CL1 is a child of CL2. */ +static int +hol_cluster_is_child (const struct hol_cluster *cl1, + const struct hol_cluster *cl2) +{ + while (cl1 && cl1 != cl2) + cl1 = cl1->parent; + return cl1 == cl2; +} + +/* Given the name of an OPTION_DOC option, modifies NAME to start at the tail + that should be used for comparisons, and returns true iff it should be + treated as a non-option. */ +static int +canon_doc_option (const char **name) +{ + int non_opt; + + if (!*name) + non_opt = 1; + else + { + /* Skip initial whitespace. */ + while (isspace ((unsigned char) **name)) + (*name)++; + /* Decide whether this looks like an option (leading '-') or not. */ + non_opt = (**name != '-'); + /* Skip until part of name used for sorting. */ + while (**name && !isalnum ((unsigned char) **name)) + (*name)++; + } + return non_opt; +} + +#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1) + +/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help + listing. */ +static int +hol_entry_cmp (const struct hol_entry *entry1, + const struct hol_entry *entry2) +{ + /* The group numbers by which the entries should be ordered; if either is + in a cluster, then this is just the group within the cluster. */ + int group1 = entry1->group, group2 = entry2->group; + int rc; + + if (entry1->cluster != entry2->cluster) + { + /* The entries are not within the same cluster, so we can't compare them + directly, we have to use the appropiate clustering level too. */ + if (! entry1->cluster) + /* ENTRY1 is at the "base level", not in a cluster, so we have to + compare it's group number with that of the base cluster in which + ENTRY2 resides. Note that if they're in the same group, the + clustered option always comes laster. */ + return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1); + else if (! entry2->cluster) + /* Likewise, but ENTRY2's not in a cluster. */ + return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1); + else + /* Both entries are in clusters, we can just compare the clusters. */ + return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ? + rc : HOL_ENTRY_PTRCMP (entry1, entry2); + } + else if (group1 == group2) + /* The entries are both in the same cluster and group, so compare them + alphabetically. */ + { + int short1 = hol_entry_first_short (entry1); + int short2 = hol_entry_first_short (entry2); + int doc1 = odoc (entry1->opt); + int doc2 = odoc (entry2->opt); + const char *long1 = hol_entry_first_long (entry1); + const char *long2 = hol_entry_first_long (entry2); + + if (doc1) + doc1 = canon_doc_option (&long1); + if (doc2) + doc2 = canon_doc_option (&long2); + + if (doc1 != doc2) + /* "documentation" options always follow normal options (or + documentation options that *look* like normal options). */ + return doc1 - doc2; + else if (!short1 && !short2 && long1 && long2) + /* Only long options. */ + return (rc = __strcasecmp (long1, long2)) ? + rc : HOL_ENTRY_PTRCMP (entry1, entry2); + else + /* Compare short/short, long/short, short/long, using the first + character of long options. Entries without *any* valid + options (such as options with OPTION_HIDDEN set) will be put + first, but as they're not displayed, it doesn't matter where + they are. */ + { + unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0; + unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0; + /* Use tolower, not _tolower, since only the former is + guaranteed to work on something already lower case. */ + int lower_cmp = tolower (first1) - tolower (first2); + /* Compare ignoring case, except when the options are both the + same letter, in which case lower-case always comes first. */ + return lower_cmp ? lower_cmp : + (rc = first2 - first1) ? + rc : HOL_ENTRY_PTRCMP (entry1, entry2); + } + } + else + /* Within the same cluster, but not the same group, so just compare + groups. */ + return group_cmp (group1, group2, HOL_ENTRY_PTRCMP (entry1, entry2)); +} + +/* Version of hol_entry_cmp with correct signature for qsort. */ +static int +hol_entry_qcmp (const void *entry1_v, const void *entry2_v) +{ + return hol_entry_cmp (entry1_v, entry2_v); +} + +/* Sort HOL by group and alphabetically by option name (with short options + taking precedence over long). Since the sorting is for display purposes + only, the shadowing of options isn't effected. */ +static void +hol_sort (struct hol *hol) +{ + if (hol->num_entries > 0) + { + unsigned i; + struct hol_entry *e; + for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++) + e->ord = i; + qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry), + hol_entry_qcmp); + } +} + +/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow + any in MORE with the same name. */ +static void +hol_append (struct hol *hol, struct hol *more) +{ + struct hol_cluster **cl_end = &hol->clusters; + + /* Steal MORE's cluster list, and add it to the end of HOL's. */ + while (*cl_end) + cl_end = &(*cl_end)->next; + *cl_end = more->clusters; + more->clusters = 0; + + /* Merge entries. */ + if (more->num_entries > 0) + { + if (hol->num_entries == 0) + { + hol->num_entries = more->num_entries; + hol->entries = more->entries; + hol->short_options = more->short_options; + more->num_entries = 0; /* Mark MORE's fields as invalid. */ + } + else + /* Append the entries in MORE to those in HOL, taking care to only add + non-shadowed SHORT_OPTIONS values. */ + { + unsigned left; + char *so, *more_so; + struct hol_entry *e; + unsigned num_entries = hol->num_entries + more->num_entries; + struct hol_entry *entries = + malloc (num_entries * sizeof (struct hol_entry)); + unsigned hol_so_len = strlen (hol->short_options); + char *short_options = + malloc (hol_so_len + strlen (more->short_options) + 1); + + assert (entries && short_options); + if (SIZE_MAX <= UINT_MAX) + assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry)); + + __mempcpy (__mempcpy (entries, hol->entries, + hol->num_entries * sizeof (struct hol_entry)), + more->entries, + more->num_entries * sizeof (struct hol_entry)); + + __mempcpy (short_options, hol->short_options, hol_so_len); + + /* Fix up the short options pointers from HOL. */ + for (e = entries, left = hol->num_entries; left > 0; e++, left--) + e->short_options = + short_options + (e->short_options - hol->short_options); + + /* Now add the short options from MORE, fixing up its entries + too. */ + so = short_options + hol_so_len; + more_so = more->short_options; + for (left = more->num_entries; left > 0; e++, left--) + { + int opts_left; + const struct argp_option *opt; + + e->short_options = so; + + for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--) + { + int ch = *more_so; + if (oshort (opt) && ch == opt->key) + /* The next short option in MORE_SO, CH, is from OPT. */ + { + if (! find_char (ch, short_options, + short_options + hol_so_len)) + /* The short option CH isn't shadowed by HOL's options, + so add it to the sum. */ + *so++ = ch; + more_so++; + } + } + } + + *so = '\0'; + + free (hol->entries); + free (hol->short_options); + + hol->entries = entries; + hol->num_entries = num_entries; + hol->short_options = short_options; + } + } + + hol_free (more); +} + +/* Inserts enough spaces to make sure STREAM is at column COL. */ +static void +indent_to (argp_fmtstream_t stream, unsigned col) +{ + int needed = col - __argp_fmtstream_point (stream); + while (needed-- > 0) + __argp_fmtstream_putc (stream, ' '); +} + +/* Output to STREAM either a space, or a newline if there isn't room for at + least ENSURE characters before the right margin. */ +static void +space (argp_fmtstream_t stream, size_t ensure) +{ + if (__argp_fmtstream_point (stream) + ensure + >= __argp_fmtstream_rmargin (stream)) + __argp_fmtstream_putc (stream, '\n'); + else + __argp_fmtstream_putc (stream, ' '); +} + +/* If the option REAL has an argument, we print it in using the printf + format REQ_FMT or OPT_FMT depending on whether it's a required or + optional argument. */ +static void +arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt, + const char *domain, argp_fmtstream_t stream) +{ + if (real->arg) + { + if (real->flags & OPTION_ARG_OPTIONAL) + __argp_fmtstream_printf (stream, opt_fmt, + dgettext (domain, real->arg)); + else + __argp_fmtstream_printf (stream, req_fmt, + dgettext (domain, real->arg)); + } +} + +/* Helper functions for hol_entry_help. */ + +/* State used during the execution of hol_help. */ +struct hol_help_state +{ + /* PREV_ENTRY should contain the previous entry printed, or 0. */ + struct hol_entry *prev_entry; + + /* If an entry is in a different group from the previous one, and SEP_GROUPS + is true, then a blank line will be printed before any output. */ + int sep_groups; + + /* True if a duplicate option argument was suppressed (only ever set if + UPARAMS.dup_args is false). */ + int suppressed_dup_arg; +}; + +/* Some state used while printing a help entry (used to communicate with + helper functions). See the doc for hol_entry_help for more info, as most + of the fields are copied from its arguments. */ +struct pentry_state +{ + const struct hol_entry *entry; + argp_fmtstream_t stream; + struct hol_help_state *hhstate; + + /* True if nothing's been printed so far. */ + int first; + + /* If non-zero, the state that was used to print this help. */ + const struct argp_state *state; +}; + +/* If a user doc filter should be applied to DOC, do so. */ +static const char * +filter_doc (const char *doc, int key, const struct argp *argp, + const struct argp_state *state) +{ + if (argp->help_filter) + /* We must apply a user filter to this output. */ + { + void *input = __argp_input (argp, state); + return (*argp->help_filter) (key, doc, input); + } + else + /* No filter. */ + return doc; +} + +/* Prints STR as a header line, with the margin lines set appropiately, and + notes the fact that groups should be separated with a blank line. ARGP is + the argp that should dictate any user doc filtering to take place. Note + that the previous wrap margin isn't restored, but the left margin is reset + to 0. */ +static void +print_header (const char *str, const struct argp *argp, + struct pentry_state *pest) +{ + const char *tstr = dgettext (argp->argp_domain, str); + const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state); + + if (fstr) + { + if (*fstr) + { + if (pest->hhstate->prev_entry) + /* Precede with a blank line. */ + __argp_fmtstream_putc (pest->stream, '\n'); + indent_to (pest->stream, uparams.header_col); + __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col); + __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col); + __argp_fmtstream_puts (pest->stream, fstr); + __argp_fmtstream_set_lmargin (pest->stream, 0); + __argp_fmtstream_putc (pest->stream, '\n'); + } + + pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */ + } + + if (fstr != tstr) + free ((char *) fstr); +} + +/* Inserts a comma if this isn't the first item on the line, and then makes + sure we're at least to column COL. If this *is* the first item on a line, + prints any pending whitespace/headers that should precede this line. Also + clears FIRST. */ +static void +comma (unsigned col, struct pentry_state *pest) +{ + if (pest->first) + { + const struct hol_entry *pe = pest->hhstate->prev_entry; + const struct hol_cluster *cl = pest->entry->cluster; + + if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group) + __argp_fmtstream_putc (pest->stream, '\n'); + + if (cl && cl->header && *cl->header + && (!pe + || (pe->cluster != cl + && !hol_cluster_is_child (pe->cluster, cl)))) + /* If we're changing clusters, then this must be the start of the + ENTRY's cluster unless that is an ancestor of the previous one + (in which case we had just popped into a sub-cluster for a bit). + If so, then print the cluster's header line. */ + { + int old_wm = __argp_fmtstream_wmargin (pest->stream); + print_header (cl->header, cl->argp, pest); + __argp_fmtstream_set_wmargin (pest->stream, old_wm); + } + + pest->first = 0; + } + else + __argp_fmtstream_puts (pest->stream, ", "); + + indent_to (pest->stream, col); +} + +/* Print help for ENTRY to STREAM. */ +static void +hol_entry_help (struct hol_entry *entry, const struct argp_state *state, + argp_fmtstream_t stream, struct hol_help_state *hhstate) +{ + unsigned num; + const struct argp_option *real = entry->opt, *opt; + char *so = entry->short_options; + int have_long_opt = 0; /* We have any long options. */ + /* Saved margins. */ + int old_lm = __argp_fmtstream_set_lmargin (stream, 0); + int old_wm = __argp_fmtstream_wmargin (stream); + /* PEST is a state block holding some of our variables that we'd like to + share with helper functions. */ + struct pentry_state pest; + + pest.entry = entry; + pest.stream = stream; + pest.hhstate = hhstate; + pest.first = 1; + pest.state = state; + + if (! odoc (real)) + for (opt = real, num = entry->num; num > 0; opt++, num--) + if (opt->name && ovisible (opt)) + { + have_long_opt = 1; + break; + } + + /* First emit short options. */ + __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */ + for (opt = real, num = entry->num; num > 0; opt++, num--) + if (oshort (opt) && opt->key == *so) + /* OPT has a valid (non shadowed) short option. */ + { + if (ovisible (opt)) + { + comma (uparams.short_opt_col, &pest); + __argp_fmtstream_putc (stream, '-'); + __argp_fmtstream_putc (stream, *so); + if (!have_long_opt || uparams.dup_args) + arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream); + else if (real->arg) + hhstate->suppressed_dup_arg = 1; + } + so++; + } + + /* Now, long options. */ + if (odoc (real)) + /* A "documentation" option. */ + { + __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col); + for (opt = real, num = entry->num; num > 0; opt++, num--) + if (opt->name && *opt->name && ovisible (opt)) + { + comma (uparams.doc_opt_col, &pest); + /* Calling dgettext here isn't quite right, since sorting will + have been done on the original; but documentation options + should be pretty rare anyway... */ + __argp_fmtstream_puts (stream, + onotrans (opt) ? + opt->name : + dgettext (state->root_argp->argp_domain, + opt->name)); + } + } + else + /* A real long option. */ + { + int first_long_opt = 1; + + __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col); + for (opt = real, num = entry->num; num > 0; opt++, num--) + if (opt->name && ovisible (opt)) + { + comma (uparams.long_opt_col, &pest); + __argp_fmtstream_printf (stream, "--%s", opt->name); + if (first_long_opt || uparams.dup_args) + arg (real, "=%s", "[=%s]", state->root_argp->argp_domain, + stream); + else if (real->arg) + hhstate->suppressed_dup_arg = 1; + } + } + + /* Next, documentation strings. */ + __argp_fmtstream_set_lmargin (stream, 0); + + if (pest.first) + { + /* Didn't print any switches, what's up? */ + if (!oshort (real) && !real->name) + /* This is a group header, print it nicely. */ + print_header (real->doc, entry->argp, &pest); + else + /* Just a totally shadowed option or null header; print nothing. */ + goto cleanup; /* Just return, after cleaning up. */ + } + else + { + const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain, + real->doc) : 0; + const char *fstr = filter_doc (tstr, real->key, entry->argp, state); + if (fstr && *fstr) + { + unsigned int col = __argp_fmtstream_point (stream); + + __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col); + __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col); + + if (col > (unsigned int) (uparams.opt_doc_col + 3)) + __argp_fmtstream_putc (stream, '\n'); + else if (col >= (unsigned int) uparams.opt_doc_col) + __argp_fmtstream_puts (stream, " "); + else + indent_to (stream, uparams.opt_doc_col); + + __argp_fmtstream_puts (stream, fstr); + } + if (fstr && fstr != tstr) + free ((char *) fstr); + + /* Reset the left margin. */ + __argp_fmtstream_set_lmargin (stream, 0); + __argp_fmtstream_putc (stream, '\n'); + } + + hhstate->prev_entry = entry; + +cleanup: + __argp_fmtstream_set_lmargin (stream, old_lm); + __argp_fmtstream_set_wmargin (stream, old_wm); +} + +/* Output a long help message about the options in HOL to STREAM. */ +static void +hol_help (struct hol *hol, const struct argp_state *state, + argp_fmtstream_t stream) +{ + unsigned num; + struct hol_entry *entry; + struct hol_help_state hhstate = { 0, 0, 0 }; + + for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--) + hol_entry_help (entry, state, stream, &hhstate); + + if (hhstate.suppressed_dup_arg && uparams.dup_args_note) + { + const char *tstr = dgettext (state->root_argp->argp_domain, "\ +Mandatory or optional arguments to long options are also mandatory or \ +optional for any corresponding short options."); + const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE, + state ? state->root_argp : 0, state); + if (fstr && *fstr) + { + __argp_fmtstream_putc (stream, '\n'); + __argp_fmtstream_puts (stream, fstr); + __argp_fmtstream_putc (stream, '\n'); + } + if (fstr && fstr != tstr) + free ((char *) fstr); + } +} + +/* Helper functions for hol_usage. */ + +/* If OPT is a short option without an arg, append its key to the string + pointer pointer to by COOKIE, and advance the pointer. */ +static int +add_argless_short_opt (const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie) +{ + char **snao_end = cookie; + if (!(opt->arg || real->arg) + && !((opt->flags | real->flags) & OPTION_NO_USAGE)) + *(*snao_end)++ = opt->key; + return 0; +} + +/* If OPT is a short option with an arg, output a usage entry for it to the + stream pointed at by COOKIE. */ +static int +usage_argful_short_opt (const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie) +{ + argp_fmtstream_t stream = cookie; + const char *arg = opt->arg; + int flags = opt->flags | real->flags; + + if (! arg) + arg = real->arg; + + if (arg && !(flags & OPTION_NO_USAGE)) + { + arg = dgettext (domain, arg); + + if (flags & OPTION_ARG_OPTIONAL) + __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg); + else + { + /* Manually do line wrapping so that it (probably) won't + get wrapped at the embedded space. */ + space (stream, 6 + strlen (arg)); + __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg); + } + } + + return 0; +} + +/* Output a usage entry for the long option opt to the stream pointed at by + COOKIE. */ +static int +usage_long_opt (const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie) +{ + argp_fmtstream_t stream = cookie; + const char *arg = opt->arg; + int flags = opt->flags | real->flags; + + if (! arg) + arg = real->arg; + + if (! (flags & OPTION_NO_USAGE) && !odoc (opt)) + { + if (arg) + { + arg = dgettext (domain, arg); + if (flags & OPTION_ARG_OPTIONAL) + __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg); + else + __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg); + } + else + __argp_fmtstream_printf (stream, " [--%s]", opt->name); + } + + return 0; +} + +/* Print a short usage description for the arguments in HOL to STREAM. */ +static void +hol_usage (struct hol *hol, argp_fmtstream_t stream) +{ + if (hol->num_entries > 0) + { + unsigned nentries; + struct hol_entry *entry; + char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1); + char *snao_end = short_no_arg_opts; + + /* First we put a list of short options without arguments. */ + for (entry = hol->entries, nentries = hol->num_entries + ; nentries > 0 + ; entry++, nentries--) + hol_entry_short_iterate (entry, add_argless_short_opt, + entry->argp->argp_domain, &snao_end); + if (snao_end > short_no_arg_opts) + { + *snao_end++ = 0; + __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts); + } + + /* Now a list of short options *with* arguments. */ + for (entry = hol->entries, nentries = hol->num_entries + ; nentries > 0 + ; entry++, nentries--) + hol_entry_short_iterate (entry, usage_argful_short_opt, + entry->argp->argp_domain, stream); + + /* Finally, a list of long options (whew!). */ + for (entry = hol->entries, nentries = hol->num_entries + ; nentries > 0 + ; entry++, nentries--) + hol_entry_long_iterate (entry, usage_long_opt, + entry->argp->argp_domain, stream); + } +} + +/* Make a HOL containing all levels of options in ARGP. CLUSTER is the + cluster in which ARGP's entries should be clustered, or 0. */ +static struct hol * +argp_hol (const struct argp *argp, struct hol_cluster *cluster) +{ + const struct argp_child *child = argp->children; + struct hol *hol = make_hol (argp, cluster); + if (child) + while (child->argp) + { + struct hol_cluster *child_cluster = + ((child->group || child->header) + /* Put CHILD->argp within its own cluster. */ + ? hol_add_cluster (hol, child->group, child->header, + child - argp->children, cluster, argp) + /* Just merge it into the parent's cluster. */ + : cluster); + hol_append (hol, argp_hol (child->argp, child_cluster)) ; + child++; + } + return hol; +} + +/* Calculate how many different levels with alternative args strings exist in + ARGP. */ +static size_t +argp_args_levels (const struct argp *argp) +{ + size_t levels = 0; + const struct argp_child *child = argp->children; + + if (argp->args_doc && strchr (argp->args_doc, '\n')) + levels++; + + if (child) + while (child->argp) + levels += argp_args_levels ((child++)->argp); + + return levels; +} + +/* Print all the non-option args documented in ARGP to STREAM. Any output is + preceded by a space. LEVELS is a pointer to a byte vector the length + returned by argp_args_levels; it should be initialized to zero, and + updated by this routine for the next call if ADVANCE is true. True is + returned as long as there are more patterns to output. */ +static int +argp_args_usage (const struct argp *argp, const struct argp_state *state, + char **levels, int advance, argp_fmtstream_t stream) +{ + char *our_level = *levels; + int multiple = 0; + const struct argp_child *child = argp->children; + const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0; + const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state); + + if (fdoc) + { + const char *cp = fdoc; + nl = __strchrnul (cp, '\n'); + if (*nl != '\0') + /* This is a "multi-level" args doc; advance to the correct position + as determined by our state in LEVELS, and update LEVELS. */ + { + int i; + multiple = 1; + for (i = 0; i < *our_level; i++) + cp = nl + 1, nl = __strchrnul (cp, '\n'); + (*levels)++; + } + + /* Manually do line wrapping so that it (probably) won't get wrapped at + any embedded spaces. */ + space (stream, 1 + nl - cp); + + __argp_fmtstream_write (stream, cp, nl - cp); + } + if (fdoc && fdoc != tdoc) + free ((char *)fdoc); /* Free user's modified doc string. */ + + if (child) + while (child->argp) + advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream); + + if (advance && multiple) + { + /* Need to increment our level. */ + if (*nl) + /* There's more we can do here. */ + { + (*our_level)++; + advance = 0; /* Our parent shouldn't advance also. */ + } + else if (*our_level > 0) + /* We had multiple levels, but used them up; reset to zero. */ + *our_level = 0; + } + + return !advance; +} + +/* Print the documentation for ARGP to STREAM; if POST is false, then + everything preceeding a '\v' character in the documentation strings (or + the whole string, for those with none) is printed, otherwise, everything + following the '\v' character (nothing for strings without). Each separate + bit of documentation is separated a blank line, and if PRE_BLANK is true, + then the first is as well. If FIRST_ONLY is true, only the first + occurrence is output. Returns true if anything was output. */ +static int +argp_doc (const struct argp *argp, const struct argp_state *state, + int post, int pre_blank, int first_only, + argp_fmtstream_t stream) +{ + const char *text; + const char *inp_text; + size_t inp_text_len = 0; + const char *trans_text; + void *input = 0; + int anything = 0; + const struct argp_child *child = argp->children; + + if (argp->doc) + { + char *vt = strchr (argp->doc, '\v'); + if (vt) + { + if (post) + inp_text = vt + 1; + else + { + inp_text_len = vt - argp->doc; + inp_text = __strndup (argp->doc, inp_text_len); + } + } + else + inp_text = post ? 0 : argp->doc; + trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL; + } + else + trans_text = inp_text = 0; + + if (argp->help_filter) + /* We have to filter the doc strings. */ + { + input = __argp_input (argp, state); + text = + (*argp->help_filter) (post + ? ARGP_KEY_HELP_POST_DOC + : ARGP_KEY_HELP_PRE_DOC, + trans_text, input); + } + else + text = (const char *) trans_text; + + if (text) + { + if (pre_blank) + __argp_fmtstream_putc (stream, '\n'); + + __argp_fmtstream_puts (stream, text); + + if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream)) + __argp_fmtstream_putc (stream, '\n'); + + anything = 1; + } + + if (text && text != trans_text) + free ((char *) text); /* Free TEXT returned from the help filter. */ + + if (inp_text && inp_text_len) + free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */ + + if (post && argp->help_filter) + /* Now see if we have to output an ARGP_KEY_HELP_EXTRA text. */ + { + text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input); + if (text) + { + if (anything || pre_blank) + __argp_fmtstream_putc (stream, '\n'); + __argp_fmtstream_puts (stream, text); + free ((char *) text); + if (__argp_fmtstream_point (stream) + > __argp_fmtstream_lmargin (stream)) + __argp_fmtstream_putc (stream, '\n'); + anything = 1; + } + } + + if (child) + while (child->argp && !(first_only && anything)) + anything |= + argp_doc ((child++)->argp, state, + post, anything || pre_blank, first_only, + stream); + + return anything; +} + +/* Output a usage message for ARGP to STREAM. If called from + argp_state_help, STATE is the relevent parsing state. FLAGS are from the + set ARGP_HELP_*. NAME is what to use wherever a "program name" is + needed. */ +static void +_help (const struct argp *argp, const struct argp_state *state, FILE *stream, + unsigned flags, char *name) +{ + int anything = 0; /* Whether we've output anything. */ + struct hol *hol = 0; + argp_fmtstream_t fs; + + if (! stream) + return; + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __flockfile (stream); +#endif + + if (! uparams.valid) + fill_in_uparams (state); + + fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0); + if (! fs) + { +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __funlockfile (stream); +#endif + return; + } + + if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG)) + { + hol = argp_hol (argp, 0); + + /* If present, these options always come last. */ + hol_set_group (hol, "help", -1); + hol_set_group (hol, "version", -1); + + hol_sort (hol); + } + + if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE)) + /* Print a short "Usage:" message. */ + { + int first_pattern = 1, more_patterns; + size_t num_pattern_levels = argp_args_levels (argp); + char *pattern_levels = alloca (num_pattern_levels); + + memset (pattern_levels, 0, num_pattern_levels); + + do + { + int old_lm; + int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent); + char *levels = pattern_levels; + + if (first_pattern) + __argp_fmtstream_printf (fs, "%s %s", + dgettext (argp->argp_domain, "Usage:"), + name); + else + __argp_fmtstream_printf (fs, "%s %s", + dgettext (argp->argp_domain, " or: "), + name); + + /* We set the lmargin as well as the wmargin, because hol_usage + manually wraps options with newline to avoid annoying breaks. */ + old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent); + + if (flags & ARGP_HELP_SHORT_USAGE) + /* Just show where the options go. */ + { + if (hol->num_entries > 0) + __argp_fmtstream_puts (fs, dgettext (argp->argp_domain, + " [OPTION...]")); + } + else + /* Actually print the options. */ + { + hol_usage (hol, fs); + flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */ + } + + more_patterns = argp_args_usage (argp, state, &levels, 1, fs); + + __argp_fmtstream_set_wmargin (fs, old_wm); + __argp_fmtstream_set_lmargin (fs, old_lm); + + __argp_fmtstream_putc (fs, '\n'); + anything = 1; + + first_pattern = 0; + } + while (more_patterns); + } + + if (flags & ARGP_HELP_PRE_DOC) + anything |= argp_doc (argp, state, 0, 0, 1, fs); + + if (flags & ARGP_HELP_SEE) + { + __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\ +Try '%s --help' or '%s --usage' for more information.\n"), + name, name); + anything = 1; + } + + if (flags & ARGP_HELP_LONG) + /* Print a long, detailed help message. */ + { + /* Print info about all the options. */ + if (hol->num_entries > 0) + { + if (anything) + __argp_fmtstream_putc (fs, '\n'); + hol_help (hol, state, fs); + anything = 1; + } + } + + if (flags & ARGP_HELP_POST_DOC) + /* Print any documentation strings at the end. */ + anything |= argp_doc (argp, state, 1, anything, 0, fs); + + if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address) + { + if (anything) + __argp_fmtstream_putc (fs, '\n'); + __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, + "Report bugs to %s.\n"), + argp_program_bug_address); + anything = 1; + } + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __funlockfile (stream); +#endif + + if (hol) + hol_free (hol); + + __argp_fmtstream_free (fs); +} + +/* Output a usage message for ARGP to STREAM. FLAGS are from the set + ARGP_HELP_*. NAME is what to use wherever a "program name" is needed. */ +void __argp_help (const struct argp *argp, FILE *stream, + unsigned flags, char *name) +{ + struct argp_state state; + memset (&state, 0, sizeof state); + state.root_argp = argp; + _help (argp, &state, stream, flags, name); +} +#ifdef weak_alias +weak_alias (__argp_help, argp_help) +#endif + +#if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME) +char * +__argp_short_program_name (void) +{ +# if HAVE_DECL_PROGRAM_INVOCATION_NAME + return __argp_base_name (program_invocation_name); +# else + /* FIXME: What now? Miles suggests that it is better to use NULL, + but currently the value is passed on directly to fputs_unlocked, + so that requires more changes. */ +# if __GNUC__ +# warning No reasonable value to return +# endif /* __GNUC__ */ + return ""; +# endif +} +#endif + +/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are + from the set ARGP_HELP_*. */ +void +__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags) +{ + if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream) + { + if (state && (state->flags & ARGP_LONG_ONLY)) + flags |= ARGP_HELP_LONG_ONLY; + + _help (state ? state->root_argp : 0, state, stream, flags, + state ? state->name : __argp_short_program_name ()); + + if (!state || ! (state->flags & ARGP_NO_EXIT)) + { + if (flags & ARGP_HELP_EXIT_ERR) + exit (argp_err_exit_status); + if (flags & ARGP_HELP_EXIT_OK) + exit (0); + } + } +} +#ifdef weak_alias +weak_alias (__argp_state_help, argp_state_help) +#endif + +/* If appropriate, print the printf string FMT and following args, preceded + by the program name and ':', to stderr, and followed by a "Try ... --help" + message, then exit (1). */ +void +__argp_error (const struct argp_state *state, const char *fmt, ...) +{ + if (!state || !(state->flags & ARGP_NO_ERRS)) + { + FILE *stream = state ? state->err_stream : stderr; + + if (stream) + { + va_list ap; + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __flockfile (stream); +#endif + + va_start (ap, fmt); + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + { + char *buf; + + if (__asprintf (&buf, fmt, ap) < 0) + buf = NULL; + + __fwprintf (stream, L"%s: %s\n", + state ? state->name : __argp_short_program_name (), + buf); + + free (buf); + } + else +#endif + { + fputs_unlocked (state + ? state->name : __argp_short_program_name (), + stream); + putc_unlocked (':', stream); + putc_unlocked (' ', stream); + + vfprintf (stream, fmt, ap); + + putc_unlocked ('\n', stream); + } + + __argp_state_help (state, stream, ARGP_HELP_STD_ERR); + + va_end (ap); + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __funlockfile (stream); +#endif + } + } +} +#ifdef weak_alias +weak_alias (__argp_error, argp_error) +#endif + +/* Similar to the standard gnu error-reporting function error(), but will + respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print + to STATE->err_stream. This is useful for argument parsing code that is + shared between program startup (when exiting is desired) and runtime + option parsing (when typically an error code is returned instead). The + difference between this function and argp_error is that the latter is for + *parsing errors*, and the former is for other problems that occur during + parsing but don't reflect a (syntactic) problem with the input. */ +void +__argp_failure (const struct argp_state *state, int status, int errnum, + const char *fmt, ...) +{ + if (!state || !(state->flags & ARGP_NO_ERRS)) + { + FILE *stream = state ? state->err_stream : stderr; + + if (stream) + { +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __flockfile (stream); +#endif + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + __fwprintf (stream, L"%s", + state ? state->name : __argp_short_program_name ()); + else +#endif + fputs_unlocked (state + ? state->name : __argp_short_program_name (), + stream); + + if (fmt) + { + va_list ap; + + va_start (ap, fmt); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + { + char *buf; + + if (__asprintf (&buf, fmt, ap) < 0) + buf = NULL; + + __fwprintf (stream, L": %s", buf); + + free (buf); + } + else +#endif + { + putc_unlocked (':', stream); + putc_unlocked (' ', stream); + + vfprintf (stream, fmt, ap); + } + + va_end (ap); + } + + if (errnum) + { + char buf[200]; + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + __fwprintf (stream, L": %s", + __strerror_r (errnum, buf, sizeof (buf))); + else +#endif + { + char const *s = NULL; + putc_unlocked (':', stream); + putc_unlocked (' ', stream); +#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P && !defined strerror_r) + s = __strerror_r (errnum, buf, sizeof buf); +#elif HAVE_DECL_STRERROR_R + if (__strerror_r (errnum, buf, sizeof buf) == 0) + s = buf; +#endif +#if !_LIBC + if (! s && ! (s = strerror (errnum))) + s = dgettext (state->root_argp->argp_domain, + "Unknown system error"); +#endif + fputs (s, stream); + } + } + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + putwc_unlocked (L'\n', stream); + else +#endif + putc_unlocked ('\n', stream); + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __funlockfile (stream); +#endif + + if (status && (!state || !(state->flags & ARGP_NO_EXIT))) + exit (status); + } + } +} +#ifdef weak_alias +weak_alias (__argp_failure, argp_failure) +#endif diff --git a/gnu/argp-namefrob.h b/gnu/argp-namefrob.h new file mode 100644 index 00000000..8bb30a8d --- /dev/null +++ b/gnu/argp-namefrob.h @@ -0,0 +1,159 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Name frobnication for compiling argp outside of glibc + Copyright (C) 1997, 2003, 2007, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +#if !_LIBC +/* This code is written for inclusion in gnu-libc, and uses names in the + namespace reserved for libc. If we're not compiling in libc, define those + names to be the normal ones instead. */ + +/* argp-parse functions */ +#undef __argp_parse +#define __argp_parse argp_parse +#undef __option_is_end +#define __option_is_end _option_is_end +#undef __option_is_short +#define __option_is_short _option_is_short +#undef __argp_input +#define __argp_input _argp_input + +/* argp-help functions */ +#undef __argp_help +#define __argp_help argp_help +#undef __argp_error +#define __argp_error argp_error +#undef __argp_failure +#define __argp_failure argp_failure +#undef __argp_state_help +#define __argp_state_help argp_state_help +#undef __argp_usage +#define __argp_usage argp_usage + +/* argp-fmtstream functions */ +#undef __argp_make_fmtstream +#define __argp_make_fmtstream argp_make_fmtstream +#undef __argp_fmtstream_free +#define __argp_fmtstream_free argp_fmtstream_free +#undef __argp_fmtstream_putc +#define __argp_fmtstream_putc argp_fmtstream_putc +#undef __argp_fmtstream_puts +#define __argp_fmtstream_puts argp_fmtstream_puts +#undef __argp_fmtstream_write +#define __argp_fmtstream_write argp_fmtstream_write +#undef __argp_fmtstream_printf +#define __argp_fmtstream_printf argp_fmtstream_printf +#undef __argp_fmtstream_set_lmargin +#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin +#undef __argp_fmtstream_set_rmargin +#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin +#undef __argp_fmtstream_set_wmargin +#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin +#undef __argp_fmtstream_point +#define __argp_fmtstream_point argp_fmtstream_point +#undef __argp_fmtstream_update +#define __argp_fmtstream_update _argp_fmtstream_update +#undef __argp_fmtstream_ensure +#define __argp_fmtstream_ensure _argp_fmtstream_ensure +#undef __argp_fmtstream_lmargin +#define __argp_fmtstream_lmargin argp_fmtstream_lmargin +#undef __argp_fmtstream_rmargin +#define __argp_fmtstream_rmargin argp_fmtstream_rmargin +#undef __argp_fmtstream_wmargin +#define __argp_fmtstream_wmargin argp_fmtstream_wmargin + +/* normal libc functions we call */ +#undef __flockfile +#define __flockfile flockfile +#undef __funlockfile +#define __funlockfile funlockfile +#undef __mempcpy +#define __mempcpy mempcpy +#undef __sleep +#define __sleep sleep +#undef __strcasecmp +#define __strcasecmp strcasecmp +#undef __strchrnul +#define __strchrnul strchrnul +#undef __strerror_r +#define __strerror_r strerror_r +#undef __strndup +#define __strndup strndup +#undef __vsnprintf +#define __vsnprintf vsnprintf + +#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED +# define clearerr_unlocked(x) clearerr (x) +#endif +#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED +# define feof_unlocked(x) feof (x) +#endif +#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED +# define ferror_unlocked(x) ferror (x) +#endif +#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED +# define fflush_unlocked(x) fflush (x) +#endif +#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED +# define fgets_unlocked(x,y,z) fgets (x,y,z) +#endif +#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED +# define fputc_unlocked(x,y) fputc (x,y) +#endif +#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED +# define fputs_unlocked(x,y) fputs (x,y) +#endif +#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED +# define fread_unlocked(w,x,y,z) fread (w,x,y,z) +#endif +#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED +# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) +#endif +#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED +# define getc_unlocked(x) getc (x) +#endif +#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED +# define getchar_unlocked() getchar () +#endif +#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED +# define putc_unlocked(x,y) putc (x,y) +#endif +#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED +# define putchar_unlocked(x) putchar (x) +#endif + +#endif /* !_LIBC */ + +#ifndef __set_errno +# define __set_errno(e) (errno = (e)) +#endif + +#if defined GNULIB_ARGP_DISABLE_DIRNAME +# define __argp_base_name(arg) arg +#elif defined GNULIB_ARGP_EXTERN_BASENAME +extern char *__argp_base_name (const char *arg); +#else +# include "dirname.h" +# define __argp_base_name last_component +#endif + +#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME +# define __argp_short_program_name() (program_invocation_short_name) +#else +extern char *__argp_short_program_name (void); +#endif diff --git a/gnu/argp-parse.c b/gnu/argp-parse.c new file mode 100644 index 00000000..5f8a1f42 --- /dev/null +++ b/gnu/argp-parse.c @@ -0,0 +1,955 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Hierarchial argument parsing, layered over getopt + Copyright (C) 1995-2000, 2002-2004, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <alloca.h> +#include <stdalign.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <getopt.h> +#include <getopt_int.h> + +#ifdef _LIBC +# include <libintl.h> +# undef dgettext +# define dgettext(domain, msgid) \ + INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) +#else +# include "gettext.h" +#endif +#define N_(msgid) msgid + +#include "argp.h" +#include "argp-namefrob.h" + +#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d)) + +/* Getopt return values. */ +#define KEY_END (-1) /* The end of the options. */ +#define KEY_ARG 1 /* A non-option argument. */ +#define KEY_ERR '?' /* An error parsing the options. */ + +/* The meta-argument used to prevent any further arguments being interpreted + as options. */ +#define QUOTE "--" + +/* The number of bits we steal in a long-option value for our own use. */ +#define GROUP_BITS CHAR_BIT + +/* The number of bits available for the user value. */ +#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS) +#define USER_MASK ((1 << USER_BITS) - 1) + +/* EZ alias for ARGP_ERR_UNKNOWN. */ +#define EBADKEY ARGP_ERR_UNKNOWN + +/* Default options. */ + +/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep + for one second intervals, decrementing _ARGP_HANG until it's zero. Thus + you can force the program to continue by attaching a debugger and setting + it to 0 yourself. */ +static volatile int _argp_hang; + +#define OPT_PROGNAME -2 +#define OPT_USAGE -3 +#define OPT_HANG -4 + +static const struct argp_option argp_default_options[] = +{ + {"help", '?', 0, 0, N_("give this help list"), -1}, + {"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0}, + {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0}, + {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN, + N_("hang for SECS seconds (default 3600)"), 0}, + {NULL, 0, 0, 0, NULL, 0} +}; + +static error_t +argp_default_parser (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case '?': + __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP); + break; + case OPT_USAGE: + __argp_state_help (state, state->out_stream, + ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); + break; + + case OPT_PROGNAME: /* Set the program name. */ +#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME + program_invocation_name = arg; +#endif + /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka + __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined + to be that, so we have to be a bit careful here.] */ + + /* Update what we use for messages. */ + state->name = __argp_base_name (arg); + +#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME + program_invocation_short_name = state->name; +#endif + + if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) + == ARGP_PARSE_ARGV0) + /* Update what getopt uses too. */ + state->argv[0] = arg; + + break; + + case OPT_HANG: + _argp_hang = atoi (arg ? arg : "3600"); + while (_argp_hang-- > 0) + __sleep (1); + break; + + default: + return EBADKEY; + } + return 0; +} + +static const struct argp argp_default_argp = + {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"}; + + +static const struct argp_option argp_version_options[] = +{ + {"version", 'V', 0, 0, N_("print program version"), -1}, + {NULL, 0, 0, 0, NULL, 0} +}; + +static error_t +argp_version_parser (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'V': + if (argp_program_version_hook) + (*argp_program_version_hook) (state->out_stream, state); + else if (argp_program_version) + fprintf (state->out_stream, "%s\n", argp_program_version); + else + __argp_error (state, "%s", + dgettext (state->root_argp->argp_domain, + "(PROGRAM ERROR) No version known!?")); + if (! (state->flags & ARGP_NO_EXIT)) + exit (0); + break; + default: + return EBADKEY; + } + return 0; +} + +static const struct argp argp_version_argp = + {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"}; + +/* Returns the offset into the getopt long options array LONG_OPTIONS of a + long option with called NAME, or -1 if none is found. Passing NULL as + NAME will return the number of options. */ +static int +find_long_option (struct option *long_options, const char *name) +{ + struct option *l = long_options; + while (l->name != NULL) + if (name != NULL && strcmp (l->name, name) == 0) + return l - long_options; + else + l++; + if (name == NULL) + return l - long_options; + else + return -1; +} + + +/* The state of a "group" during parsing. Each group corresponds to a + particular argp structure from the tree of such descending from the top + level argp passed to argp_parse. */ +struct group +{ + /* This group's parsing function. */ + argp_parser_t parser; + + /* Which argp this group is from. */ + const struct argp *argp; + + /* Points to the point in SHORT_OPTS corresponding to the end of the short + options for this group. We use it to determine from which group a + particular short options is from. */ + char *short_end; + + /* The number of non-option args sucessfully handled by this parser. */ + unsigned args_processed; + + /* This group's parser's parent's group. */ + struct group *parent; + unsigned parent_index; /* And the our position in the parent. */ + + /* These fields are swapped into and out of the state structure when + calling this group's parser. */ + void *input, **child_inputs; + void *hook; +}; + +/* Call GROUP's parser with KEY and ARG, swapping any group-specific info + from STATE before calling, and back into state afterwards. If GROUP has + no parser, EBADKEY is returned. */ +static error_t +group_parse (struct group *group, struct argp_state *state, int key, char *arg) +{ + if (group->parser) + { + error_t err; + state->hook = group->hook; + state->input = group->input; + state->child_inputs = group->child_inputs; + state->arg_num = group->args_processed; + err = (*group->parser)(key, arg, state); + group->hook = state->hook; + return err; + } + else + return EBADKEY; +} + +struct parser +{ + const struct argp *argp; + + /* SHORT_OPTS is the getopt short options string for the union of all the + groups of options. */ + char *short_opts; + /* LONG_OPTS is the array of getop long option structures for the union of + all the groups of options. */ + struct option *long_opts; + /* OPT_DATA is the getopt data used for the re-entrant getopt. */ + struct _getopt_data opt_data; + + /* States of the various parsing groups. */ + struct group *groups; + /* The end of the GROUPS array. */ + struct group *egroup; + /* A vector containing storage for the CHILD_INPUTS field in all groups. */ + void **child_inputs; + + /* True if we think using getopt is still useful; if false, then + remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is + cleared whenever getopt returns KEY_END, but may be set again if the user + moves the next argument pointer backwards. */ + int try_getopt; + + /* State block supplied to parsing routines. */ + struct argp_state state; + + /* Memory used by this parser. */ + void *storage; +}; + +/* The next usable entries in the various parser tables being filled in by + convert_options. */ +struct parser_convert_state +{ + struct parser *parser; + char *short_end; + struct option *long_end; + void **child_inputs_end; +}; + +/* Converts all options in ARGP (which is put in GROUP) and ancestors + into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and + CVT->LONG_END are the points at which new options are added. Returns the + next unused group entry. CVT holds state used during the conversion. */ +static struct group * +convert_options (const struct argp *argp, + struct group *parent, unsigned parent_index, + struct group *group, struct parser_convert_state *cvt) +{ + /* REAL is the most recent non-alias value of OPT. */ + const struct argp_option *real = argp->options; + const struct argp_child *children = argp->children; + + if (real || argp->parser) + { + const struct argp_option *opt; + + if (real) + for (opt = real; !__option_is_end (opt); opt++) + { + if (! (opt->flags & OPTION_ALIAS)) + /* OPT isn't an alias, so we can use values from it. */ + real = opt; + + if (! (real->flags & OPTION_DOC)) + /* A real option (not just documentation). */ + { + if (__option_is_short (opt)) + /* OPT can be used as a short option. */ + { + *cvt->short_end++ = opt->key; + if (real->arg) + { + *cvt->short_end++ = ':'; + if (real->flags & OPTION_ARG_OPTIONAL) + *cvt->short_end++ = ':'; + } + *cvt->short_end = '\0'; /* keep 0 terminated */ + } + + if (opt->name + && find_long_option (cvt->parser->long_opts, opt->name) < 0) + /* OPT can be used as a long option. */ + { + cvt->long_end->name = opt->name; + cvt->long_end->has_arg = + (real->arg + ? (real->flags & OPTION_ARG_OPTIONAL + ? optional_argument + : required_argument) + : no_argument); + cvt->long_end->flag = 0; + /* we add a disambiguating code to all the user's + values (which is removed before we actually call + the function to parse the value); this means that + the user loses use of the high 8 bits in all his + values (the sign of the lower bits is preserved + however)... */ + cvt->long_end->val = + ((opt->key ? opt->key : real->key) & USER_MASK) + + (((group - cvt->parser->groups) + 1) << USER_BITS); + + /* Keep the LONG_OPTS list terminated. */ + (++cvt->long_end)->name = NULL; + } + } + } + + group->parser = argp->parser; + group->argp = argp; + group->short_end = cvt->short_end; + group->args_processed = 0; + group->parent = parent; + group->parent_index = parent_index; + group->input = 0; + group->hook = 0; + group->child_inputs = 0; + + if (children) + /* Assign GROUP's CHILD_INPUTS field some space from + CVT->child_inputs_end.*/ + { + unsigned num_children = 0; + while (children[num_children].argp) + num_children++; + group->child_inputs = cvt->child_inputs_end; + cvt->child_inputs_end += num_children; + } + + parent = group++; + } + else + parent = 0; + + if (children) + { + unsigned index = 0; + while (children->argp) + group = + convert_options (children++->argp, parent, index++, group, cvt); + } + + return group; +} + +/* Find the merged set of getopt options, with keys appropiately prefixed. */ +static void +parser_convert (struct parser *parser, const struct argp *argp, int flags) +{ + struct parser_convert_state cvt; + + cvt.parser = parser; + cvt.short_end = parser->short_opts; + cvt.long_end = parser->long_opts; + cvt.child_inputs_end = parser->child_inputs; + + if (flags & ARGP_IN_ORDER) + *cvt.short_end++ = '-'; + else if (flags & ARGP_NO_ARGS) + *cvt.short_end++ = '+'; + *cvt.short_end = '\0'; + + cvt.long_end->name = NULL; + + parser->argp = argp; + + if (argp) + parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt); + else + parser->egroup = parser->groups; /* No parsers at all! */ +} + +/* Lengths of various parser fields which we will allocated. */ +struct parser_sizes +{ + size_t short_len; /* Getopt short options string. */ + size_t long_len; /* Getopt long options vector. */ + size_t num_groups; /* Group structures we allocate. */ + size_t num_child_inputs; /* Child input slots. */ +}; + +/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of + argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by + the maximum lengths of the resulting merged getopt short options string and + long-options array, respectively. */ +static void +calc_sizes (const struct argp *argp, struct parser_sizes *szs) +{ + const struct argp_child *child = argp->children; + const struct argp_option *opt = argp->options; + + if (opt || argp->parser) + { + szs->num_groups++; + if (opt) + { + int num_opts = 0; + while (!__option_is_end (opt++)) + num_opts++; + szs->short_len += num_opts * 3; /* opt + up to 2 ':'s */ + szs->long_len += num_opts; + } + } + + if (child) + while (child->argp) + { + calc_sizes ((child++)->argp, szs); + szs->num_child_inputs++; + } +} + +/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */ +static error_t +parser_init (struct parser *parser, const struct argp *argp, + int argc, char **argv, int flags, void *input) +{ + error_t err = 0; + struct group *group; + struct parser_sizes szs; + struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER; + char *storage; + size_t glen, gsum; + size_t clen, csum; + size_t llen, lsum; + size_t slen, ssum; + + szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1; + szs.long_len = 0; + szs.num_groups = 0; + szs.num_child_inputs = 0; + + if (argp) + calc_sizes (argp, &szs); + + /* Lengths of the various bits of storage used by PARSER. */ + glen = (szs.num_groups + 1) * sizeof (struct group); + clen = szs.num_child_inputs * sizeof (void *); + llen = (szs.long_len + 1) * sizeof (struct option); + slen = szs.short_len + 1; + + /* Sums of previous lengths, properly aligned. There's no need to + align gsum, since struct group is aligned at least as strictly as + void * (since it contains a void * member). And there's no need + to align lsum, since struct option is aligned at least as + strictly as char. */ + gsum = glen; + csum = alignto (gsum + clen, alignof (struct option)); + lsum = csum + llen; + ssum = lsum + slen; + + parser->storage = malloc (ssum); + if (! parser->storage) + return ENOMEM; + + storage = parser->storage; + parser->groups = parser->storage; + parser->child_inputs = (void **) (storage + gsum); + parser->long_opts = (struct option *) (storage + csum); + parser->short_opts = storage + lsum; + parser->opt_data = opt_data; + + memset (parser->child_inputs, 0, clen); + parser_convert (parser, argp, flags); + + memset (&parser->state, 0, sizeof (struct argp_state)); + parser->state.root_argp = parser->argp; + parser->state.argc = argc; + parser->state.argv = argv; + parser->state.flags = flags; + parser->state.err_stream = stderr; + parser->state.out_stream = stdout; + parser->state.next = 0; /* Tell getopt to initialize. */ + parser->state.pstate = parser; + + parser->try_getopt = 1; + + /* Call each parser for the first time, giving it a chance to propagate + values to child parsers. */ + if (parser->groups < parser->egroup) + parser->groups->input = input; + for (group = parser->groups; + group < parser->egroup && (!err || err == EBADKEY); + group++) + { + if (group->parent) + /* If a child parser, get the initial input value from the parent. */ + group->input = group->parent->child_inputs[group->parent_index]; + + if (!group->parser + && group->argp->children && group->argp->children->argp) + /* For the special case where no parsing function is supplied for an + argp, propagate its input to its first child, if any (this just + makes very simple wrapper argps more convenient). */ + group->child_inputs[0] = group->input; + + err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); + } + if (err == EBADKEY) + err = 0; /* Some parser didn't understand. */ + + if (err) + return err; + + if (parser->state.flags & ARGP_NO_ERRS) + { + parser->opt_data.opterr = 0; + if (parser->state.flags & ARGP_PARSE_ARGV0) + /* getopt always skips ARGV[0], so we have to fake it out. As long + as OPTERR is 0, then it shouldn't actually try to access it. */ + parser->state.argv--, parser->state.argc++; + } + else + parser->opt_data.opterr = 1; /* Print error messages. */ + + if (parser->state.argv == argv && argv[0]) + /* There's an argv[0]; use it for messages. */ + parser->state.name = __argp_base_name (argv[0]); + else + parser->state.name = __argp_short_program_name (); + + return 0; +} + +/* Free any storage consumed by PARSER (but not PARSER itself). */ +static error_t +parser_finalize (struct parser *parser, + error_t err, int arg_ebadkey, int *end_index) +{ + struct group *group; + + if (err == EBADKEY && arg_ebadkey) + /* Suppress errors generated by unparsed arguments. */ + err = 0; + + if (! err) + { + if (parser->state.next == parser->state.argc) + /* We successfully parsed all arguments! Call all the parsers again, + just a few more times... */ + { + for (group = parser->groups; + group < parser->egroup && (!err || err==EBADKEY); + group++) + if (group->args_processed == 0) + err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); + for (group = parser->egroup - 1; + group >= parser->groups && (!err || err==EBADKEY); + group--) + err = group_parse (group, &parser->state, ARGP_KEY_END, 0); + + if (err == EBADKEY) + err = 0; /* Some parser didn't understand. */ + + /* Tell the user that all arguments are parsed. */ + if (end_index) + *end_index = parser->state.next; + } + else if (end_index) + /* Return any remaining arguments to the user. */ + *end_index = parser->state.next; + else + /* No way to return the remaining arguments, they must be bogus. */ + { + if (!(parser->state.flags & ARGP_NO_ERRS) + && parser->state.err_stream) + fprintf (parser->state.err_stream, + dgettext (parser->argp->argp_domain, + "%s: Too many arguments\n"), + parser->state.name); + err = EBADKEY; + } + } + + /* Okay, we're all done, with either an error or success; call the parsers + to indicate which one. */ + + if (err) + { + /* Maybe print an error message. */ + if (err == EBADKEY) + /* An appropriate message describing what the error was should have + been printed earlier. */ + __argp_state_help (&parser->state, parser->state.err_stream, + ARGP_HELP_STD_ERR); + + /* Since we didn't exit, give each parser an error indication. */ + for (group = parser->groups; group < parser->egroup; group++) + group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); + } + else + /* Notify parsers of success, and propagate back values from parsers. */ + { + /* We pass over the groups in reverse order so that child groups are + given a chance to do there processing before passing back a value to + the parent. */ + for (group = parser->egroup - 1 + ; group >= parser->groups && (!err || err == EBADKEY) + ; group--) + err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); + if (err == EBADKEY) + err = 0; /* Some parser didn't understand. */ + } + + /* Call parsers once more, to do any final cleanup. Errors are ignored. */ + for (group = parser->egroup - 1; group >= parser->groups; group--) + group_parse (group, &parser->state, ARGP_KEY_FINI, 0); + + if (err == EBADKEY) + err = EINVAL; + + free (parser->storage); + + return err; +} + +/* Call the user parsers to parse the non-option argument VAL, at the current + position, returning any error. The state NEXT pointer is assumed to have + been adjusted (by getopt) to point after this argument; this function will + adjust it correctly to reflect however many args actually end up being + consumed. */ +static error_t +parser_parse_arg (struct parser *parser, char *val) +{ + /* Save the starting value of NEXT, first adjusting it so that the arg + we're parsing is again the front of the arg vector. */ + int index = --parser->state.next; + error_t err = EBADKEY; + struct group *group; + int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ + + /* Try to parse the argument in each parser. */ + for (group = parser->groups + ; group < parser->egroup && err == EBADKEY + ; group++) + { + parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ + key = ARGP_KEY_ARG; + err = group_parse (group, &parser->state, key, val); + + if (err == EBADKEY) + /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ + { + parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ + key = ARGP_KEY_ARGS; + err = group_parse (group, &parser->state, key, 0); + } + } + + if (! err) + { + if (key == ARGP_KEY_ARGS) + /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't + changed by the user, *all* arguments should be considered + consumed. */ + parser->state.next = parser->state.argc; + + if (parser->state.next > index) + /* Remember that we successfully processed a non-option + argument -- but only if the user hasn't gotten tricky and set + the clock back. */ + (--group)->args_processed += (parser->state.next - index); + else + /* The user wants to reparse some args, give getopt another try. */ + parser->try_getopt = 1; + } + + return err; +} + +/* Call the user parsers to parse the option OPT, with argument VAL, at the + current position, returning any error. */ +static error_t +parser_parse_opt (struct parser *parser, int opt, char *val) +{ + /* The group key encoded in the high bits; 0 for short opts or + group_number + 1 for long opts. */ + int group_key = opt >> USER_BITS; + error_t err = EBADKEY; + + if (group_key == 0) + /* A short option. By comparing OPT's position in SHORT_OPTS to the + various starting positions in each group's SHORT_END field, we can + determine which group OPT came from. */ + { + struct group *group; + char *short_index = strchr (parser->short_opts, opt); + + if (short_index) + for (group = parser->groups; group < parser->egroup; group++) + if (group->short_end > short_index) + { + err = group_parse (group, &parser->state, opt, + parser->opt_data.optarg); + break; + } + } + else + /* A long option. We use shifts instead of masking for extracting + the user value in order to preserve the sign. */ + err = + group_parse (&parser->groups[group_key - 1], &parser->state, + (opt << GROUP_BITS) >> GROUP_BITS, + parser->opt_data.optarg); + + if (err == EBADKEY) + /* At least currently, an option not recognized is an error in the + parser, because we pre-compute which parser is supposed to deal + with each option. */ + { + static const char bad_key_err[] = + N_("(PROGRAM ERROR) Option should have been recognized!?"); + if (group_key == 0) + __argp_error (&parser->state, "-%c: %s", opt, + dgettext (parser->argp->argp_domain, bad_key_err)); + else + { + struct option *long_opt = parser->long_opts; + while (long_opt->val != opt && long_opt->name) + long_opt++; + __argp_error (&parser->state, "--%s: %s", + long_opt->name ? long_opt->name : "???", + dgettext (parser->argp->argp_domain, bad_key_err)); + } + } + + return err; +} + +/* Parse the next argument in PARSER (as indicated by PARSER->state.next). + Any error from the parsers is returned, and *ARGP_EBADKEY indicates + whether a value of EBADKEY is due to an unrecognized argument (which is + generally not fatal). */ +static error_t +parser_parse_next (struct parser *parser, int *arg_ebadkey) +{ + int opt; + error_t err = 0; + + if (parser->state.quoted && parser->state.next < parser->state.quoted) + /* The next argument pointer has been moved to before the quoted + region, so pretend we never saw the quoting "--", and give getopt + another chance. If the user hasn't removed it, getopt will just + process it again. */ + parser->state.quoted = 0; + + if (parser->try_getopt && !parser->state.quoted) + /* Give getopt a chance to parse this. */ + { + /* Put it back in OPTIND for getopt. */ + parser->opt_data.optind = parser->state.next; + /* Distinguish KEY_ERR from a real option. */ + parser->opt_data.optopt = KEY_END; + if (parser->state.flags & ARGP_LONG_ONLY) + opt = _getopt_long_only_r (parser->state.argc, parser->state.argv, + parser->short_opts, parser->long_opts, 0, + &parser->opt_data); + else + opt = _getopt_long_r (parser->state.argc, parser->state.argv, + parser->short_opts, parser->long_opts, 0, + &parser->opt_data); + /* And see what getopt did. */ + parser->state.next = parser->opt_data.optind; + + if (opt == KEY_END) + /* Getopt says there are no more options, so stop using + getopt; we'll continue if necessary on our own. */ + { + parser->try_getopt = 0; + if (parser->state.next > 1 + && strcmp (parser->state.argv[parser->state.next - 1], QUOTE) + == 0) + /* Not only is this the end of the options, but it's a + "quoted" region, which may have args that *look* like + options, so we definitely shouldn't try to use getopt past + here, whatever happens. */ + parser->state.quoted = parser->state.next; + } + else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END) + /* KEY_ERR can have the same value as a valid user short + option, but in the case of a real error, getopt sets OPTOPT + to the offending character, which can never be KEY_END. */ + { + *arg_ebadkey = 0; + return EBADKEY; + } + } + else + opt = KEY_END; + + if (opt == KEY_END) + { + /* We're past what getopt considers the options. */ + if (parser->state.next >= parser->state.argc + || (parser->state.flags & ARGP_NO_ARGS)) + /* Indicate that we're done. */ + { + *arg_ebadkey = 1; + return EBADKEY; + } + else + /* A non-option arg; simulate what getopt might have done. */ + { + opt = KEY_ARG; + parser->opt_data.optarg = parser->state.argv[parser->state.next++]; + } + } + + if (opt == KEY_ARG) + /* A non-option argument; try each parser in turn. */ + err = parser_parse_arg (parser, parser->opt_data.optarg); + else + err = parser_parse_opt (parser, opt, parser->opt_data.optarg); + + if (err == EBADKEY) + *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG); + + return err; +} + +/* Parse the options strings in ARGC & ARGV according to the argp in ARGP. + FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the + index in ARGV of the first unparsed option is returned in it. If an + unknown option is present, EINVAL is returned; if some parser routine + returned a non-zero value, it is returned; otherwise 0 is returned. */ +error_t +__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, + int *end_index, void *input) +{ + error_t err; + struct parser parser; + + /* If true, then err == EBADKEY is a result of a non-option argument failing + to be parsed (which in some cases isn't actually an error). */ + int arg_ebadkey = 0; + +#ifndef _LIBC + if (!(flags & ARGP_PARSE_ARGV0)) + { +#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME + if (!program_invocation_name) + program_invocation_name = argv[0]; +#endif +#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME + if (!program_invocation_short_name) + program_invocation_short_name = __argp_base_name (argv[0]); +#endif + } +#endif + + if (! (flags & ARGP_NO_HELP)) + /* Add our own options. */ + { + struct argp_child *child = alloca (4 * sizeof (struct argp_child)); + struct argp *top_argp = alloca (sizeof (struct argp)); + + /* TOP_ARGP has no options, it just serves to group the user & default + argps. */ + memset (top_argp, 0, sizeof (*top_argp)); + top_argp->children = child; + + memset (child, 0, 4 * sizeof (struct argp_child)); + + if (argp) + (child++)->argp = argp; + (child++)->argp = &argp_default_argp; + if (argp_program_version || argp_program_version_hook) + (child++)->argp = &argp_version_argp; + child->argp = 0; + + argp = top_argp; + } + + /* Construct a parser for these arguments. */ + err = parser_init (&parser, argp, argc, argv, flags, input); + + if (! err) + /* Parse! */ + { + while (! err) + err = parser_parse_next (&parser, &arg_ebadkey); + err = parser_finalize (&parser, err, arg_ebadkey, end_index); + } + + return err; +} +#ifdef weak_alias +weak_alias (__argp_parse, argp_parse) +#endif + +/* Return the input field for ARGP in the parser corresponding to STATE; used + by the help routines. */ +void * +__argp_input (const struct argp *argp, const struct argp_state *state) +{ + if (state) + { + struct group *group; + struct parser *parser = state->pstate; + + for (group = parser->groups; group < parser->egroup; group++) + if (group->argp == argp) + return group->input; + } + + return 0; +} +#ifdef weak_alias +weak_alias (__argp_input, _argp_input) +#endif diff --git a/gnu/argp-pin.c b/gnu/argp-pin.c new file mode 100644 index 00000000..83eee63d --- /dev/null +++ b/gnu/argp-pin.c @@ -0,0 +1,29 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Full and short program names for argp module + Copyright (C) 2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME +char *program_invocation_short_name = 0; +#endif +#ifndef HAVE_PROGRAM_INVOCATION_NAME +char *program_invocation_name = 0; +#endif + diff --git a/gnu/argp-pv.c b/gnu/argp-pv.c new file mode 100644 index 00000000..e4e899f5 --- /dev/null +++ b/gnu/argp-pv.c @@ -0,0 +1,36 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Default definition for ARGP_PROGRAM_VERSION. + Copyright (C) 1996-1997, 1999, 2006, 2009-2012 Free Software Foundation, + Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +/* If set by the user program to a non-zero value, then a default option + --version is added (unless the ARGP_NO_HELP flag is used), which will + print this string followed by a newline and exit (unless the + ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ +const char *argp_program_version +/* This variable should be zero-initialized. On most systems, putting it into + BSS is sufficient. Not so on MacOS X 10.3 and 10.4, see + <http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00329.html> + <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00096.html>. */ +#if defined __ELF__ + /* On ELF systems, variables in BSS behave well. */ +#else + = (const char *) 0 +#endif + ; diff --git a/gnu/argp-pvh.c b/gnu/argp-pvh.c new file mode 100644 index 00000000..67f8f7af --- /dev/null +++ b/gnu/argp-pvh.c @@ -0,0 +1,33 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Default definition for ARGP_PROGRAM_VERSION_HOOK. + Copyright (C) 1996-1997, 1999, 2004, 2009-2012 Free Software Foundation, + Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "argp.h" + +/* If set by the user program to a non-zero value, then a default option + --version is added (unless the ARGP_NO_HELP flag is used), which calls + this function with a stream to print the version to and a pointer to the + current parsing state, and then exits (unless the ARGP_NO_EXIT flag is + used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ +void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL; diff --git a/gnu/argp-version-etc.c b/gnu/argp-version-etc.c new file mode 100644 index 00000000..117fa077 --- /dev/null +++ b/gnu/argp-version-etc.c @@ -0,0 +1,40 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Version hook for Argp. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> +#include <version-etc.h> +#include <argp.h> +#include <argp-version-etc.h> + +static const char *program_canonical_name; +static const char * const *program_authors; + +static void +version_etc_hook (FILE *stream, struct argp_state *state) +{ + version_etc_ar (stream, program_canonical_name, PACKAGE_NAME, VERSION, + program_authors); +} + +void +argp_version_setup (const char *name, const char * const *authors) +{ + argp_program_version_hook = version_etc_hook; + program_canonical_name = name; + program_authors = authors; +} diff --git a/gnu/argp-version-etc.h b/gnu/argp-version-etc.h new file mode 100644 index 00000000..450f58c0 --- /dev/null +++ b/gnu/argp-version-etc.h @@ -0,0 +1,42 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Version hook for Argp. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _ARGP_VERSION_ETC_H +#define _ARGP_VERSION_ETC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Setup standard display of the version information for the '--version' + option. NAME is the canonical program name, and AUTHORS is a NULL- + terminated array of author names. At least one author name must be + given. + + If NAME is NULL, the package name (as given by the PACKAGE macro) + is asumed to be the name of the program. + + This function is intended to be called before argp_parse(). +*/ +extern void argp_version_setup (const char *name, const char * const *authors); + +#ifdef __cplusplus +} +#endif + +#endif /* _ARGP_VERSION_ETC_H */ diff --git a/gnu/argp-xinl.c b/gnu/argp-xinl.c new file mode 100644 index 00000000..366f5582 --- /dev/null +++ b/gnu/argp-xinl.c @@ -0,0 +1,44 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Real definitions for extern inline functions in argp.h + Copyright (C) 1997-1998, 2004, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if defined _LIBC || defined HAVE_FEATURES_H +# include <features.h> +#endif + +#ifndef __USE_EXTERN_INLINES +# define __USE_EXTERN_INLINES 1 +#endif +#define ARGP_EI +#undef __OPTIMIZE__ +#define __OPTIMIZE__ 1 +#include "argp.h" + +/* Add weak aliases. */ +#if _LIBC - 0 && defined (weak_alias) + +weak_alias (__argp_usage, argp_usage) +weak_alias (__option_is_short, _option_is_short) +weak_alias (__option_is_end, _option_is_end) + +#endif diff --git a/gnu/argp.h b/gnu/argp.h new file mode 100644 index 00000000..bf80aa85 --- /dev/null +++ b/gnu/argp.h @@ -0,0 +1,647 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Hierarchial argument parsing, layered over getopt. + Copyright (C) 1995-1999, 2003-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader <miles@gnu.ai.mit.edu>. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (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 <http://www.gnu.org/licenses/>. */ + +#ifndef _ARGP_H +#define _ARGP_H + +#include <stdio.h> +#include <ctype.h> +#include <getopt.h> +#include <limits.h> + +#define __need_error_t +#include <errno.h> + +#ifndef __THROW +# define __THROW +#endif +#ifndef __NTH +# define __NTH(fct) fct __THROW +#endif + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ +#endif + +/* 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. */ +#ifndef __restrict +# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) +# if 199901L <= __STDC_VERSION__ +# define __restrict restrict +# else +# define __restrict +# endif +# endif +#endif + +#ifndef __error_t_defined +typedef int error_t; +# define __error_t_defined +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* A description of a particular option. A pointer to an array of + these is passed in the OPTIONS field of an argp structure. Each option + entry can correspond to one long option and/or one short option; more + names for the same option can be added by following an entry in an option + array with options having the OPTION_ALIAS flag set. */ +struct argp_option +{ + /* The long option name. For more than one name for the same option, you + can use following options with the OPTION_ALIAS flag set. */ + const char *name; + + /* What key is returned for this option. If > 0 and printable, then it's + also accepted as a short option. */ + int key; + + /* If non-NULL, this is the name of the argument associated with this + option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */ + const char *arg; + + /* OPTION_ flags. */ + int flags; + + /* The doc string for this option. If both NAME and KEY are 0, This string + will be printed outdented from the normal option column, making it + useful as a group header (it will be the first thing printed in its + group); in this usage, it's conventional to end the string with a ':'. + + Write the initial value as N_("TEXT") if you want xgettext to collect + it into a POT file. */ + const char *doc; + + /* The group this option is in. In a long help message, options are sorted + alphabetically within each group, and the groups presented in the order + 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with + if this field 0 will inherit the group number of the previous entry, or + zero if it's the first one, unless its a group header (NAME and KEY both + 0), in which case, the previous entry + 1 is the default. Automagic + options such as --help are put into group -1. */ + int group; +}; + +/* The argument associated with this option is optional. */ +#define OPTION_ARG_OPTIONAL 0x1 + +/* This option isn't displayed in any help messages. */ +#define OPTION_HIDDEN 0x2 + +/* This option is an alias for the closest previous non-alias option. This + means that it will be displayed in the same help entry, and will inherit + fields other than NAME and KEY from the aliased option. */ +#define OPTION_ALIAS 0x4 + +/* This option isn't actually an option (and so should be ignored by the + actual option parser), but rather an arbitrary piece of documentation that + should be displayed in much the same manner as the options. If this flag + is set, then the option NAME field is displayed unmodified (e.g., no '--' + prefix is added) at the left-margin (where a *short* option would normally + be displayed), and the documentation string in the normal place. The NAME + field will be translated using gettext, unless OPTION_NO_TRANS is set (see + below). For purposes of sorting, any leading whitespace and punctuation is + ignored, except that if the first non-whitespace character is not '-', this + entry is displayed after all options (and OPTION_DOC entries with a leading + '-') in the same group. */ +#define OPTION_DOC 0x8 + +/* This option shouldn't be included in "long" usage messages (but is still + included in help messages). This is mainly intended for options that are + completely documented in an argp's ARGS_DOC field, in which case including + the option in the generic usage list would be redundant. For instance, + if ARGS_DOC is "FOO BAR\n-x BLAH", and the '-x' option's purpose is to + distinguish these two cases, -x should probably be marked + OPTION_NO_USAGE. */ +#define OPTION_NO_USAGE 0x10 + +/* Valid only in conjunction with OPTION_DOC. This option disables translation + of option name. */ +#define OPTION_NO_TRANS 0x20 + + +struct argp; /* fwd declare this type */ +struct argp_state; /* " */ +struct argp_child; /* " */ + +/* The type of a pointer to an argp parsing function. */ +typedef error_t (*argp_parser_t) (int key, char *arg, + struct argp_state *state); + +/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such + returns will simply be ignored. For user keys, this error will be turned + into EINVAL (if the call to argp_parse is such that errors are propagated + back to the user instead of exiting); returning EINVAL itself would result + in an immediate stop to parsing in *all* cases. */ +#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */ + +/* Special values for the KEY argument to an argument parsing function. + ARGP_ERR_UNKNOWN should be returned if they aren't understood. + + The sequence of keys to a parsing function is either (where each + uppercased word should be prefixed by 'ARGP_KEY_' and opt is a user key): + + INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all + or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed + or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized + + The third case is where every parser returned ARGP_KEY_UNKNOWN for an + argument, in which case parsing stops at that argument (returning the + unparsed arguments to the caller of argp_parse if requested, or stopping + with an error message if not). + + If an error occurs (either detected by argp, or because the parsing + function returned an error value), then the parser is called with + ARGP_KEY_ERROR, and no further calls are made. */ + +/* This is not an option at all, but rather a command line argument. If a + parser receiving this key returns success, the fact is recorded, and the + ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the + argument, a parser function decrements the NEXT field of the state it's + passed, the option won't be considered processed; this is to allow you to + actually modify the argument (perhaps into an option), and have it + processed again. */ +#define ARGP_KEY_ARG 0 +/* There are remaining arguments not parsed by any parser, which may be found + starting at (STATE->argv + STATE->next). If success is returned, but + STATE->next left untouched, it's assumed that all arguments were consume, + otherwise, the parser should adjust STATE->next to reflect any arguments + consumed. */ +#define ARGP_KEY_ARGS 0x1000006 +/* There are no more command line arguments at all. */ +#define ARGP_KEY_END 0x1000001 +/* Because it's common to want to do some special processing if there aren't + any non-option args, user parsers are called with this key if they didn't + successfully process any non-option arguments. Called just before + ARGP_KEY_END (where more general validity checks on previously parsed + arguments can take place). */ +#define ARGP_KEY_NO_ARGS 0x1000002 +/* Passed in before any parsing is done. Afterwards, the values of each + element of the CHILD_INPUT field, if any, in the state structure is + copied to each child's state to be the initial value of the INPUT field. */ +#define ARGP_KEY_INIT 0x1000003 +/* Use after all other keys, including SUCCESS & END. */ +#define ARGP_KEY_FINI 0x1000007 +/* Passed in when parsing has successfully been completed (even if there are + still arguments remaining). */ +#define ARGP_KEY_SUCCESS 0x1000004 +/* Passed in if an error occurs. */ +#define ARGP_KEY_ERROR 0x1000005 + +/* An argp structure contains a set of options declarations, a function to + deal with parsing one, documentation string, a possible vector of child + argp's, and perhaps a function to filter help output. When actually + parsing options, getopt is called with the union of all the argp + structures chained together through their CHILD pointers, with conflicts + being resolved in favor of the first occurrence in the chain. */ +struct argp +{ + /* An array of argp_option structures, terminated by an entry with both + NAME and KEY having a value of 0. */ + const struct argp_option *options; + + /* What to do with an option from this structure. KEY is the key + associated with the option, and ARG is any associated argument (NULL if + none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be + returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then + parsing is stopped immediately, and that value is returned from + argp_parse(). For special (non-user-supplied) values of KEY, see the + ARGP_KEY_ definitions below. */ + argp_parser_t parser; + + /* A string describing what other arguments are wanted by this program. It + is only used by argp_usage to print the "Usage:" message. If it + contains newlines, the strings separated by them are considered + alternative usage patterns, and printed on separate lines (lines after + the first are prefix by " or: " instead of "Usage:"). */ + const char *args_doc; + + /* If non-NULL, a string containing extra text to be printed before and + after the options in a long help message (separated by a vertical tab + '\v' character). + Write the initial value as N_("BEFORE-TEXT") "\v" N_("AFTER-TEXT") if + you want xgettext to collect the two pieces of text into a POT file. */ + const char *doc; + + /* A vector of argp_children structures, terminated by a member with a 0 + argp field, pointing to child argps should be parsed with this one. Any + conflicts are resolved in favor of this argp, or early argps in the + CHILDREN list. This field is useful if you use libraries that supply + their own argp structure, which you want to use in conjunction with your + own. */ + const struct argp_child *children; + + /* If non-zero, this should be a function to filter the output of help + messages. KEY is either a key from an option, in which case TEXT is + that option's help text, or a special key from the ARGP_KEY_HELP_ + defines, below, describing which other help text TEXT is. The function + should return either TEXT, if it should be used as-is, a replacement + string, which should be malloced, and will be freed by argp, or NULL, + meaning "print nothing". The value for TEXT is *after* any translation + has been done, so if any of the replacement text also needs translation, + that should be done by the filter function. INPUT is either the input + supplied to argp_parse, or NULL, if argp_help was called directly. */ + char *(*help_filter) (int __key, const char *__text, void *__input); + + /* If non-zero the strings used in the argp library are translated using + the domain described by this string. Otherwise the currently installed + default domain is used. */ + const char *argp_domain; +}; + +/* Possible KEY arguments to a help filter function. */ +#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */ +#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */ +#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */ +#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation; + TEXT is NULL for this key. */ +/* Explanatory note emitted when duplicate option arguments have been + suppressed. */ +#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 +#define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */ + +/* When an argp has a non-zero CHILDREN field, it should point to a vector of + argp_child structures, each of which describes a subsidiary argp. */ +struct argp_child +{ + /* The child parser. */ + const struct argp *argp; + + /* Flags for this child. */ + int flags; + + /* If non-zero, an optional header to be printed in help output before the + child options. As a side-effect, a non-zero value forces the child + options to be grouped together; to achieve this effect without actually + printing a header string, use a value of "". */ + const char *header; + + /* Where to group the child options relative to the other ("consolidated") + options in the parent argp; the values are the same as the GROUP field + in argp_option structs, but all child-groupings follow parent options at + a particular group level. If both this field and HEADER are zero, then + they aren't grouped at all, but rather merged with the parent options + (merging the child's grouping levels with the parents). */ + int group; +}; + +/* Parsing state. This is provided to parsing functions called by argp, + which may examine and, as noted, modify fields. */ +struct argp_state +{ + /* The top level ARGP being parsed. */ + const struct argp *root_argp; + + /* The argument vector being parsed. May be modified. */ + int argc; + char **argv; + + /* The index in ARGV of the next arg that to be parsed. May be modified. */ + int next; + + /* The flags supplied to argp_parse. May be modified. */ + unsigned flags; + + /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the + number of the current arg, starting at zero, and incremented after each + such call returns. At all other times, this is the number of such + arguments that have been processed. */ + unsigned arg_num; + + /* If non-zero, the index in ARGV of the first argument following a special + '--' argument (which prevents anything following being interpreted as an + option). Only set once argument parsing has proceeded past this point. */ + int quoted; + + /* An arbitrary pointer passed in from the user. */ + void *input; + /* Values to pass to child parsers. This vector will be the same length as + the number of children for the current parser. */ + void **child_inputs; + + /* For the parser's use. Initialized to 0. */ + void *hook; + + /* The name used when printing messages. This is initialized to ARGV[0], + or PROGRAM_INVOCATION_NAME if that is unavailable. */ + char *name; + + /* Streams used when argp prints something. */ + FILE *err_stream; /* For errors; initialized to stderr. */ + FILE *out_stream; /* For information; initialized to stdout. */ + + void *pstate; /* Private, for use by argp. */ +}; + +/* Flags for argp_parse (note that the defaults are those that are + convenient for program command line parsing): */ + +/* Don't ignore the first element of ARGV. Normally (and always unless + ARGP_NO_ERRS is set) the first element of the argument vector is + skipped for option parsing purposes, as it corresponds to the program name + in a command line. */ +#define ARGP_PARSE_ARGV0 0x01 + +/* Don't print error messages for unknown options to stderr; unless this flag + is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program + name in the error messages. This flag implies ARGP_NO_EXIT (on the + assumption that silent exiting upon errors is bad behaviour). */ +#define ARGP_NO_ERRS 0x02 + +/* Don't parse any non-option args. Normally non-option args are parsed by + calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg + as the value. Since it's impossible to know which parse function wants to + handle it, each one is called in turn, until one returns 0 or an error + other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the + argp_parse returns prematurely (but with a return value of 0). If all + args have been parsed without error, all parsing functions are called one + last time with a key of ARGP_KEY_END. This flag needn't normally be set, + as the normal behavior is to stop parsing as soon as some argument can't + be handled. */ +#define ARGP_NO_ARGS 0x04 + +/* Parse options and arguments in the same order they occur on the command + line -- normally they're rearranged so that all options come first. */ +#define ARGP_IN_ORDER 0x08 + +/* Don't provide the standard long option --help, which causes usage and + option help information to be output to stdout, and exit (0) called. */ +#define ARGP_NO_HELP 0x10 + +/* Don't exit on errors (they may still result in error messages). */ +#define ARGP_NO_EXIT 0x20 + +/* Use the gnu getopt "long-only" rules for parsing arguments. */ +#define ARGP_LONG_ONLY 0x40 + +/* Turns off any message-printing/exiting options. */ +#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP) + +/* Parse the options strings in ARGC & ARGV according to the options in ARGP. + FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the + index in ARGV of the first unparsed option is returned in it. If an + unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser + routine returned a non-zero value, it is returned; otherwise 0 is + returned. This function may also call exit unless the ARGP_NO_HELP flag + is set. INPUT is a pointer to a value to be passed in to the parser. */ +extern error_t argp_parse (const struct argp *__restrict __argp, + int /*argc*/, char **__restrict /*argv*/, + unsigned __flags, int *__restrict __arg_index, + void *__restrict __input); +extern error_t __argp_parse (const struct argp *__restrict __argp, + int /*argc*/, char **__restrict /*argv*/, + unsigned __flags, int *__restrict __arg_index, + void *__restrict __input); + +/* Global variables. */ + +/* GNULIB makes sure both program_invocation_name and + program_invocation_short_name are available */ +#ifdef GNULIB_PROGRAM_INVOCATION_NAME +extern char *program_invocation_name; +# undef HAVE_DECL_PROGRAM_INVOCATION_NAME +# define HAVE_DECL_PROGRAM_INVOCATION_NAME 1 +#endif + +#ifdef GNULIB_PROGRAM_INVOCATION_SHORT_NAME +extern char *program_invocation_short_name; +# undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME +# define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1 +#endif + +/* If defined or set by the user program to a non-zero value, then a default + option --version is added (unless the ARGP_NO_HELP flag is used), which + will print this string followed by a newline and exit (unless the + ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ +extern const char *argp_program_version; + +/* If defined or set by the user program to a non-zero value, then a default + option --version is added (unless the ARGP_NO_HELP flag is used), which + calls this function with a stream to print the version to and a pointer to + the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is + used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ +extern void (*argp_program_version_hook) (FILE *__restrict __stream, + struct argp_state *__restrict + __state); + +/* If defined or set by the user program, it should point to string that is + the bug-reporting address for the program. It will be printed by + argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various + standard help messages), embedded in a sentence that says something like + "Report bugs to ADDR." */ +extern const char *argp_program_bug_address; + +/* The exit status that argp will use when exiting due to a parsing error. + If not defined or set by the user program, this defaults to EX_USAGE from + <sysexits.h>. */ +extern error_t argp_err_exit_status; + +/* Flags for argp_help. */ +#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */ +#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */ +#define ARGP_HELP_SEE 0x04 /* a "Try ... for more help" message. */ +#define ARGP_HELP_LONG 0x08 /* a long help message. */ +#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */ +#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */ +#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC) +#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */ +#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to + reflect ARGP_LONG_ONLY mode. */ + +/* These ARGP_HELP flags are only understood by argp_state_help. */ +#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */ +#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */ + +/* The standard thing to do after a program command line parsing error, if an + error message has already been printed. */ +#define ARGP_HELP_STD_ERR \ + (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) +/* The standard thing to do after a program command line parsing error, if no + more specific error message has been printed. */ +#define ARGP_HELP_STD_USAGE \ + (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) +/* The standard thing to do in response to a --help option. */ +#define ARGP_HELP_STD_HELP \ + (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \ + | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR) + +/* Output a usage message for ARGP to STREAM. FLAGS are from the set + ARGP_HELP_*. */ +extern void argp_help (const struct argp *__restrict __argp, + FILE *__restrict __stream, + unsigned __flags, char *__restrict __name); +extern void __argp_help (const struct argp *__restrict __argp, + FILE *__restrict __stream, unsigned __flags, + char *__name); + +/* The following routines are intended to be called from within an argp + parsing routine (thus taking an argp_state structure as the first + argument). They may or may not print an error message and exit, depending + on the flags in STATE -- in any case, the caller should be prepared for + them *not* to exit, and should return an appropiate error after calling + them. [argp_usage & argp_error should probably be called argp_state_..., + but they're used often enough that they should be short] */ + +/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are + from the set ARGP_HELP_*. */ +extern void argp_state_help (const struct argp_state *__restrict __state, + FILE *__restrict __stream, + unsigned int __flags); +extern void __argp_state_help (const struct argp_state *__restrict __state, + FILE *__restrict __stream, + unsigned int __flags); + +#if _LIBC || !defined __USE_EXTERN_INLINES +/* Possibly output the standard usage message for ARGP to stderr and exit. */ +extern void argp_usage (const struct argp_state *__state); +extern void __argp_usage (const struct argp_state *__state); +#endif + +/* If appropriate, print the printf string FMT and following args, preceded + by the program name and ':', to stderr, and followed by a "Try ... --help" + message, then exit (1). */ +extern void argp_error (const struct argp_state *__restrict __state, + const char *__restrict __fmt, ...) + _GL_ATTRIBUTE_FORMAT ((__printf__, 2, 3)); +extern void __argp_error (const struct argp_state *__restrict __state, + const char *__restrict __fmt, ...) + _GL_ATTRIBUTE_FORMAT ((__printf__, 2, 3)); + +/* Similar to the standard gnu error-reporting function error(), but will + respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print + to STATE->err_stream. This is useful for argument parsing code that is + shared between program startup (when exiting is desired) and runtime + option parsing (when typically an error code is returned instead). The + difference between this function and argp_error is that the latter is for + *parsing errors*, and the former is for other problems that occur during + parsing but don't reflect a (syntactic) problem with the input. */ +extern void argp_failure (const struct argp_state *__restrict __state, + int __status, int __errnum, + const char *__restrict __fmt, ...) + _GL_ATTRIBUTE_FORMAT ((__printf__, 4, 5)); +extern void __argp_failure (const struct argp_state *__restrict __state, + int __status, int __errnum, + const char *__restrict __fmt, ...) + _GL_ATTRIBUTE_FORMAT ((__printf__, 4, 5)); + +#if _LIBC || !defined __USE_EXTERN_INLINES +/* Returns true if the option OPT is a valid short option. */ +extern int _option_is_short (const struct argp_option *__opt) __THROW; +extern int __option_is_short (const struct argp_option *__opt) __THROW; + +/* Returns true if the option OPT is in fact the last (unused) entry in an + options array. */ +extern int _option_is_end (const struct argp_option *__opt) __THROW; +extern int __option_is_end (const struct argp_option *__opt) __THROW; +#endif + +/* Return the input field for ARGP in the parser corresponding to STATE; used + by the help routines. */ +extern void *_argp_input (const struct argp *__restrict __argp, + const struct argp_state *__restrict __state) + __THROW; +extern void *__argp_input (const struct argp *__restrict __argp, + const struct argp_state *__restrict __state) + __THROW; + +#ifdef __USE_EXTERN_INLINES + +# if !_LIBC +# define __argp_usage argp_usage +# define __argp_state_help argp_state_help +# define __option_is_short _option_is_short +# define __option_is_end _option_is_end +# endif + +# ifndef ARGP_EI +# ifdef __GNUC__ + /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 + inline semantics, unless -fgnu89-inline is used. It defines a macro + __GNUC_STDC_INLINE__ to indicate this situation or a macro + __GNUC_GNU_INLINE__ to indicate the opposite situation. + GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline + semantics but warns, unless -fgnu89-inline is used: + warning: C99 inline functions are not supported; using GNU89 + warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute + It defines a macro __GNUC_GNU_INLINE__ to indicate this situation. */ +# if defined __GNUC_STDC_INLINE__ +# define ARGP_EI __inline__ +# elif defined __GNUC_GNU_INLINE__ +# define ARGP_EI extern __inline__ __attribute__ ((__gnu_inline__)) +# else +# define ARGP_EI extern __inline__ +# endif +# else + /* With other compilers, assume the ISO C99 meaning of 'inline', if + the compiler supports 'inline' at all. */ +# define ARGP_EI inline +# endif +# endif + +ARGP_EI void +__argp_usage (const struct argp_state *__state) +{ + __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE); +} + +ARGP_EI int +__NTH (__option_is_short (const struct argp_option *__opt)) +{ + if (__opt->flags & OPTION_DOC) + return 0; + else + { + int __key = __opt->key; + return __key > 0 && __key <= UCHAR_MAX && isprint (__key); + } +} + +ARGP_EI int +__NTH (__option_is_end (const struct argp_option *__opt)) +{ + return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; +} + +# if !_LIBC +# undef __argp_usage +# undef __argp_state_help +# undef __option_is_short +# undef __option_is_end +# endif +#endif /* Use extern inlines. */ + +#ifdef __cplusplus +} +#endif + +#endif /* argp.h */ diff --git a/gnu/asnprintf.c b/gnu/asnprintf.c new file mode 100644 index 00000000..f7a9ca3f --- /dev/null +++ b/gnu/asnprintf.c @@ -0,0 +1,37 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Formatted output to strings. + Copyright (C) 1999, 2002, 2006, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include "vasnprintf.h" + +#include <stdarg.h> + +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/gnu/asprintf.c b/gnu/asprintf.c new file mode 100644 index 00000000..82cf26a8 --- /dev/null +++ b/gnu/asprintf.c @@ -0,0 +1,42 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Formatted output to strings. + Copyright (C) 1999, 2002, 2006-2007, 2009-2012 Free Software Foundation, + Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#ifdef IN_LIBASPRINTF +# include "vasprintf.h" +#else +# include <stdio.h> +#endif + +#include <stdarg.h> + +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/gnu/at-func.c b/gnu/at-func.c new file mode 100644 index 00000000..2230147f --- /dev/null +++ b/gnu/at-func.c @@ -0,0 +1,133 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Define at-style functions like fstatat, unlinkat, fchownat, etc. + Copyright (C) 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering */ + +#include "dosname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ +#include "openat.h" +#include "openat-priv.h" +#include "save-cwd.h" + +#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 inlude 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) +{ + /* 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; + + VALIDATE_FLAG (flag); + + if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) + return CALL_FUNC (file); + + { + 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; +} +#undef CALL_FUNC +#undef FUNC_RESULT +#undef FUNC_FAIL diff --git a/gnu/at-func2.c b/gnu/at-func2.c new file mode 100644 index 00000000..c9ffae09 --- /dev/null +++ b/gnu/at-func2.c @@ -0,0 +1,284 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Define 2-FD at-style functions like linkat or renameat. + Copyright (C) 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering and Eric Blake */ + +#include <config.h> + +#include "openat-priv.h" + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "dosname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ +#include "filenamecat.h" +#include "openat.h" +#include "same-inode.h" +#include "save-cwd.h" + +/* Call FUNC to operate on a pair of files, where FILE1 is relative to FD1, + and FILE2 is relative to FD2. If possible, do it without changing the + working directory. Otherwise, resort to using save_cwd/fchdir, + FUNC, restore_cwd (up to two times). If either the save_cwd or the + restore_cwd fails, then give a diagnostic and exit nonzero. */ +int +at_func2 (int fd1, char const *file1, + int fd2, char const *file2, + int (*func) (char const *file1, char const *file2)) +{ + struct saved_cwd saved_cwd; + int saved_errno; + int err; + char *file1_alt; + char *file2_alt; + struct stat st1; + struct stat st2; + + /* There are 16 possible scenarios, based on whether an fd is + AT_FDCWD or real, and whether a file is absolute or relative: + + fd1 file1 fd2 file2 action + 0 cwd abs cwd abs direct call + 1 cwd abs cwd rel direct call + 2 cwd abs fd abs direct call + 3 cwd abs fd rel chdir to fd2 + 4 cwd rel cwd abs direct call + 5 cwd rel cwd rel direct call + 6 cwd rel fd abs direct call + 7 cwd rel fd rel convert file1 to abs, then case 3 + 8 fd abs cwd abs direct call + 9 fd abs cwd rel direct call + 10 fd abs fd abs direct call + 11 fd abs fd rel chdir to fd2 + 12 fd rel cwd abs chdir to fd1 + 13 fd rel cwd rel convert file2 to abs, then case 12 + 14 fd rel fd abs chdir to fd1 + 15a fd1 rel fd1 rel chdir to fd1 + 15b fd1 rel fd2 rel chdir to fd1, then case 7 + + Try some optimizations to reduce fd to AT_FDCWD, or to at least + avoid converting an absolute name or doing a double chdir. */ + + if ((fd1 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file1)) + && (fd2 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file2))) + return func (file1, file2); /* Case 0-2, 4-6, 8-10. */ + + /* If /proc/self/fd works, we don't need any stat or chdir. */ + { + char proc_buf1[OPENAT_BUFFER_SIZE]; + char *proc_file1 = ((fd1 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file1)) + ? (char *) file1 + : openat_proc_name (proc_buf1, fd1, file1)); + if (proc_file1) + { + char proc_buf2[OPENAT_BUFFER_SIZE]; + char *proc_file2 = ((fd2 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file2)) + ? (char *) file2 + : openat_proc_name (proc_buf2, fd2, file2)); + if (proc_file2) + { + int proc_result = func (proc_file1, proc_file2); + int proc_errno = errno; + if (proc_file1 != proc_buf1 && proc_file1 != file1) + free (proc_file1); + if (proc_file2 != proc_buf2 && proc_file2 != file2) + free (proc_file2); + /* 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 <= proc_result) + return proc_result; + if (! EXPECTED_ERRNO (proc_errno)) + { + errno = proc_errno; + return proc_result; + } + } + else if (proc_file1 != proc_buf1 && proc_file1 != file1) + free (proc_file1); + } + } + + /* Cases 3, 7, 11-15 remain. Time to normalize directory fds, if + possible. */ + if (IS_ABSOLUTE_FILE_NAME (file1)) + fd1 = AT_FDCWD; /* Case 11 reduced to 3. */ + else if (IS_ABSOLUTE_FILE_NAME (file2)) + fd2 = AT_FDCWD; /* Case 14 reduced to 12. */ + + /* Cases 3, 7, 12, 13, 15 remain. */ + + if (fd1 == AT_FDCWD) /* Cases 3, 7. */ + { + if (stat (".", &st1) == -1 || fstat (fd2, &st2) == -1) + return -1; + if (!S_ISDIR (st2.st_mode)) + { + errno = ENOTDIR; + return -1; + } + if (SAME_INODE (st1, st2)) /* Reduced to cases 1, 5. */ + return func (file1, file2); + } + else if (fd2 == AT_FDCWD) /* Cases 12, 13. */ + { + if (stat (".", &st2) == -1 || fstat (fd1, &st1) == -1) + return -1; + if (!S_ISDIR (st1.st_mode)) + { + errno = ENOTDIR; + return -1; + } + if (SAME_INODE (st1, st2)) /* Reduced to cases 4, 5. */ + return func (file1, file2); + } + else if (fd1 != fd2) /* Case 15b. */ + { + if (fstat (fd1, &st1) == -1 || fstat (fd2, &st2) == -1) + return -1; + if (!S_ISDIR (st1.st_mode) || !S_ISDIR (st2.st_mode)) + { + errno = ENOTDIR; + return -1; + } + if (SAME_INODE (st1, st2)) /* Reduced to case 15a. */ + { + fd2 = fd1; + if (stat (".", &st1) == 0 && SAME_INODE (st1, st2)) + return func (file1, file2); /* Further reduced to case 5. */ + } + } + else /* Case 15a. */ + { + if (fstat (fd1, &st1) == -1) + return -1; + if (!S_ISDIR (st1.st_mode)) + { + errno = ENOTDIR; + return -1; + } + if (stat (".", &st2) == 0 && SAME_INODE (st1, st2)) + return func (file1, file2); /* Reduced to case 5. */ + } + + /* Cases 3, 7, 12, 13, 15a, 15b remain. With all reductions in + place, it is time to start changing directories. */ + + if (save_cwd (&saved_cwd) != 0) + openat_save_fail (errno); + + if (fd1 != AT_FDCWD && fd2 != AT_FDCWD && fd1 != fd2) /* Case 15b. */ + { + if (fchdir (fd1) != 0) + { + saved_errno = errno; + free_cwd (&saved_cwd); + errno = saved_errno; + return -1; + } + fd1 = AT_FDCWD; /* Reduced to case 7. */ + } + + /* Cases 3, 7, 12, 13, 15a remain. Convert one relative name to + absolute, if necessary. */ + + file1_alt = (char *) file1; + file2_alt = (char *) file2; + + if (fd1 == AT_FDCWD && !IS_ABSOLUTE_FILE_NAME (file1)) /* Case 7. */ + { + /* It would be nicer to use: + file1_alt = file_name_concat (xgetcwd (), file1, NULL); + but libraries should not call xalloc_die. */ + char *cwd = getcwd (NULL, 0); + if (!cwd) + { + saved_errno = errno; + free_cwd (&saved_cwd); + errno = saved_errno; + return -1; + } + file1_alt = mfile_name_concat (cwd, file1, NULL); + if (!file1_alt) + { + saved_errno = errno; + free (cwd); + free_cwd (&saved_cwd); + errno = saved_errno; + return -1; + } + free (cwd); /* Reduced to case 3. */ + } + else if (fd2 == AT_FDCWD && !IS_ABSOLUTE_FILE_NAME (file2)) /* Case 13. */ + { + char *cwd = getcwd (NULL, 0); + if (!cwd) + { + saved_errno = errno; + free_cwd (&saved_cwd); + errno = saved_errno; + return -1; + } + file2_alt = mfile_name_concat (cwd, file2, NULL); + if (!file2_alt) + { + saved_errno = errno; + free (cwd); + free_cwd (&saved_cwd); + errno = saved_errno; + return -1; + } + free (cwd); /* Reduced to case 12. */ + } + + /* Cases 3, 12, 15a remain. Change to the correct directory. */ + if (fchdir (fd1 == AT_FDCWD ? fd2 : fd1) != 0) + { + saved_errno = errno; + free_cwd (&saved_cwd); + if (file1 != file1_alt) + free (file1_alt); + else if (file2 != file2_alt) + free (file2_alt); + errno = saved_errno; + return -1; + } + + /* Finally safe to perform the user's function, then clean up. */ + + err = func (file1_alt, file2_alt); + saved_errno = (err < 0 ? errno : 0); + + if (file1 != file1_alt) + free (file1_alt); + else if (file2 != file2_alt) + free (file2_alt); + + if (restore_cwd (&saved_cwd) != 0) + openat_restore_fail (errno); + + free_cwd (&saved_cwd); + + if (saved_errno) + errno = saved_errno; + return err; +} +#undef CALL_FUNC +#undef FUNC_RESULT diff --git a/gnu/backupfile.c b/gnu/backupfile.c new file mode 100644 index 00000000..5ec5f7b5 --- /dev/null +++ b/gnu/backupfile.c @@ -0,0 +1,357 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* backupfile.c -- make Emacs style backup file names + + Copyright (C) 1990-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert and David MacKenzie. + Some algorithms adapted from GNU Emacs. */ + +#include <config.h> + +#include "backupfile.h" + +#include "argmatch.h" +#include "dirname.h" +#include "xalloc.h" + +#include <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include <limits.h> + +#include <unistd.h> + +#include "dirent--.h" +#ifndef _D_EXACT_NAMLEN +# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name) +#endif +#if D_INO_IN_DIRENT +# define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0) +#else +# define REAL_DIR_ENTRY(dp) 1 +#endif + +#if ! (HAVE_PATHCONF && defined _PC_NAME_MAX) +# define pathconf(file, option) (errno = -1) +#endif + +#ifndef _POSIX_NAME_MAX +# define _POSIX_NAME_MAX 14 +#endif +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + +#if defined _XOPEN_NAME_MAX +# define NAME_MAX_MINIMUM _XOPEN_NAME_MAX +#else +# define NAME_MAX_MINIMUM _POSIX_NAME_MAX +#endif + +#ifndef HAVE_DOS_FILE_NAMES +# define HAVE_DOS_FILE_NAMES 0 +#endif +#ifndef HAVE_LONG_FILE_NAMES +# define HAVE_LONG_FILE_NAMES 0 +#endif + +/* ISDIGIT differs from isdigit, as follows: + - Its arg may be any int or unsigned int; it need not be an unsigned char + or EOF. + - It's typically faster. + POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to + ISDIGIT unless it's important to use the locale's definition + of "digit" even when the host does not conform to POSIX. */ +#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) + +/* The extension added to file names to produce a simple (as opposed + to numbered) backup file name. */ +char const *simple_backup_suffix = "~"; + + +/* If FILE (which was of length FILELEN before an extension was + appended to it) is too long, replace the extension with the single + char E. If the result is still too long, remove the char just + before E. */ + +static void +check_extension (char *file, size_t filelen, char e) +{ + char *base = last_component (file); + size_t baselen = base_len (base); + size_t baselen_max = HAVE_LONG_FILE_NAMES ? 255 : NAME_MAX_MINIMUM; + + if (HAVE_DOS_FILE_NAMES || NAME_MAX_MINIMUM < baselen) + { + /* The new base name is long enough to require a pathconf check. */ + long name_max; + + /* Temporarily modify the buffer into its parent directory name, + invoke pathconf on the directory, and then restore the buffer. */ + char tmp[sizeof "."]; + memcpy (tmp, base, sizeof "."); + strcpy (base, "."); + errno = 0; + name_max = pathconf (file, _PC_NAME_MAX); + if (0 <= name_max || errno == 0) + { + long size = baselen_max = name_max; + if (name_max != size) + baselen_max = SIZE_MAX; + } + memcpy (base, tmp, sizeof "."); + } + + if (HAVE_DOS_FILE_NAMES && baselen_max <= 12) + { + /* Live within DOS's 8.3 limit. */ + char *dot = strchr (base, '.'); + if (!dot) + baselen_max = 8; + else + { + char const *second_dot = strchr (dot + 1, '.'); + baselen_max = (second_dot + ? second_dot - base + : dot + 1 - base + 3); + } + } + + if (baselen_max < baselen) + { + baselen = file + filelen - base; + if (baselen_max <= baselen) + baselen = baselen_max - 1; + base[baselen] = e; + base[baselen + 1] = '\0'; + } +} + +/* Returned values for NUMBERED_BACKUP. */ + +enum numbered_backup_result + { + /* The new backup name is the same length as an existing backup + name, so it's valid for that directory. */ + BACKUP_IS_SAME_LENGTH, + + /* Some backup names already exist, but the returned name is longer + than any of them, and its length should be checked. */ + BACKUP_IS_LONGER, + + /* There are no existing backup names. The new name's length + should be checked. */ + BACKUP_IS_NEW + }; + +/* *BUFFER contains a file name. Store into *BUFFER the next backup + name for the named file, with a version number greater than all the + existing numbered backups. Reallocate *BUFFER as necessary; its + initial allocated size is BUFFER_SIZE, which must be at least 4 + bytes longer than the file name to make room for the initially + appended ".~1". FILELEN is the length of the original file name. + The returned value indicates what kind of backup was found. If an + I/O or other read error occurs, use the highest backup number that + was found. */ + +static enum numbered_backup_result +numbered_backup (char **buffer, size_t buffer_size, size_t filelen) +{ + enum numbered_backup_result result = BACKUP_IS_NEW; + DIR *dirp; + struct dirent *dp; + char *buf = *buffer; + size_t versionlenmax = 1; + char *base = last_component (buf); + size_t base_offset = base - buf; + size_t baselen = base_len (base); + + /* Temporarily modify the buffer into its parent directory name, + open the directory, and then restore the buffer. */ + char tmp[sizeof "."]; + memcpy (tmp, base, sizeof "."); + strcpy (base, "."); + dirp = opendir (buf); + memcpy (base, tmp, sizeof "."); + strcpy (base + baselen, ".~1~"); + + if (!dirp) + return result; + + while ((dp = readdir (dirp)) != NULL) + { + char const *p; + char *q; + bool all_9s; + size_t versionlen; + size_t new_buflen; + + if (! REAL_DIR_ENTRY (dp) || _D_EXACT_NAMLEN (dp) < baselen + 4) + continue; + + if (memcmp (buf + base_offset, dp->d_name, baselen + 2) != 0) + continue; + + p = dp->d_name + baselen + 2; + + /* Check whether this file has a version number and if so, + whether it is larger. Use string operations rather than + integer arithmetic, to avoid problems with integer overflow. */ + + if (! ('1' <= *p && *p <= '9')) + continue; + all_9s = (*p == '9'); + for (versionlen = 1; ISDIGIT (p[versionlen]); versionlen++) + all_9s &= (p[versionlen] == '9'); + + if (! (p[versionlen] == '~' && !p[versionlen + 1] + && (versionlenmax < versionlen + || (versionlenmax == versionlen + && memcmp (buf + filelen + 2, p, versionlen) <= 0)))) + continue; + + /* This directory has the largest version number seen so far. + Append this highest numbered extension to the file name, + prepending '0' to the number if it is all 9s. */ + + versionlenmax = all_9s + versionlen; + result = (all_9s ? BACKUP_IS_LONGER : BACKUP_IS_SAME_LENGTH); + new_buflen = filelen + 2 + versionlenmax + 1; + if (buffer_size <= new_buflen) + { + buf = xnrealloc (buf, 2, new_buflen); + buffer_size = new_buflen * 2; + } + q = buf + filelen; + *q++ = '.'; + *q++ = '~'; + *q = '0'; + q += all_9s; + memcpy (q, p, versionlen + 2); + + /* Add 1 to the version number. */ + + q += versionlen; + while (*--q == '9') + *q = '0'; + ++*q; + } + + closedir (dirp); + *buffer = buf; + return result; +} + +/* Return the name of the new backup file for the existing file FILE, + allocated with malloc. Report an error and fail if out of memory. + Do not call this function if backup_type == no_backups. */ + +char * +find_backup_file_name (char const *file, enum backup_type backup_type) +{ + size_t filelen = strlen (file); + char *s; + size_t ssize; + bool simple = true; + + /* Allow room for simple or ".~N~" backups. The guess must be at + least sizeof ".~1~", but otherwise will be adjusted as needed. */ + size_t simple_backup_suffix_size = strlen (simple_backup_suffix) + 1; + size_t backup_suffix_size_guess = simple_backup_suffix_size; + enum { GUESS = sizeof ".~12345~" }; + if (backup_suffix_size_guess < GUESS) + backup_suffix_size_guess = GUESS; + + ssize = filelen + backup_suffix_size_guess + 1; + s = xmalloc (ssize); + memcpy (s, file, filelen + 1); + + if (backup_type != simple_backups) + switch (numbered_backup (&s, ssize, filelen)) + { + case BACKUP_IS_SAME_LENGTH: + return s; + + case BACKUP_IS_LONGER: + simple = false; + break; + + case BACKUP_IS_NEW: + simple = (backup_type == numbered_existing_backups); + break; + } + + if (simple) + memcpy (s + filelen, simple_backup_suffix, simple_backup_suffix_size); + check_extension (s, filelen, '~'); + return s; +} + +static char const * const backup_args[] = +{ + /* In a series of synonyms, present the most meaningful first, so + that argmatch_valid be more readable. */ + "none", "off", + "simple", "never", + "existing", "nil", + "numbered", "t", + NULL +}; + +static const enum backup_type backup_types[] = +{ + no_backups, no_backups, + simple_backups, simple_backups, + numbered_existing_backups, numbered_existing_backups, + numbered_backups, numbered_backups +}; + +/* Ensure that these two vectors have the same number of elements, + not counting the final NULL in the first one. */ +ARGMATCH_VERIFY (backup_args, backup_types); + +/* Return the type of backup specified by VERSION. + If VERSION is NULL or the empty string, return numbered_existing_backups. + If VERSION is invalid or ambiguous, fail with a diagnostic appropriate + for the specified CONTEXT. Unambiguous abbreviations are accepted. */ + +enum backup_type +get_version (char const *context, char const *version) +{ + if (version == 0 || *version == 0) + return numbered_existing_backups; + else + return XARGMATCH (context, version, backup_args, backup_types); +} + + +/* Return the type of backup specified by VERSION. + If VERSION is NULL, use the value of the envvar VERSION_CONTROL. + If the specified string is invalid or ambiguous, fail with a diagnostic + appropriate for the specified CONTEXT. + Unambiguous abbreviations are accepted. */ + +enum backup_type +xget_version (char const *context, char const *version) +{ + if (version && *version) + return get_version (context, version); + else + return get_version ("$VERSION_CONTROL", getenv ("VERSION_CONTROL")); +} diff --git a/gnu/backupfile.h b/gnu/backupfile.h new file mode 100644 index 00000000..6ff35a8d --- /dev/null +++ b/gnu/backupfile.h @@ -0,0 +1,61 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* backupfile.h -- declarations for making Emacs style backup file names + + Copyright (C) 1990-1992, 1997-1999, 2003-2004, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef BACKUPFILE_H_ +# define BACKUPFILE_H_ + +# ifdef __cplusplus +extern "C" { +# endif + + +/* When to make backup files. */ +enum backup_type +{ + /* Never make backups. */ + no_backups, + + /* Make simple backups of every file. */ + simple_backups, + + /* Make numbered backups of files that already have numbered backups, + and simple backups of the others. */ + numbered_existing_backups, + + /* Make numbered backups of every file. */ + numbered_backups +}; + +# define VALID_BACKUP_TYPE(Type) \ + ((unsigned int) (Type) <= numbered_backups) + +extern char const *simple_backup_suffix; + +char *find_backup_file_name (char const *, enum backup_type); +enum backup_type get_version (char const *context, char const *arg); +enum backup_type xget_version (char const *context, char const *arg); +void addext (char *, char const *, int); + + +# ifdef __cplusplus +} +# endif + +#endif /* ! BACKUPFILE_H_ */ diff --git a/gnu/basename-lgpl.c b/gnu/basename-lgpl.c new file mode 100644 index 00000000..e81ea6a7 --- /dev/null +++ b/gnu/basename-lgpl.c @@ -0,0 +1,77 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* basename.c -- return the last element in a file name + + Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "dirname.h" + +#include <string.h> + +/* Return the address of the last file name component of NAME. If + NAME has no relative file name components because it is a file + system root, return the empty string. */ + +char * +last_component (char const *name) +{ + char const *base = name + FILE_SYSTEM_PREFIX_LEN (name); + char const *p; + bool saw_slash = false; + + while (ISSLASH (*base)) + base++; + + for (p = base; *p; p++) + { + if (ISSLASH (*p)) + saw_slash = true; + else if (saw_slash) + { + base = p; + saw_slash = false; + } + } + + return (char *) base; +} + +/* Return the length of the basename NAME. Typically NAME is the + value returned by base_name or last_component. Act like strlen + (NAME), except omit all trailing slashes. */ + +size_t +base_len (char const *name) +{ + 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/gnu/basename.c b/gnu/basename.c new file mode 100644 index 00000000..c516bea3 --- /dev/null +++ b/gnu/basename.c @@ -0,0 +1,60 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* basename.c -- return the last element in a file name + + Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "dirname.h" + +#include <string.h> +#include "xalloc.h" +#include "xstrndup.h" + +char * +base_name (char const *name) +{ + char const *base = last_component (name); + size_t length; + + /* If there is no last component, then name is a file system root or the + empty string. */ + if (! *base) + return xstrndup (name, base_len (name)); + + /* Collapse a sequence of trailing slashes into one. */ + length = base_len (base); + if (ISSLASH (base[length])) + length++; + + /* On systems with drive letters, "a/b:c" must return "./b:c" rather + than "b:c" to avoid confusion with a drive letter. On systems + with pure POSIX semantics, this is not an issue. */ + if (FILE_SYSTEM_PREFIX_LEN (base)) + { + char *p = xmalloc (length + 3); + p[0] = '.'; + p[1] = '/'; + memcpy (p + 2, base, length); + p[length + 2] = '\0'; + return p; + } + + /* Finally, copy the basename. */ + return xstrndup (base, length); +} diff --git a/gnu/bitrotate.h b/gnu/bitrotate.h new file mode 100644 index 00000000..0fa07b0a --- /dev/null +++ b/gnu/bitrotate.h @@ -0,0 +1,128 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* bitrotate.h - Rotate bits in integers + Copyright (C) 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Simon Josefsson <simon@josefsson.org>, 2008. */ + +#ifndef _GL_BITROTATE_H +#define _GL_BITROTATE_H + +#include <limits.h> +#include <stdint.h> +#include <sys/types.h> + +#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. */ +static 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.*/ +static 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. */ +static 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.*/ +static 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. */ +static 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. */ +static 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. */ +static inline uint16_t +rotl16 (uint16_t x, int n) +{ + return ((x << n) | (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. */ +static inline uint16_t +rotr16 (uint16_t x, int n) +{ + return ((x >> n) | (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. */ +static inline uint8_t +rotl8 (uint8_t x, int n) +{ + return ((x << n) | (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. */ +static inline uint8_t +rotr8 (uint8_t x, int n) +{ + return ((x >> n) | (x << (8 - n))) & UINT8_MAX; +} + +#endif /* _GL_BITROTATE_H */ diff --git a/gnu/btowc.c b/gnu/btowc.c new file mode 100644 index 00000000..02f1907a --- /dev/null +++ b/gnu/btowc.c @@ -0,0 +1,41 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert unibyte character to wide character. + Copyright (C) 2008, 2010-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <wchar.h> + +#include <stdio.h> +#include <stdlib.h> + +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/gnu/c-ctype.c b/gnu/c-ctype.c new file mode 100644 index 00000000..cd935a39 --- /dev/null +++ b/gnu/c-ctype.c @@ -0,0 +1,398 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Character handling in C locale. + + Copyright 2000-2003, 2006, 2009-2012 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, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#define NO_C_CTYPE_MACROS +#include "c-ctype.h" + +/* The function isascii is not locale dependent. Its use in EBCDIC is + questionable. */ +bool +c_isascii (int c) +{ + return (c >= 0x00 && c <= 0x7f); +} + +bool +c_isalnum (int c) +{ +#if C_CTYPE_CONSECUTIVE_DIGITS \ + && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII + return ((c >= '0' && c <= '9') + || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z')); +#else + return ((c >= '0' && c <= '9') + || (c >= 'A' && c <= 'Z') + || (c >= 'a' && c <= 'z')); +#endif +#else + switch (c) + { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + 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 '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': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isalpha (int c) +{ +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII + return ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z'); +#else + return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); +#endif +#else + switch (c) + { + 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 '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': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isblank (int c) +{ + return (c == ' ' || c == '\t'); +} + +bool +c_iscntrl (int c) +{ +#if C_CTYPE_ASCII + return ((c & ~0x1f) == 0 || c == 0x7f); +#else + switch (c) + { + case ' ': 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 '@': + 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 '`': + 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 0; + default: + return 1; + } +#endif +} + +bool +c_isdigit (int c) +{ +#if C_CTYPE_CONSECUTIVE_DIGITS + return (c >= '0' && c <= '9'); +#else + switch (c) + { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + return 1; + default: + return 0; + } +#endif +} + +bool +c_islower (int c) +{ +#if C_CTYPE_CONSECUTIVE_LOWERCASE + return (c >= 'a' && c <= 'z'); +#else + switch (c) + { + 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': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isgraph (int c) +{ +#if C_CTYPE_ASCII + return (c >= '!' && c <= '~'); +#else + switch (c) + { + 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 '@': + 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 '`': + 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 +} + +bool +c_isprint (int c) +{ +#if C_CTYPE_ASCII + return (c >= ' ' && c <= '~'); +#else + switch (c) + { + case ' ': 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 '@': + 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 '`': + 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 +} + +bool +c_ispunct (int c) +{ +#if C_CTYPE_ASCII + return ((c >= '!' && c <= '~') + && !((c >= '0' && c <= '9') + || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z'))); +#else + switch (c) + { + 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 '~': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isspace (int c) +{ + return (c == ' ' || c == '\t' + || c == '\n' || c == '\v' || c == '\f' || c == '\r'); +} + +bool +c_isupper (int c) +{ +#if C_CTYPE_CONSECUTIVE_UPPERCASE + return (c >= 'A' && c <= 'Z'); +#else + switch (c) + { + 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': + return 1; + default: + return 0; + } +#endif +} + +bool +c_isxdigit (int c) +{ +#if C_CTYPE_CONSECUTIVE_DIGITS \ + && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII + return ((c >= '0' && c <= '9') + || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'F')); +#else + return ((c >= '0' && c <= '9') + || (c >= 'A' && c <= 'F') + || (c >= 'a' && c <= 'f')); +#endif +#else + switch (c) + { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + return 1; + default: + return 0; + } +#endif +} + +int +c_tolower (int c) +{ +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE + return (c >= 'A' && c <= 'Z' ? c - 'A' + 'a' : c); +#else + switch (c) + { + case 'A': return 'a'; + case 'B': return 'b'; + case 'C': return 'c'; + case 'D': return 'd'; + case 'E': return 'e'; + case 'F': return 'f'; + case 'G': return 'g'; + case 'H': return 'h'; + case 'I': return 'i'; + case 'J': return 'j'; + case 'K': return 'k'; + case 'L': return 'l'; + case 'M': return 'm'; + case 'N': return 'n'; + case 'O': return 'o'; + case 'P': return 'p'; + case 'Q': return 'q'; + case 'R': return 'r'; + case 'S': return 's'; + case 'T': return 't'; + case 'U': return 'u'; + case 'V': return 'v'; + case 'W': return 'w'; + case 'X': return 'x'; + case 'Y': return 'y'; + case 'Z': return 'z'; + default: return c; + } +#endif +} + +int +c_toupper (int c) +{ +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE + return (c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c); +#else + switch (c) + { + case 'a': return 'A'; + case 'b': return 'B'; + case 'c': return 'C'; + case 'd': return 'D'; + case 'e': return 'E'; + case 'f': return 'F'; + case 'g': return 'G'; + case 'h': return 'H'; + case 'i': return 'I'; + case 'j': return 'J'; + case 'k': return 'K'; + case 'l': return 'L'; + case 'm': return 'M'; + case 'n': return 'N'; + case 'o': return 'O'; + case 'p': return 'P'; + case 'q': return 'Q'; + case 'r': return 'R'; + case 's': return 'S'; + case 't': return 'T'; + case 'u': return 'U'; + case 'v': return 'V'; + case 'w': return 'W'; + case 'x': return 'X'; + case 'y': return 'Y'; + case 'z': return 'Z'; + default: return c; + } +#endif +} diff --git a/gnu/c-ctype.h b/gnu/c-ctype.h new file mode 100644 index 00000000..e33c606e --- /dev/null +++ b/gnu/c-ctype.h @@ -0,0 +1,297 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Character handling in C locale. + + These functions work like the corresponding functions in <ctype.h>, + except that they have the C (POSIX) locale hardwired, whereas the + <ctype.h> functions' behaviour depends on the current locale set via + setlocale. + + Copyright (C) 2000-2003, 2006, 2008-2012 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, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef C_CTYPE_H +#define C_CTYPE_H + +#include <stdbool.h> + + +#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. */ + + +/* Check whether the ASCII optimizations apply. */ + +/* ANSI C89 (and ISO C99 5.2.1.3 too) already guarantees that + '0', '1', ..., '9' have consecutive integer values. */ +#define C_CTYPE_CONSECUTIVE_DIGITS 1 + +#if ('A' <= 'Z') \ + && ('A' + 1 == 'B') && ('B' + 1 == 'C') && ('C' + 1 == 'D') \ + && ('D' + 1 == 'E') && ('E' + 1 == 'F') && ('F' + 1 == 'G') \ + && ('G' + 1 == 'H') && ('H' + 1 == 'I') && ('I' + 1 == 'J') \ + && ('J' + 1 == 'K') && ('K' + 1 == 'L') && ('L' + 1 == 'M') \ + && ('M' + 1 == 'N') && ('N' + 1 == 'O') && ('O' + 1 == 'P') \ + && ('P' + 1 == 'Q') && ('Q' + 1 == 'R') && ('R' + 1 == 'S') \ + && ('S' + 1 == 'T') && ('T' + 1 == 'U') && ('U' + 1 == 'V') \ + && ('V' + 1 == 'W') && ('W' + 1 == 'X') && ('X' + 1 == 'Y') \ + && ('Y' + 1 == 'Z') +#define C_CTYPE_CONSECUTIVE_UPPERCASE 1 +#endif + +#if ('a' <= 'z') \ + && ('a' + 1 == 'b') && ('b' + 1 == 'c') && ('c' + 1 == 'd') \ + && ('d' + 1 == 'e') && ('e' + 1 == 'f') && ('f' + 1 == 'g') \ + && ('g' + 1 == 'h') && ('h' + 1 == 'i') && ('i' + 1 == 'j') \ + && ('j' + 1 == 'k') && ('k' + 1 == 'l') && ('l' + 1 == 'm') \ + && ('m' + 1 == 'n') && ('n' + 1 == 'o') && ('o' + 1 == 'p') \ + && ('p' + 1 == 'q') && ('q' + 1 == 'r') && ('r' + 1 == 's') \ + && ('s' + 1 == 't') && ('t' + 1 == 'u') && ('u' + 1 == 'v') \ + && ('v' + 1 == 'w') && ('w' + 1 == 'x') && ('x' + 1 == 'y') \ + && ('y' + 1 == 'z') +#define C_CTYPE_CONSECUTIVE_LOWERCASE 1 +#endif + +#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 +#endif + + +/* Function declarations. */ + +/* Unlike the functions in <ctype.h>, 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 <ctype.h> 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)) ... + */ + +extern bool c_isascii (int c) _GL_ATTRIBUTE_CONST; /* not locale dependent */ + +extern bool c_isalnum (int c) _GL_ATTRIBUTE_CONST; +extern bool c_isalpha (int c) _GL_ATTRIBUTE_CONST; +extern bool c_isblank (int c) _GL_ATTRIBUTE_CONST; +extern bool c_iscntrl (int c) _GL_ATTRIBUTE_CONST; +extern bool c_isdigit (int c) _GL_ATTRIBUTE_CONST; +extern bool c_islower (int c) _GL_ATTRIBUTE_CONST; +extern bool c_isgraph (int c) _GL_ATTRIBUTE_CONST; +extern bool c_isprint (int c) _GL_ATTRIBUTE_CONST; +extern bool c_ispunct (int c) _GL_ATTRIBUTE_CONST; +extern bool c_isspace (int c) _GL_ATTRIBUTE_CONST; +extern bool c_isupper (int c) _GL_ATTRIBUTE_CONST; +extern bool c_isxdigit (int c) _GL_ATTRIBUTE_CONST; + +extern int c_tolower (int c) _GL_ATTRIBUTE_CONST; +extern int c_toupper (int c) _GL_ATTRIBUTE_CONST; + + +#if defined __GNUC__ && defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS + +/* ASCII optimizations. */ + +#undef c_isascii +#define c_isascii(c) \ + ({ int __c = (c); \ + (__c >= 0x00 && __c <= 0x7f); \ + }) + +#if C_CTYPE_CONSECUTIVE_DIGITS \ + && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII +#undef c_isalnum +#define c_isalnum(c) \ + ({ int __c = (c); \ + ((__c >= '0' && __c <= '9') \ + || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \ + }) +#else +#undef c_isalnum +#define c_isalnum(c) \ + ({ int __c = (c); \ + ((__c >= '0' && __c <= '9') \ + || (__c >= 'A' && __c <= 'Z') \ + || (__c >= 'a' && __c <= 'z')); \ + }) +#endif +#endif + +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII +#undef c_isalpha +#define c_isalpha(c) \ + ({ int __c = (c); \ + ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \ + }) +#else +#undef c_isalpha +#define c_isalpha(c) \ + ({ int __c = (c); \ + ((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \ + }) +#endif +#endif + +#undef c_isblank +#define c_isblank(c) \ + ({ int __c = (c); \ + (__c == ' ' || __c == '\t'); \ + }) + +#if C_CTYPE_ASCII +#undef c_iscntrl +#define c_iscntrl(c) \ + ({ int __c = (c); \ + ((__c & ~0x1f) == 0 || __c == 0x7f); \ + }) +#endif + +#if C_CTYPE_CONSECUTIVE_DIGITS +#undef c_isdigit +#define c_isdigit(c) \ + ({ int __c = (c); \ + (__c >= '0' && __c <= '9'); \ + }) +#endif + +#if C_CTYPE_CONSECUTIVE_LOWERCASE +#undef c_islower +#define c_islower(c) \ + ({ int __c = (c); \ + (__c >= 'a' && __c <= 'z'); \ + }) +#endif + +#if C_CTYPE_ASCII +#undef c_isgraph +#define c_isgraph(c) \ + ({ int __c = (c); \ + (__c >= '!' && __c <= '~'); \ + }) +#endif + +#if C_CTYPE_ASCII +#undef c_isprint +#define c_isprint(c) \ + ({ int __c = (c); \ + (__c >= ' ' && __c <= '~'); \ + }) +#endif + +#if C_CTYPE_ASCII +#undef c_ispunct +#define c_ispunct(c) \ + ({ int _c = (c); \ + (c_isgraph (_c) && ! c_isalnum (_c)); \ + }) +#endif + +#undef c_isspace +#define c_isspace(c) \ + ({ int __c = (c); \ + (__c == ' ' || __c == '\t' \ + || __c == '\n' || __c == '\v' || __c == '\f' || __c == '\r'); \ + }) + +#if C_CTYPE_CONSECUTIVE_UPPERCASE +#undef c_isupper +#define c_isupper(c) \ + ({ int __c = (c); \ + (__c >= 'A' && __c <= 'Z'); \ + }) +#endif + +#if C_CTYPE_CONSECUTIVE_DIGITS \ + && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#if C_CTYPE_ASCII +#undef c_isxdigit +#define c_isxdigit(c) \ + ({ int __c = (c); \ + ((__c >= '0' && __c <= '9') \ + || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'F')); \ + }) +#else +#undef c_isxdigit +#define c_isxdigit(c) \ + ({ int __c = (c); \ + ((__c >= '0' && __c <= '9') \ + || (__c >= 'A' && __c <= 'F') \ + || (__c >= 'a' && __c <= 'f')); \ + }) +#endif +#endif + +#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +#undef c_tolower +#define c_tolower(c) \ + ({ int __c = (c); \ + (__c >= 'A' && __c <= 'Z' ? __c - 'A' + 'a' : __c); \ + }) +#undef c_toupper +#define c_toupper(c) \ + ({ int __c = (c); \ + (__c >= 'a' && __c <= 'z' ? __c - 'a' + 'A' : __c); \ + }) +#endif + +#endif /* optimizing for speed */ + + +#ifdef __cplusplus +} +#endif + +#endif /* C_CTYPE_H */ diff --git a/gnu/c-strcase.h b/gnu/c-strcase.h new file mode 100644 index 00000000..1383a8b4 --- /dev/null +++ b/gnu/c-strcase.h @@ -0,0 +1,59 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Case-insensitive string comparison functions in C locale. + Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2012 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef C_STRCASE_H +#define C_STRCASE_H + +#include <stddef.h> + + +/* 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/gnu/c-strcasecmp.c b/gnu/c-strcasecmp.c new file mode 100644 index 00000000..028e5f82 --- /dev/null +++ b/gnu/c-strcasecmp.c @@ -0,0 +1,59 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* c-strcasecmp.c -- case insensitive string comparator in C locale + Copyright (C) 1998-1999, 2005-2006, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include "c-strcase.h" + +#include <limits.h> + +#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 (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); +} diff --git a/gnu/c-strcaseeq.h b/gnu/c-strcaseeq.h new file mode 100644 index 00000000..17e6f042 --- /dev/null +++ b/gnu/c-strcaseeq.h @@ -0,0 +1,186 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Optimized case-insensitive string comparison in C locale. + Copyright (C) 2001-2002, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>. */ + +#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 (__OPTIMIZE__) + +/* Case insensitive comparison of ASCII characters. */ +# if C_CTYPE_ASCII +# define CASEEQ(other,upper) \ + (c_isupper (upper) ? ((other) & ~0x20) == (upper) : (other) == (upper)) +# elif C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE +# define CASEEQ(other,upper) \ + (c_isupper (upper) ? (other) == (upper) || (other) == (upper) - 'A' + 'a' : (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/gnu/c-strncasecmp.c b/gnu/c-strncasecmp.c new file mode 100644 index 00000000..f974cdf8 --- /dev/null +++ b/gnu/c-strncasecmp.c @@ -0,0 +1,59 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* c-strncasecmp.c -- case insensitive string comparator in C locale + Copyright (C) 1998-1999, 2005-2006, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include "c-strcase.h" + +#include <limits.h> + +#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 (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); +} diff --git a/gnu/canonicalize-lgpl.c b/gnu/canonicalize-lgpl.c new file mode 100644 index 00000000..7a2cc03b --- /dev/null +++ b/gnu/canonicalize-lgpl.c @@ -0,0 +1,380 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Return the canonical absolute name of a given file. + Copyright (C) 1996-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _LIBC +# define _GL_USE_STDLIB_ALLOC 1 +# include <config.h> +#endif + +#if !HAVE_CANONICALIZE_FILE_NAME || !FUNC_REALPATH_WORKS || defined _LIBC + +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the name == NULL test below. */ +#define _GL_ARG_NONNULL(params) + +/* Specification. */ +#include <stdlib.h> + +#include <alloca.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#if HAVE_SYS_PARAM_H || defined _LIBC +# include <sys/param.h> +#endif +#include <sys/stat.h> +#include <errno.h> +#include <stddef.h> + +#ifdef _LIBC +# include <shlib-compat.h> +#else +# define SHLIB_COMPAT(lib, introduced, obsoleted) 0 +# define versioned_symbol(lib, local, symbol, version) extern int dummy +# define compat_symbol(lib, local, symbol, version) +# define weak_alias(local, symbol) +# define __canonicalize_file_name canonicalize_file_name +# define __realpath realpath +# include "pathmax.h" +# include "malloca.h" +# if 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 +# ifdef VMS + /* We want the directory in Unix syntax, not in VMS syntax. */ +# define __getcwd(buf, max) getcwd (buf, max, 0) +# else +# define __getcwd getcwd +# endif +# else +# define __getcwd(buf, max) getwd (buf) +# endif +# define __readlink readlink +# define __set_errno(e) errno = (e) +# ifndef MAXSYMLINKS +# ifdef SYMLOOP_MAX +# define MAXSYMLINKS SYMLOOP_MAX +# else +# define MAXSYMLINKS 20 +# endif +# endif +#endif + +#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT +# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 +#endif + +#if !FUNC_REALPATH_WORKS || defined _LIBC +/* Return the canonical absolute name of file NAME. A canonical name + does not contain any ".", ".." components nor any repeated path + separators ('/') or symlinks. All path 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 path of the first component + that cannot be resolved. If the path can be resolved, RESOLVED + holds the same value as the value returned. */ + +char * +__realpath (const char *name, char *resolved) +{ + char *rpath, *dest, *extra_buf = NULL; + const char *start, *end, *rpath_limit; + long int path_max; + 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; + } + +#ifdef PATH_MAX + path_max = PATH_MAX; +#else + path_max = pathconf (name, _PC_PATH_MAX); + if (path_max <= 0) + path_max = 8192; +#endif + + if (resolved == NULL) + { + rpath = malloc (path_max); + if (rpath == NULL) + { + /* It's easier to set errno to ENOMEM than to rely on the + 'malloc-posix' gnulib module. */ + errno = ENOMEM; + return NULL; + } + } + else + rpath = resolved; + rpath_limit = rpath + path_max; + + if (name[0] != '/') + { + if (!__getcwd (rpath, path_max)) + { + rpath[0] = '\0'; + goto error; + } + dest = strchr (rpath, '\0'); + } + else + { + rpath[0] = '/'; + dest = rpath + 1; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && name[1] == '/') + *dest++ = '/'; + } + + for (start = end = name; *start; start = end) + { +#ifdef _LIBC + struct stat64 st; +#else + struct stat st; +#endif + int n; + + /* Skip sequence of multiple path-separators. */ + while (*start == '/') + ++start; + + /* Find end of path component. */ + for (end = start; *end && *end != '/'; ++end) + /* Nothing. */; + + if (end - start == 0) + break; + else if (end - start == 1 && start[0] == '.') + /* nothing */; + else if (end - start == 2 && start[0] == '.' && start[1] == '.') + { + /* Back up to previous component, ignore if at root already. */ + if (dest > rpath + 1) + while ((--dest)[-1] != '/'); + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 + && *dest == '/') + dest++; + } + else + { + size_t new_size; + + if (dest[-1] != '/') + *dest++ = '/'; + + if (dest + (end - start) >= rpath_limit) + { + ptrdiff_t dest_offset = dest - rpath; + char *new_rpath; + + if (resolved) + { + __set_errno (ENAMETOOLONG); + if (dest > rpath + 1) + dest--; + *dest = '\0'; + goto error; + } + new_size = rpath_limit - rpath; + if (end - start + 1 > path_max) + new_size += end - start + 1; + else + new_size += path_max; + new_rpath = (char *) realloc (rpath, new_size); + if (new_rpath == NULL) + { + /* It's easier to set errno to ENOMEM than to rely on the + 'realloc-posix' gnulib module. */ + errno = ENOMEM; + goto error; + } + rpath = new_rpath; + rpath_limit = rpath + new_size; + + dest = rpath + dest_offset; + } + +#ifdef _LIBC + dest = __mempcpy (dest, start, end - start); +#else + memcpy (dest, start, end - start); + dest += end - start; +#endif + *dest = '\0'; + +#ifdef _LIBC + if (__lxstat64 (_STAT_VER, rpath, &st) < 0) +#else + if (lstat (rpath, &st) < 0) +#endif + goto error; + + if (S_ISLNK (st.st_mode)) + { + char *buf; + size_t len; + + if (++num_links > MAXSYMLINKS) + { + __set_errno (ELOOP); + goto error; + } + + buf = malloca (path_max); + if (!buf) + { + errno = ENOMEM; + goto error; + } + + n = __readlink (rpath, buf, path_max - 1); + if (n < 0) + { + int saved_errno = errno; + freea (buf); + errno = saved_errno; + goto error; + } + buf[n] = '\0'; + + if (!extra_buf) + { + extra_buf = malloca (path_max); + if (!extra_buf) + { + freea (buf); + errno = ENOMEM; + goto error; + } + } + + len = strlen (end); + if ((long int) (n + len) >= path_max) + { + freea (buf); + __set_errno (ENAMETOOLONG); + goto error; + } + + /* Careful here, end may be a pointer into extra_buf... */ + memmove (&extra_buf[n], end, len + 1); + name = end = memcpy (extra_buf, buf, n); + + if (buf[0] == '/') + { + dest = rpath + 1; /* It's an absolute symlink */ + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && buf[1] == '/') + *dest++ = '/'; + } + else + { + /* Back up to previous component, ignore if at root + already: */ + if (dest > rpath + 1) + while ((--dest)[-1] != '/'); + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 + && *dest == '/') + dest++; + } + } + else if (!S_ISDIR (st.st_mode) && *end != '\0') + { + __set_errno (ENOTDIR); + goto error; + } + } + } + if (dest > rpath + 1 && dest[-1] == '/') + --dest; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 && *dest == '/') + dest++; + *dest = '\0'; + + if (extra_buf) + freea (extra_buf); + + return rpath; + +error: + { + int saved_errno = errno; + if (extra_buf) + freea (extra_buf); + if (resolved == NULL) + free (rpath); + errno = saved_errno; + } + return NULL; +} +versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); +#endif /* !FUNC_REALPATH_WORKS || defined _LIBC */ + + +#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) + +#else + +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; + +#endif diff --git a/gnu/careadlinkat.c b/gnu/careadlinkat.c new file mode 100644 index 00000000..0d31614b --- /dev/null +++ b/gnu/careadlinkat.c @@ -0,0 +1,177 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Read symbolic links into a buffer without size limitation, relative to fd. + + Copyright (C) 2001, 2003-2004, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ + +#include <config.h> + +#include "careadlinkat.h" + +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +/* Define this independently so that stdint.h is not a prerequisite. */ +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + +#ifndef SSIZE_MAX +# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) +#endif + +#include "allocator.h" + +/* Get the symbolic link value of FILENAME and put it into BUFFER, with + size BUFFER_SIZE. This function acts like readlink but has + readlinkat's signature. */ +ssize_t +careadlinkatcwd (int fd, char const *filename, char *buffer, + size_t buffer_size) +{ + /* FD must be AT_FDCWD here, otherwise the caller is using this + function in contexts for which it was not meant for. */ + if (fd != AT_FDCWD) + abort (); + return readlink (filename, buffer, buffer_size); +} + +/* Assuming the current directory is FD, get the symbolic link value + of FILENAME as a null-terminated string and put it into a buffer. + If FD is AT_FDCWD, FILENAME is interpreted relative to the current + working directory, as in openat. + + If the link is small enough to fit into BUFFER put it there. + BUFFER's size is BUFFER_SIZE, and BUFFER can be null + if BUFFER_SIZE is zero. + + If the link is not small, put it into a dynamically allocated + buffer managed by ALLOC. It is the caller's responsibility to free + the returned value if it is nonnull and is not BUFFER. A null + ALLOC stands for the standard allocator. + + The PREADLINKAT function specifies how to read links. It operates + like POSIX readlinkat() + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html> + but can assume that its first argument is the same as FD. + + If successful, return the buffer address; otherwise return NULL and + set errno. */ + +char * +careadlinkat (int fd, char const *filename, + char *buffer, size_t buffer_size, + struct allocator const *alloc, + ssize_t (*preadlinkat) (int, char const *, char *, size_t)) +{ + char *buf; + size_t buf_size; + size_t buf_size_max = + SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; + char stack_buf[1024]; + + if (! alloc) + alloc = &stdlib_allocator; + + if (! buffer_size) + { + /* Allocate the initial buffer on the stack. This way, in the + common case of a symlink of small size, we get away with a + single small malloc() instead of a big malloc() followed by a + shrinking realloc(). */ + buffer = stack_buf; + buffer_size = sizeof stack_buf; + } + + buf = buffer; + buf_size = buffer_size; + + do + { + /* Attempt to read the link into the current buffer. */ + ssize_t link_length = preadlinkat (fd, filename, buf, buf_size); + size_t link_size; + if (link_length < 0) + { + /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1 + with errno == ERANGE if the buffer is too small. */ + int readlinkat_errno = errno; + if (readlinkat_errno != ERANGE) + { + if (buf != buffer) + { + alloc->free (buf); + errno = readlinkat_errno; + } + return NULL; + } + } + + link_size = link_length; + + if (link_size < buf_size) + { + buf[link_size++] = '\0'; + + if (buf == stack_buf) + { + char *b = (char *) alloc->allocate (link_size); + buf_size = link_size; + if (! b) + break; + memcpy (b, buf, link_size); + buf = b; + } + else if (link_size < buf_size && buf != buffer && alloc->reallocate) + { + /* Shrink BUF before returning it. */ + char *b = (char *) alloc->reallocate (buf, link_size); + if (b) + buf = b; + } + + return buf; + } + + if (buf != buffer) + alloc->free (buf); + + if (buf_size <= buf_size_max / 2) + buf_size *= 2; + else if (buf_size < buf_size_max) + buf_size = buf_size_max; + else if (buf_size_max < SIZE_MAX) + { + errno = ENAMETOOLONG; + return NULL; + } + else + break; + buf = (char *) alloc->allocate (buf_size); + } + while (buf); + + if (alloc->die) + alloc->die (buf_size); + errno = ENOMEM; + return NULL; +} diff --git a/gnu/careadlinkat.h b/gnu/careadlinkat.h new file mode 100644 index 00000000..7edd6dbf --- /dev/null +++ b/gnu/careadlinkat.h @@ -0,0 +1,74 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Read symbolic links into a buffer without size limitation, relative to fd. + + Copyright (C) 2011-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ + +#ifndef _GL_CAREADLINKAT_H +#define _GL_CAREADLINKAT_H + +#include <fcntl.h> +#include <unistd.h> + +struct allocator; + +/* Assuming the current directory is FD, get the symbolic link value + of FILENAME as a null-terminated string and put it into a buffer. + If FD is AT_FDCWD, FILENAME is interpreted relative to the current + working directory, as in openat. + + If the link is small enough to fit into BUFFER put it there. + BUFFER's size is BUFFER_SIZE, and BUFFER can be null + if BUFFER_SIZE is zero. + + If the link is not small, put it into a dynamically allocated + buffer managed by ALLOC. It is the caller's responsibility to free + the returned value if it is nonnull and is not BUFFER. + + The PREADLINKAT function specifies how to read links. It operates + like POSIX readlinkat() + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html> + but can assume that its first argument is the same as FD. + + If successful, return the buffer address; otherwise return NULL and + set errno. */ + +char *careadlinkat (int fd, char const *filename, + char *buffer, size_t buffer_size, + struct allocator const *alloc, + ssize_t (*preadlinkat) (int, char const *, + char *, size_t)); + +/* Suitable values for careadlinkat's FD and PREADLINKAT arguments, + when doing a plain readlink: + Pass FD = AT_FDCWD and PREADLINKAT = careadlinkatcwd. */ +#if HAVE_READLINKAT +/* AT_FDCWD is declared in <fcntl.h>. */ +#else +/* Define AT_FDCWD independently, so that the careadlinkat module does + not depend on the fcntl-h module. The value does not matter, since + careadlinkatcwd ignores it, but we might as well use the same value + as fcntl-h. */ +# ifndef AT_FDCWD +# define AT_FDCWD (-3041965) +# endif +#endif +ssize_t careadlinkatcwd (int fd, char const *filename, + char *buffer, size_t buffer_size); + +#endif /* _GL_CAREADLINKAT_H */ diff --git a/gnu/chdir-long.c b/gnu/chdir-long.c new file mode 100644 index 00000000..0517b6c2 --- /dev/null +++ b/gnu/chdir-long.c @@ -0,0 +1,268 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* provide a chdir function that tries not to fail due to ENAMETOOLONG + Copyright (C) 2004-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering */ + +#include <config.h> + +#include "chdir-long.h" + +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <stdio.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 inline void +cdb_init (struct cd_buf *cdb) +{ + cdb->fd = AT_FDCWD; +} + +static inline int +cdb_fchdir (struct cd_buf const *cdb) +{ + return fchdir (cdb->fd); +} + +static inline void +cdb_free (struct cd_buf const *cdb) +{ + if (0 <= cdb->fd) + { + bool close_fail = close (cdb->fd); + assert (! 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 inline 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. */ + assert (0 < len); + assert (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; + } + + assert (*dir != '/'); + assert (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'; + assert (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" + +char *program_name; + +int +main (int argc, char *argv[]) +{ + char *line = NULL; + size_t n = 0; + int len; + + program_name = argv[0]; + 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/gnu/chdir-long.h b/gnu/chdir-long.h new file mode 100644 index 00000000..336811c3 --- /dev/null +++ b/gnu/chdir-long.h @@ -0,0 +1,32 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* provide a chdir function that tries not to fail due to ENAMETOOLONG + Copyright (C) 2004-2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#include <unistd.h> +#include <limits.h> + +#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/gnu/chown.c b/gnu/chown.c new file mode 100644 index 00000000..b75eb5d2 --- /dev/null +++ b/gnu/chown.c @@ -0,0 +1,158 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* provide consistent interface to chown for systems that don't interpret + an ID of -1 as meaning "don't change the corresponding ID". + + Copyright (C) 1997, 2004-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <string.h> +#include <sys/stat.h> + +#if !HAVE_CHOWN + +/* Simple stub that always fails with ENOSYS, for mingw. */ +int +chown (const char *file _GL_UNUSED, uid_t uid _GL_UNUSED, + gid_t gid _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} + +#else /* HAVE_CHOWN */ + +/* Below we refer to the system's chown(). */ +# undef chown + +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +# undef open +# undef close + +/* Provide a more-closely POSIX-conforming version of chown on + systems with one or both of the following problems: + - chown doesn't treat an ID of -1 as meaning + "don't change the corresponding ID". + - chown doesn't dereference symlinks. */ + +int +rpl_chown (const char *file, uid_t uid, gid_t gid) +{ + struct stat st; + bool stat_valid = false; + int result; + +# if CHOWN_CHANGE_TIME_BUG + if (gid != (gid_t) -1 || uid != (uid_t) -1) + { + if (stat (file, &st)) + return -1; + stat_valid = true; + } +# endif + +# if CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE + if (gid == (gid_t) -1 || uid == (uid_t) -1) + { + /* Stat file to get id(s) that should remain unchanged. */ + if (!stat_valid && stat (file, &st)) + return -1; + if (gid == (gid_t) -1) + gid = st.st_gid; + if (uid == (uid_t) -1) + uid = st.st_uid; + } +# endif + +# if CHOWN_MODIFIES_SYMLINK + { + /* Handle the case in which the system-supplied chown function + does *not* follow symlinks. Instead, it changes permissions + on the symlink itself. To work around that, we open the + file (but this can fail due to lack of read or write permission) and + use fchown on the resulting descriptor. */ + int open_flags = O_NONBLOCK | O_NOCTTY; + int fd = open (file, O_RDONLY | open_flags); + if (0 <= fd + || (errno == EACCES + && 0 <= (fd = open (file, O_WRONLY | open_flags)))) + { + int saved_errno; + bool fchown_socket_failure; + + result = fchown (fd, uid, gid); + saved_errno = errno; + + /* POSIX says fchown can fail with errno == EINVAL on sockets + and pipes, so fall back on chown in that case. */ + fchown_socket_failure = + (result != 0 && saved_errno == EINVAL + && fstat (fd, &st) == 0 + && (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode))); + + close (fd); + + if (! fchown_socket_failure) + { + errno = saved_errno; + return result; + } + } + else if (errno != EACCES) + return -1; + } +# endif + +# if CHOWN_TRAILING_SLASH_BUG + if (!stat_valid) + { + size_t len = strlen (file); + if (len && file[len - 1] == '/' && stat (file, &st)) + return -1; + } +# endif + + result = chown (file, uid, gid); + +# if CHOWN_CHANGE_TIME_BUG + if (result == 0 && stat_valid + && (uid == st.st_uid || uid == (uid_t) -1) + && (gid == st.st_gid || gid == (gid_t) -1)) + { + /* No change in ownership, but at least one argument was not -1, + so we are required to update ctime. Since chown succeeded, + we assume that chmod will do likewise. Fortunately, on all + known systems where a 'no-op' chown skips the ctime update, a + 'no-op' chmod still does the trick. */ + result = chmod (file, st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO + | S_ISUID | S_ISGID | S_ISVTX)); + } +# endif + + return result; +} + +#endif /* HAVE_CHOWN */ diff --git a/gnu/cloexec.c b/gnu/cloexec.c new file mode 100644 index 00000000..5fe42bd8 --- /dev/null +++ b/gnu/cloexec.c @@ -0,0 +1,85 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* closexec.c - set or clear the close-on-exec descriptor flag + + Copyright (C) 1991, 2004-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. + + The code is taken from glibc/manual/llio.texi */ + +#include <config.h> + +#include "cloexec.h" + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + +/* 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/gnu/cloexec.h b/gnu/cloexec.h new file mode 100644 index 00000000..91084e50 --- /dev/null +++ b/gnu/cloexec.h @@ -0,0 +1,40 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* closexec.c - set or clear the close-on-exec descriptor flag + + Copyright (C) 2004, 2009-2012 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 <http://www.gnu.org/licenses/>. + +*/ + +#include <stdbool.h> + +/* 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/gnu/close-stream.c b/gnu/close-stream.c new file mode 100644 index 00000000..1ce72afc --- /dev/null +++ b/gnu/close-stream.c @@ -0,0 +1,80 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Close a stream, with nicer error checking than fclose's. + + Copyright (C) 1998-2002, 2004, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "close-stream.h" + +#include <errno.h> +#include <stdbool.h> + +#include "fpending.h" + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +/* Close STREAM. Return 0 if successful, EOF (setting errno) + otherwise. A failure might set errno to 0 if the error number + cannot be determined. + + A failure with errno set to EPIPE may or may not indicate an error + situation worth signaling to the user. See the documentation of the + close_stdout_set_ignore_EPIPE function for details. + + If a program writes *anything* to STREAM, that program should close + STREAM and make sure that it succeeds before exiting. Otherwise, + suppose that you go to the extreme of checking the return status + of every function that does an explicit write to STREAM. The last + printf can succeed in writing to the internal stream buffer, and yet + the fclose(STREAM) could still fail (due e.g., to a disk full error) + when it tries to write out that buffered data. Thus, you would be + left with an incomplete output file and the offending program would + exit successfully. Even calling fflush is not always sufficient, + since some file systems (NFS and CODA) buffer written/flushed data + until an actual close call. + + Besides, it's wasteful to check the return value from every call + that writes to STREAM -- just let the internal stream state record + the failure. That's what the ferror test is checking below. */ + +int +close_stream (FILE *stream) +{ + const bool some_pending = (__fpending (stream) != 0); + const bool prev_fail = (ferror (stream) != 0); + const bool fclose_fail = (fclose (stream) != 0); + + /* Return an error indication if there was a previous failure or if + fclose failed, with one exception: ignore an fclose failure if + there was no previous error, no data remains to be flushed, and + fclose failed with EBADF. That can happen when a program like cp + is invoked like this 'cp a b >&-' (i.e., with standard output + closed) and doesn't generate any output (hence no previous error + and nothing to be flushed). */ + + if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) + { + if (! fclose_fail) + errno = 0; + return EOF; + } + + return 0; +} diff --git a/gnu/close-stream.h b/gnu/close-stream.h new file mode 100644 index 00000000..d8cad179 --- /dev/null +++ b/gnu/close-stream.h @@ -0,0 +1,4 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#include <stdio.h> +int close_stream (FILE *stream); diff --git a/gnu/close.c b/gnu/close.c new file mode 100644 index 00000000..4ad947c3 --- /dev/null +++ b/gnu/close.c @@ -0,0 +1,71 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* close replacement. + Copyright (C) 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#include <errno.h> + +#include "fd-hook.h" +#include "msvc-inval.h" + +#undef close + +#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 + +/* 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/gnu/closedir.c b/gnu/closedir.c new file mode 100644 index 00000000..999240d1 --- /dev/null +++ b/gnu/closedir.c @@ -0,0 +1,69 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Stop reading the entries of a directory. + Copyright (C) 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <dirent.h> + +#if REPLACE_FCHDIR +# include <unistd.h> +#endif + +#if HAVE_CLOSEDIR + +/* Override closedir(), to keep track of the open file descriptors. + Needed because there is a function dirfd(). */ + +#else + +# include <stdlib.h> + +# include "dirent-private.h" + +#endif + +int +closedir (DIR *dirp) +{ +# if REPLACE_FCHDIR + int fd = dirfd (dirp); +# endif + int retval; + +#if HAVE_CLOSEDIR +# undef closedir + + retval = closedir (dirp); + +#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/gnu/closeout.c b/gnu/closeout.c new file mode 100644 index 00000000..835820f9 --- /dev/null +++ b/gnu/closeout.c @@ -0,0 +1,126 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Close standard output and standard error, exiting with a diagnostic on error. + + Copyright (C) 1998-2002, 2004, 2006, 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "closeout.h" + +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <unistd.h> + +#include "gettext.h" +#define _(msgid) gettext (msgid) + +#include "close-stream.h" +#include "error.h" +#include "exitfail.h" +#include "quotearg.h" + +static const char *file_name; + +/* Set the file name to be reported in the event an error is detected + by close_stdout. */ +void +close_stdout_set_file_name (const char *file) +{ + file_name = file; +} + +static bool ignore_EPIPE /* = false */; + +/* Specify the reaction to an EPIPE error during the closing of stdout: + - If ignore = true, it shall be ignored. + - If ignore = false, it shall evoke a diagnostic, along with a nonzero + exit status. + The default is ignore = false. + + This setting matters only if the SIGPIPE signal is ignored (i.e. its + handler set to SIG_IGN) or blocked. Only particular programs need to + temporarily ignore SIGPIPE. If SIGPIPE is ignored or blocked because + it was ignored or blocked in the parent process when it created the + child process, it usually is a bug in the parent process: It is bad + practice to have SIGPIPE ignored or blocked while creating a child + process. + + EPIPE occurs when writing to a pipe or socket that has no readers now, + when SIGPIPE is ignored or blocked. + + The ignore = false setting is suitable for a scenario where it is normally + guaranteed that the pipe writer terminates before the pipe reader. In + this case, an EPIPE is an indication of a premature termination of the + pipe reader and should lead to a diagnostic and a nonzero exit status. + + The ignore = true setting is suitable for a scenario where you don't know + ahead of time whether the pipe writer or the pipe reader will terminate + first. In this case, an EPIPE is an indication that the pipe writer can + stop doing useless write() calls; this is what close_stdout does anyway. + EPIPE is part of the normal pipe/socket shutdown protocol in this case, + and should not lead to a diagnostic message. */ + +void +close_stdout_set_ignore_EPIPE (bool ignore) +{ + ignore_EPIPE = ignore; +} + +/* Close standard output. On error, issue a diagnostic and _exit + with status 'exit_failure'. + + Also close standard error. On error, _exit with status 'exit_failure'. + + Since close_stdout is commonly registered via 'atexit', POSIX + and the C standard both say that it should not call 'exit', + because the behavior is undefined if 'exit' is called more than + once. So it calls '_exit' instead of 'exit'. If close_stdout + is registered via atexit before other functions are registered, + the other functions can act before this _exit is invoked. + + Applications that use close_stdout should flush any streams + other than stdout and stderr before exiting, since the call to + _exit will bypass other buffer flushing. Applications should + be flushing and closing other streams anyway, to check for I/O + errors. Also, applications should not use tmpfile, since _exit + can bypass the removal of these files. + + It's important to detect such failures and exit nonzero because many + tools (most notably 'make' and other build-management systems) depend + on being able to detect failure in other tools via their exit status. */ + +void +close_stdout (void) +{ + if (close_stream (stdout) != 0 + && !(ignore_EPIPE && errno == EPIPE)) + { + char const *write_error = _("write error"); + if (file_name) + error (0, errno, "%s: %s", quotearg_colon (file_name), + write_error); + else + error (0, errno, "%s", write_error); + + _exit (exit_failure); + } + + if (close_stream (stderr) != 0) + _exit (exit_failure); +} diff --git a/gnu/closeout.h b/gnu/closeout.h new file mode 100644 index 00000000..ffeb5e20 --- /dev/null +++ b/gnu/closeout.h @@ -0,0 +1,38 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Close standard output and standard error. + + Copyright (C) 1998, 2000, 2003-2004, 2006, 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef CLOSEOUT_H +# define CLOSEOUT_H 1 + +# include <stdbool.h> + +# ifdef __cplusplus +extern "C" { +# endif + +void close_stdout_set_file_name (const char *file); +void close_stdout_set_ignore_EPIPE (bool ignore); +void close_stdout (void); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/gnu/config.charset b/gnu/config.charset new file mode 100644 index 00000000..1383d9b4 --- /dev/null +++ b/gnu/config.charset @@ -0,0 +1,685 @@ +#! /bin/sh +# Output a system dependent table of character encoding aliases. +# +# Copyright (C) 2000-2004, 2006-2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The table consists of lines of the form +# ALIAS CANONICAL +# +# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". +# ALIAS is compared in a case sensitive way. +# +# CANONICAL is the GNU canonical name for this character encoding. +# It must be an encoding supported by libiconv. Support by GNU libc is +# also desirable. CANONICAL is case insensitive. Usually an upper case +# MIME charset name is preferred. +# The current list of GNU canonical charset names is as follows. +# +# name MIME? used by which systems +# (darwin = MacOS X, woe32 = native Windows) +# +# ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin cygwin +# ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +# ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +# ISO-8859-3 Y glibc solaris cygwin +# ISO-8859-4 Y osf solaris freebsd netbsd openbsd darwin +# ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +# ISO-8859-6 Y glibc aix hpux solaris cygwin +# ISO-8859-7 Y glibc aix hpux irix osf solaris netbsd openbsd darwin cygwin +# ISO-8859-8 Y glibc aix hpux osf solaris cygwin +# ISO-8859-9 Y glibc aix hpux irix osf solaris darwin cygwin +# ISO-8859-13 glibc netbsd openbsd darwin cygwin +# ISO-8859-14 glibc cygwin +# ISO-8859-15 glibc aix osf solaris freebsd netbsd openbsd darwin cygwin +# KOI8-R Y glibc solaris freebsd netbsd openbsd darwin +# KOI8-U Y glibc freebsd netbsd openbsd darwin cygwin +# KOI8-T glibc +# CP437 dos +# CP775 dos +# CP850 aix osf dos +# CP852 dos +# CP855 dos +# CP856 aix +# CP857 dos +# CP861 dos +# CP862 dos +# CP864 dos +# CP865 dos +# CP866 freebsd netbsd openbsd darwin dos +# CP869 dos +# CP874 woe32 dos +# CP922 aix +# CP932 aix cygwin woe32 dos +# CP943 aix +# CP949 osf darwin woe32 dos +# CP950 woe32 dos +# CP1046 aix +# CP1124 aix +# CP1125 dos +# CP1129 aix +# CP1131 darwin +# CP1250 woe32 +# CP1251 glibc solaris netbsd openbsd darwin cygwin woe32 +# CP1252 aix woe32 +# CP1253 woe32 +# CP1254 woe32 +# CP1255 glibc woe32 +# CP1256 woe32 +# CP1257 woe32 +# GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin +# EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin +# EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin +# EUC-TW glibc aix hpux irix osf solaris netbsd +# BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin cygwin +# BIG5-HKSCS glibc solaris darwin +# GBK glibc aix osf solaris darwin cygwin woe32 dos +# GB18030 glibc solaris netbsd darwin +# SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin +# JOHAB glibc solaris woe32 +# TIS-620 glibc aix hpux osf solaris cygwin +# VISCII Y glibc +# TCVN5712-1 glibc +# ARMSCII-8 glibc darwin +# GEORGIAN-PS glibc cygwin +# PT154 glibc +# HP-ROMAN8 hpux +# HP-ARABIC8 hpux +# HP-GREEK8 hpux +# HP-HEBREW8 hpux +# HP-TURKISH8 hpux +# HP-KANA8 hpux +# DEC-KANJI osf +# DEC-HANYU osf +# UTF-8 Y glibc aix hpux osf solaris netbsd darwin cygwin +# +# Note: Names which are not marked as being a MIME name should not be used in +# Internet protocols for information interchange (mail, news, etc.). +# +# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications +# must understand both names and treat them as equivalent. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM + +host="$1" +os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` +echo "# This file contains a table of character encoding aliases," +echo "# suitable for operating system '${os}'." +echo "# It was automatically generated from config.charset." +# List of references, updated during installation: +echo "# Packages using this file: " +case "$os" in + linux-gnulibc1*) + # Linux libc5 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "C ASCII" + echo "POSIX ASCII" + for l in af af_ZA ca ca_ES da da_DK de de_AT de_BE de_CH de_DE de_LU \ + en en_AU en_BW en_CA en_DK en_GB en_IE en_NZ en_US en_ZA \ + en_ZW es es_AR es_BO es_CL es_CO es_DO es_EC es_ES es_GT \ + es_HN es_MX es_PA es_PE es_PY es_SV es_US es_UY es_VE et \ + et_EE eu eu_ES fi fi_FI fo fo_FO fr fr_BE fr_CA fr_CH fr_FR \ + fr_LU ga ga_IE gl gl_ES id id_ID in in_ID is is_IS it it_CH \ + it_IT kl kl_GL nl nl_BE nl_NL no no_NO pt pt_BR pt_PT sv \ + sv_FI sv_SE; do + echo "$l ISO-8859-1" + echo "$l.iso-8859-1 ISO-8859-1" + echo "$l.iso-8859-15 ISO-8859-15" + echo "$l.iso-8859-15@euro ISO-8859-15" + echo "$l@euro ISO-8859-15" + echo "$l.cp-437 CP437" + echo "$l.cp-850 CP850" + echo "$l.cp-1252 CP1252" + echo "$l.cp-1252@euro CP1252" + #echo "$l.atari-st ATARI-ST" # not a commonly used encoding + echo "$l.utf-8 UTF-8" + echo "$l.utf-8@euro UTF-8" + done + for l in cs cs_CZ hr hr_HR hu hu_HU pl pl_PL ro ro_RO sk sk_SK sl \ + sl_SI sr sr_CS sr_YU; do + echo "$l ISO-8859-2" + echo "$l.iso-8859-2 ISO-8859-2" + echo "$l.cp-852 CP852" + echo "$l.cp-1250 CP1250" + echo "$l.utf-8 UTF-8" + done + for l in mk mk_MK ru ru_RU; do + echo "$l ISO-8859-5" + echo "$l.iso-8859-5 ISO-8859-5" + echo "$l.koi8-r KOI8-R" + echo "$l.cp-866 CP866" + echo "$l.cp-1251 CP1251" + echo "$l.utf-8 UTF-8" + done + for l in ar ar_SA; do + echo "$l ISO-8859-6" + echo "$l.iso-8859-6 ISO-8859-6" + echo "$l.cp-864 CP864" + #echo "$l.cp-868 CP868" # not a commonly used encoding + echo "$l.cp-1256 CP1256" + echo "$l.utf-8 UTF-8" + done + for l in el el_GR gr gr_GR; do + echo "$l ISO-8859-7" + echo "$l.iso-8859-7 ISO-8859-7" + echo "$l.cp-869 CP869" + echo "$l.cp-1253 CP1253" + echo "$l.cp-1253@euro CP1253" + echo "$l.utf-8 UTF-8" + echo "$l.utf-8@euro UTF-8" + done + for l in he he_IL iw iw_IL; do + echo "$l ISO-8859-8" + echo "$l.iso-8859-8 ISO-8859-8" + echo "$l.cp-862 CP862" + echo "$l.cp-1255 CP1255" + echo "$l.utf-8 UTF-8" + done + for l in tr tr_TR; do + echo "$l ISO-8859-9" + echo "$l.iso-8859-9 ISO-8859-9" + echo "$l.cp-857 CP857" + echo "$l.cp-1254 CP1254" + echo "$l.utf-8 UTF-8" + done + for l in lt lt_LT lv lv_LV; do + #echo "$l BALTIC" # not a commonly used encoding, wrong encoding name + echo "$l ISO-8859-13" + done + for l in ru_UA uk uk_UA; do + echo "$l KOI8-U" + done + for l in zh zh_CN; do + #echo "$l GB_2312-80" # not a commonly used encoding, wrong encoding name + echo "$l GB2312" + done + for l in ja ja_JP ja_JP.EUC; do + echo "$l EUC-JP" + done + for l in ko ko_KR; do + echo "$l EUC-KR" + done + for l in th th_TH; do + echo "$l TIS-620" + done + for l in fa fa_IR; do + #echo "$l ISIRI-3342" # a broken encoding + echo "$l.utf-8 UTF-8" + done + ;; + linux* | *-gnu*) + # With glibc-2.1 or newer, we don't need any canonicalization, + # because glibc has iconv and both glibc and libiconv support all + # GNU canonical names directly. Therefore, the Makefile does not + # need to install the alias file at all. + # The following applies only to glibc-2.0.x and older libcs. + echo "ISO_646.IRV:1983 ASCII" + ;; + aix*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-6 ISO-8859-6" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "IBM-850 CP850" + echo "IBM-856 CP856" + echo "IBM-921 ISO-8859-13" + echo "IBM-922 CP922" + echo "IBM-932 CP932" + echo "IBM-943 CP943" + echo "IBM-1046 CP1046" + echo "IBM-1124 CP1124" + echo "IBM-1129 CP1129" + echo "IBM-1252 CP1252" + echo "IBM-eucCN GB2312" + echo "IBM-eucJP EUC-JP" + echo "IBM-eucKR EUC-KR" + echo "IBM-eucTW EUC-TW" + echo "big5 BIG5" + echo "GBK GBK" + echo "TIS-620 TIS-620" + echo "UTF-8 UTF-8" + ;; + hpux*) + echo "iso88591 ISO-8859-1" + echo "iso88592 ISO-8859-2" + echo "iso88595 ISO-8859-5" + echo "iso88596 ISO-8859-6" + echo "iso88597 ISO-8859-7" + echo "iso88598 ISO-8859-8" + echo "iso88599 ISO-8859-9" + echo "iso885915 ISO-8859-15" + echo "roman8 HP-ROMAN8" + echo "arabic8 HP-ARABIC8" + echo "greek8 HP-GREEK8" + echo "hebrew8 HP-HEBREW8" + echo "turkish8 HP-TURKISH8" + echo "kana8 HP-KANA8" + echo "tis620 TIS-620" + echo "big5 BIG5" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "hp15CN GB2312" + #echo "ccdc ?" # what is this? + echo "SJIS SHIFT_JIS" + echo "utf8 UTF-8" + ;; + irix*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-9 ISO-8859-9" + echo "eucCN GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + ;; + osf*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "cp850 CP850" + echo "big5 BIG5" + echo "dechanyu DEC-HANYU" + echo "dechanzi GB2312" + echo "deckanji DEC-KANJI" + echo "deckorean EUC-KR" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "GBK GBK" + echo "KSC5601 CP949" + echo "sdeckanji EUC-JP" + echo "SJIS SHIFT_JIS" + echo "TACTIS TIS-620" + echo "UTF-8 UTF-8" + ;; + solaris*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-3 ISO-8859-3" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-6 ISO-8859-6" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "koi8-r KOI8-R" + echo "ansi-1251 CP1251" + echo "BIG5 BIG5" + echo "Big5-HKSCS BIG5-HKSCS" + echo "gb2312 GB2312" + echo "GBK GBK" + echo "GB18030 GB18030" + echo "cns11643 EUC-TW" + echo "5601 EUC-KR" + echo "ko_KR.johap92 JOHAB" + echo "eucJP EUC-JP" + echo "PCK SHIFT_JIS" + echo "TIS620.2533 TIS-620" + #echo "sun_eu_greek ?" # what is this? + echo "UTF-8 UTF-8" + ;; + freebsd* | os2*) + # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just + # reuse FreeBSD's locale data for OS/2. + echo "C ASCII" + echo "US-ASCII ASCII" + for l in la_LN lt_LN; do + echo "$l.ASCII ASCII" + done + for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ + fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ + lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do + echo "$l.ISO_8859-1 ISO-8859-1" + echo "$l.DIS_8859-15 ISO-8859-15" + done + for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do + echo "$l.ISO_8859-2 ISO-8859-2" + done + for l in la_LN lt_LT; do + echo "$l.ISO_8859-4 ISO-8859-4" + done + for l in ru_RU ru_SU; do + echo "$l.KOI8-R KOI8-R" + echo "$l.ISO_8859-5 ISO-8859-5" + echo "$l.CP866 CP866" + done + echo "uk_UA.KOI8-U KOI8-U" + echo "zh_TW.BIG5 BIG5" + echo "zh_TW.Big5 BIG5" + echo "zh_CN.EUC GB2312" + echo "ja_JP.EUC EUC-JP" + echo "ja_JP.SJIS SHIFT_JIS" + echo "ja_JP.Shift_JIS SHIFT_JIS" + echo "ko_KR.EUC EUC-KR" + ;; + netbsd*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-13 ISO-8859-13" + echo "ISO8859-15 ISO-8859-15" + echo "eucCN GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "BIG5 BIG5" + echo "SJIS SHIFT_JIS" + ;; + openbsd*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-13 ISO-8859-13" + echo "ISO8859-15 ISO-8859-15" + ;; + darwin[56]*) + # Darwin 6.8 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "C ASCII" + for l in en_AU en_CA en_GB en_US la_LN; do + echo "$l.US-ASCII ASCII" + done + for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ + fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT nl_BE \ + nl_NL no_NO pt_PT sv_SE; do + echo "$l ISO-8859-1" + echo "$l.ISO8859-1 ISO-8859-1" + echo "$l.ISO8859-15 ISO-8859-15" + done + for l in la_LN; do + echo "$l.ISO8859-1 ISO-8859-1" + echo "$l.ISO8859-15 ISO-8859-15" + done + for l in cs_CZ hr_HR hu_HU la_LN pl_PL sl_SI; do + echo "$l.ISO8859-2 ISO-8859-2" + done + for l in la_LN lt_LT; do + echo "$l.ISO8859-4 ISO-8859-4" + done + for l in ru_RU; do + echo "$l.KOI8-R KOI8-R" + echo "$l.ISO8859-5 ISO-8859-5" + echo "$l.CP866 CP866" + done + for l in bg_BG; do + echo "$l.CP1251 CP1251" + done + echo "uk_UA.KOI8-U KOI8-U" + echo "zh_TW.BIG5 BIG5" + echo "zh_TW.Big5 BIG5" + echo "zh_CN.EUC GB2312" + echo "ja_JP.EUC EUC-JP" + echo "ja_JP.SJIS SHIFT_JIS" + echo "ko_KR.EUC EUC-KR" + ;; + darwin*) + # Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is + # useless: + # - It returns the empty string when LANG is set to a locale of the + # form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8 + # LC_CTYPE file. + # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by + # the system; nl_langinfo(CODESET) returns "US-ASCII" in this case. + # - The documentation says: + # "... all code that calls BSD system routines should ensure + # that the const *char parameters of these routines are in UTF-8 + # encoding. All BSD system functions expect their string + # parameters to be in UTF-8 encoding and nothing else." + # It also says + # "An additional caveat is that string parameters for files, + # paths, and other file-system entities must be in canonical + # UTF-8. In a canonical UTF-8 Unicode string, all decomposable + # characters are decomposed ..." + # but this is not true: You can pass non-decomposed UTF-8 strings + # to file system functions, and it is the OS which will convert + # them to decomposed UTF-8 before accessing the file system. + # - The Apple Terminal application displays UTF-8 by default. + # - However, other applications are free to use different encodings: + # - xterm uses ISO-8859-1 by default. + # - TextEdit uses MacRoman by default. + # We prefer UTF-8 over decomposed UTF-8-MAC because one should + # minimize the use of decomposed Unicode. Unfortunately, through the + # Darwin file system, decomposed UTF-8 strings are leaked into user + # space nevertheless. + # Then there are also the locales with encodings other than US-ASCII + # and UTF-8. These locales can be occasionally useful to users (e.g. + # when grepping through ISO-8859-1 encoded text files), when all their + # file names are in US-ASCII. + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-13 ISO-8859-13" + echo "ISO8859-15 ISO-8859-15" + echo "KOI8-R KOI8-R" + echo "KOI8-U KOI8-U" + echo "CP866 CP866" + echo "CP949 CP949" + echo "CP1131 CP1131" + echo "CP1251 CP1251" + echo "eucCN GB2312" + echo "GB2312 GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "Big5 BIG5" + echo "Big5HKSCS BIG5-HKSCS" + echo "GBK GBK" + echo "GB18030 GB18030" + echo "SJIS SHIFT_JIS" + echo "ARMSCII-8 ARMSCII-8" + echo "PT154 PT154" + #echo "ISCII-DEV ?" + echo "* UTF-8" + ;; + beos* | haiku*) + # BeOS and Haiku have a single locale, and it has UTF-8 encoding. + echo "* UTF-8" + ;; + msdosdjgpp*) + # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "#" + echo "# The encodings given here may not all be correct." + echo "# If you find that the encoding given for your language and" + echo "# country is not the one your DOS machine actually uses, just" + echo "# correct it in this file, and send a mail to" + echo "# Juan Manuel Guerrero <juan.guerrero@gmx.de>" + echo "# and Bruno Haible <bruno@clisp.org>." + echo "#" + echo "C ASCII" + # ISO-8859-1 languages + echo "ca CP850" + echo "ca_ES CP850" + echo "da CP865" # not CP850 ?? + echo "da_DK CP865" # not CP850 ?? + echo "de CP850" + echo "de_AT CP850" + echo "de_CH CP850" + echo "de_DE CP850" + echo "en CP850" + echo "en_AU CP850" # not CP437 ?? + echo "en_CA CP850" + echo "en_GB CP850" + echo "en_NZ CP437" + echo "en_US CP437" + echo "en_ZA CP850" # not CP437 ?? + echo "es CP850" + echo "es_AR CP850" + echo "es_BO CP850" + echo "es_CL CP850" + echo "es_CO CP850" + echo "es_CR CP850" + echo "es_CU CP850" + echo "es_DO CP850" + echo "es_EC CP850" + echo "es_ES CP850" + echo "es_GT CP850" + echo "es_HN CP850" + echo "es_MX CP850" + echo "es_NI CP850" + echo "es_PA CP850" + echo "es_PY CP850" + echo "es_PE CP850" + echo "es_SV CP850" + echo "es_UY CP850" + echo "es_VE CP850" + echo "et CP850" + echo "et_EE CP850" + echo "eu CP850" + echo "eu_ES CP850" + echo "fi CP850" + echo "fi_FI CP850" + echo "fr CP850" + echo "fr_BE CP850" + echo "fr_CA CP850" + echo "fr_CH CP850" + echo "fr_FR CP850" + echo "ga CP850" + echo "ga_IE CP850" + echo "gd CP850" + echo "gd_GB CP850" + echo "gl CP850" + echo "gl_ES CP850" + echo "id CP850" # not CP437 ?? + echo "id_ID CP850" # not CP437 ?? + echo "is CP861" # not CP850 ?? + echo "is_IS CP861" # not CP850 ?? + echo "it CP850" + echo "it_CH CP850" + echo "it_IT CP850" + echo "lt CP775" + echo "lt_LT CP775" + echo "lv CP775" + echo "lv_LV CP775" + echo "nb CP865" # not CP850 ?? + echo "nb_NO CP865" # not CP850 ?? + echo "nl CP850" + echo "nl_BE CP850" + echo "nl_NL CP850" + echo "nn CP865" # not CP850 ?? + echo "nn_NO CP865" # not CP850 ?? + echo "no CP865" # not CP850 ?? + echo "no_NO CP865" # not CP850 ?? + echo "pt CP850" + echo "pt_BR CP850" + echo "pt_PT CP850" + echo "sv CP850" + echo "sv_SE CP850" + # ISO-8859-2 languages + echo "cs CP852" + echo "cs_CZ CP852" + echo "hr CP852" + echo "hr_HR CP852" + echo "hu CP852" + echo "hu_HU CP852" + echo "pl CP852" + echo "pl_PL CP852" + echo "ro CP852" + echo "ro_RO CP852" + echo "sk CP852" + echo "sk_SK CP852" + echo "sl CP852" + echo "sl_SI CP852" + echo "sq CP852" + echo "sq_AL CP852" + echo "sr CP852" # CP852 or CP866 or CP855 ?? + echo "sr_CS CP852" # CP852 or CP866 or CP855 ?? + echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? + # ISO-8859-3 languages + echo "mt CP850" + echo "mt_MT CP850" + # ISO-8859-5 languages + echo "be CP866" + echo "be_BE CP866" + echo "bg CP866" # not CP855 ?? + echo "bg_BG CP866" # not CP855 ?? + echo "mk CP866" # not CP855 ?? + echo "mk_MK CP866" # not CP855 ?? + echo "ru CP866" + echo "ru_RU CP866" + echo "uk CP1125" + echo "uk_UA CP1125" + # ISO-8859-6 languages + echo "ar CP864" + echo "ar_AE CP864" + echo "ar_DZ CP864" + echo "ar_EG CP864" + echo "ar_IQ CP864" + echo "ar_IR CP864" + echo "ar_JO CP864" + echo "ar_KW CP864" + echo "ar_MA CP864" + echo "ar_OM CP864" + echo "ar_QA CP864" + echo "ar_SA CP864" + echo "ar_SY CP864" + # ISO-8859-7 languages + echo "el CP869" + echo "el_GR CP869" + # ISO-8859-8 languages + echo "he CP862" + echo "he_IL CP862" + # ISO-8859-9 languages + echo "tr CP857" + echo "tr_TR CP857" + # Japanese + echo "ja CP932" + echo "ja_JP CP932" + # Chinese + echo "zh_CN GBK" + echo "zh_TW CP950" # not CP938 ?? + # Korean + echo "kr CP949" # not CP934 ?? + echo "kr_KR CP949" # not CP934 ?? + # Thai + echo "th CP874" + echo "th_TH CP874" + # Other + echo "eo CP850" + echo "eo_EO CP850" + ;; +esac diff --git a/gnu/dirent--.h b/gnu/dirent--.h new file mode 100644 index 00000000..42941f6d --- /dev/null +++ b/gnu/dirent--.h @@ -0,0 +1,25 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Like dirent.h, but redefine some names to avoid glitches. + + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Eric Blake. */ + +#include "dirent-safer.h" + +#undef opendir +#define opendir opendir_safer diff --git a/gnu/dirent-private.h b/gnu/dirent-private.h new file mode 100644 index 00000000..44f8d142 --- /dev/null +++ b/gnu/dirent-private.h @@ -0,0 +1,42 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Private details of the DIR type. + Copyright (C) 2011-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _DIRENT_PRIVATE_H +#define _DIRENT_PRIVATE_H 1 + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +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/gnu/dirent-safer.h b/gnu/dirent-safer.h new file mode 100644 index 00000000..91d1d501 --- /dev/null +++ b/gnu/dirent-safer.h @@ -0,0 +1,24 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Invoke dirent-like functions, but avoid some glitches. + + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Eric Blake. */ + +#include <dirent.h> + +DIR *opendir_safer (const char *name); diff --git a/gnu/dirent.in.h b/gnu/dirent.in.h new file mode 100644 index 00000000..a06130f0 --- /dev/null +++ b/gnu/dirent.in.h @@ -0,0 +1,251 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A GNU-like <dirent.h>. + Copyright (C) 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#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 <sys/types.h> + +#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 + +/* 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_OPENDIR@ +# if @REPLACE_OPENDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef opendir +# define opendir rpl_opendir +# endif +_GL_FUNCDECL_RPL (opendir, DIR *, (const char *dir_name) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (opendir, DIR *, (const char *dir_name)); +# else +# if !@HAVE_OPENDIR@ +_GL_FUNCDECL_SYS (opendir, DIR *, (const char *dir_name) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (opendir, DIR *, (const char *dir_name)); +# endif +_GL_CXXALIASWARN (opendir); +#elif 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 + +#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_CLOSEDIR@ +# if @REPLACE_CLOSEDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef closedir +# define closedir rpl_closedir +# 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_DIRFD@ +/* Return the file descriptor associated with the given directory stream, + or -1 if none exists. */ +# if @REPLACE_DIRFD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef dirfd +# define dirfd rpl_dirfd +# endif +_GL_FUNCDECL_RPL (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (dirfd, int, (DIR *)); +# 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_CXXALIAS_RPL (fdopendir, DIR *, (int fd)); +# else +# if !@HAVE_FDOPENDIR@ || !@HAVE_DECL_FDOPENDIR@ +_GL_FUNCDECL_SYS (fdopendir, DIR *, (int fd)); +# endif +_GL_CXXALIAS_SYS (fdopendir, DIR *, (int fd)); +# endif +_GL_CXXALIASWARN (fdopendir); +#elif 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 + +#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_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/gnu/dirfd.c b/gnu/dirfd.c new file mode 100644 index 00000000..9b37b7b5 --- /dev/null +++ b/gnu/dirfd.c @@ -0,0 +1,34 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* dirfd.c -- return the file descriptor associated with an open DIR* + + Copyright (C) 2001, 2006, 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#include <config.h> + +#include <dirent.h> +#include <errno.h> + +int +dirfd (DIR *dir_p) +{ + int fd = DIR_TO_FD (dir_p); + if (fd == -1) + errno = ENOTSUP; + return fd; +} diff --git a/gnu/dirname-lgpl.c b/gnu/dirname-lgpl.c new file mode 100644 index 00000000..f2dac633 --- /dev/null +++ b/gnu/dirname-lgpl.c @@ -0,0 +1,88 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* dirname.c -- return all but the last element in a file name + + Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "dirname.h" + +#include <stdlib.h> +#include <string.h> + +/* 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/gnu/dirname.c b/gnu/dirname.c new file mode 100644 index 00000000..f99a7d21 --- /dev/null +++ b/gnu/dirname.c @@ -0,0 +1,40 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* dirname.c -- return all but the last element in a file name + + Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "dirname.h" + +#include <stdlib.h> +#include <string.h> +#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/gnu/dirname.h b/gnu/dirname.h new file mode 100644 index 00000000..ee44a204 --- /dev/null +++ b/gnu/dirname.h @@ -0,0 +1,48 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Take file names apart into directory and base names. + + Copyright (C) 1998, 2001, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef DIRNAME_H_ +# define DIRNAME_H_ 1 + +# include <stdbool.h> +# include <stddef.h> +# include "dosname.h" + +# ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +# endif + +# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT +# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 +# endif + +# if GNULIB_DIRNAME +char *base_name (char const *file); +char *dir_name (char const *file); +# endif + +char *mdir_name (char const *file); +size_t base_len (char const *file) _GL_ATTRIBUTE_PURE; +size_t dir_len (char const *file) _GL_ATTRIBUTE_PURE; +char *last_component (char const *file) _GL_ATTRIBUTE_PURE; + +bool strip_trailing_slashes (char *file); + +#endif /* not DIRNAME_H_ */ diff --git a/gnu/dosname.h b/gnu/dosname.h new file mode 100644 index 00000000..f28f0ba5 --- /dev/null +++ b/gnu/dosname.h @@ -0,0 +1,55 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* File names on MS-DOS/Windows systems. + + Copyright (C) 2000-2001, 2004-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. + + From Paul Eggert and Jim Meyering. */ + +#ifndef _DOSNAME_H +#define _DOSNAME_H + +#if (defined _WIN32 || defined __WIN32__ || \ + defined __MSDOS__ || defined __CYGWIN__ || \ + defined __EMX__ || defined __DJGPP__) + /* This internal macro assumes ASCII, but all hosts that support drive + letters use ASCII. */ +# define _IS_DRIVE_LETTER(C) (((unsigned int) (C) | ('a' - 'A')) - 'a' \ + <= 'z' - 'a') +# define FILE_SYSTEM_PREFIX_LEN(Filename) \ + (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0) +# ifndef __CYGWIN__ +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1 +# endif +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +#else +# define FILE_SYSTEM_PREFIX_LEN(Filename) 0 +# define ISSLASH(C) ((C) == '/') +#endif + +#ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 +#endif + +#if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE +# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) +# else +# define IS_ABSOLUTE_FILE_NAME(F) \ + (ISSLASH ((F)[0]) || FILE_SYSTEM_PREFIX_LEN (F) != 0) +#endif +#define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) + +#endif /* DOSNAME_H_ */ diff --git a/gnu/dup-safer.c b/gnu/dup-safer.c new file mode 100644 index 00000000..9752637b --- /dev/null +++ b/gnu/dup-safer.c @@ -0,0 +1,36 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Invoke dup, but avoid some glitches. + + Copyright (C) 2001, 2004-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +#include "unistd-safer.h" + +#include <fcntl.h> +#include <unistd.h> + +/* 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/gnu/dup.c b/gnu/dup.c new file mode 100644 index 00000000..797c7966 --- /dev/null +++ b/gnu/dup.c @@ -0,0 +1,63 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Duplicate an open file descriptor. + + Copyright (C) 2011-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#include <errno.h> + +#include "msvc-inval.h" + +#undef dup + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static inline 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 + +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/gnu/dup2.c b/gnu/dup2.c new file mode 100644 index 00000000..372e5061 --- /dev/null +++ b/gnu/dup2.c @@ -0,0 +1,159 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Duplicate an open file descriptor to a specified file descriptor. + + Copyright (C) 1999, 2004-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Paul Eggert */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#include <errno.h> +#include <fcntl.h> + +#if HAVE_DUP2 + +# undef dup2 + +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +/* Get declarations of the native Windows API functions. */ +# define WIN32_LEAN_AND_MEAN +# include <windows.h> + +# include "msvc-inval.h" + +/* Get _get_osfhandle. */ +# include "msvc-nothrow.h" + +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: + http://bugs.winehq.org/show_bug.cgi?id=21289 */ + if (desired_fd < 0) + { + errno = EBADF; + return -1; + } + + TRY_MSVC_INVAL + { + result = dup2 (fd, desired_fd); + } + CATCH_MSVC_INVAL + { + errno = EBADF; + result = -1; + } + DONE_MSVC_INVAL; + + if (result == 0) + result = desired_fd; + + return result; +} + +# define dup2 ms_windows_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 Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC. */ + 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; +} + +#else /* !HAVE_DUP2 */ + +/* On older platforms, dup2 did not exist. */ + +# ifndef F_DUPFD +static int +dupfd (int fd, int desired_fd) +{ + int duplicated_fd = dup (fd); + if (duplicated_fd < 0 || duplicated_fd == desired_fd) + return duplicated_fd; + else + { + int r = dupfd (fd, desired_fd); + int e = errno; + close (duplicated_fd); + errno = e; + return r; + } +} +# endif + +int +dup2 (int fd, int desired_fd) +{ + int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd; + if (result == -1 || fd == desired_fd) + return result; + close (desired_fd); +# ifdef F_DUPFD + result = fcntl (fd, F_DUPFD, desired_fd); +# if REPLACE_FCHDIR + if (0 <= result) + result = _gl_register_dup (fd, result); +# endif +# else + result = dupfd (fd, desired_fd); +# endif + if (result == -1 && (errno == EMFILE || errno == EINVAL)) + errno = EBADF; + return result; +} +#endif /* !HAVE_DUP2 */ diff --git a/gnu/errno.in.h b/gnu/errno.in.h new file mode 100644 index 00000000..275491a3 --- /dev/null +++ b/gnu/errno.in.h @@ -0,0 +1,235 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A POSIX-like <errno.h>. + + Copyright (C) 2008-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#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 __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 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 ETXTBSY 139 +# define ENODATA 120 /* not required by POSIX */ +# define ENOSR 124 /* not required by POSIX */ +# define ENOSTR 125 /* not required by POSIX */ +# define ENOTRECOVERABLE 127 /* not required by POSIX */ +# define EOWNERDEAD 133 /* not required by POSIX */ +# define ETIME 137 /* not required by POSIX */ +# define EOTHER 131 /* not required by POSIX */ +# define GNULIB_defined_ESOCK 1 +# endif + +/* These are intentionally the same values as the WSA* error numbers, defined + in <winsock2.h>. */ +# 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 + + +#endif /* _@GUARD_PREFIX@_ERRNO_H */ +#endif /* _@GUARD_PREFIX@_ERRNO_H */ diff --git a/gnu/error.c b/gnu/error.c new file mode 100644 index 00000000..68d29f40 --- /dev/null +++ b/gnu/error.c @@ -0,0 +1,403 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Error handler for noninteractive utilities + Copyright (C) 1990-1998, 2000-2007, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ + +#if !_LIBC +# include <config.h> +#endif + +#include "error.h" + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if !_LIBC && ENABLE_NLS +# include "gettext.h" +# define _(msgid) gettext (msgid) +#endif + +#ifdef _LIBC +# include <libintl.h> +# include <stdbool.h> +# include <stdint.h> +# include <wchar.h> +# define mbsrtowcs __mbsrtowcs +#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 <errno.h> +# include <limits.h> +# include <libio/libioP.h> + +/* 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 <libio/iolibio.h> +# define fflush(s) INTUSE(_IO_fflush) (s) +# undef putc +# define putc(c, fp) INTUSE(_IO_putc) (c, fp) + +# include <bits/libc-lock.h> + +#else /* not _LIBC */ + +# include <fcntl.h> +# include <unistd.h> + +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Get declarations of the native Windows API functions. */ +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +/* Get _get_osfhandle. */ +# include "msvc-nothrow.h" +# endif + +/* The gnulib override of fcntl is not needed in this file. */ +# undef fcntl + +# if !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 (); +# else +int strerror_r (); +# endif +# endif + +/* The calling program should define program_name and set it to the + name of the executing program. */ +extern char *program_name; + +# if HAVE_STRERROR_R || defined strerror_r +# define __strerror_r strerror_r +# endif /* HAVE_STRERROR_R || defined strerror_r */ +#endif /* not _LIBC */ + +#if !_LIBC +/* Return non-zero if FD is open. */ +static inline int +is_open (int fd) +{ +# if (defined _WIN32 || 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 inline 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 defined HAVE_STRERROR_R || _LIBC + char errbuf[1024]; +# if STRERROR_R_CHAR_P || _LIBC + 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 +error_tail (int status, int errnum, const char *message, va_list args) +{ +#if _LIBC + if (_IO_fwide (stderr, 0) > 0) + { +# define ALLOCA_LIMIT 2000 + size_t len = strlen (message) + 1; + wchar_t *wmessage = NULL; + mbstate_t st; + 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 / 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); + va_end (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); + +#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 + || 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:%d: " : " ", + file_name, line_number); +#else + fprintf (stderr, file_name != NULL ? "%s:%d: " : " ", + file_name, line_number); +#endif + + va_start (args, message); + error_tail (status, errnum, message, 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/gnu/error.h b/gnu/error.h new file mode 100644 index 00000000..80ad99b7 --- /dev/null +++ b/gnu/error.h @@ -0,0 +1,67 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Declaration for error-reporting function + Copyright (C) 1995-1997, 2003, 2006, 2008-2012 Free Software Foundation, + Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _ERROR_H +#define _ERROR_H 1 + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ +#endif + +#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, ...) + _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)); + +extern void error_at_line (int __status, int __errnum, const char *__fname, + unsigned int __lineno, const char *__format, ...) + _GL_ATTRIBUTE_FORMAT ((__printf__, 5, 6)); + +/* If 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/gnu/exclude.c b/gnu/exclude.c new file mode 100644 index 00000000..977dccd7 --- /dev/null +++ b/gnu/exclude.c @@ -0,0 +1,580 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* exclude.c -- exclude file names + + Copyright (C) 1992-1994, 1997, 1999-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert <eggert@twinsun.com> + and Sergey Poznyakoff <gray@gnu.org>. + Thanks to Phil Proudman <phil@proudman51.freeserve.co.uk> + for improvement suggestions. */ + +#include <config.h> + +#include <stdbool.h> + +#include <ctype.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wctype.h> + +#include "exclude.h" +#include "hash.h" +#include "mbuiter.h" +#include "fnmatch.h" +#include "xalloc.h" +#include "verify.h" + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +/* Non-GNU systems lack these options, so we don't need to check them. */ +#ifndef FNM_CASEFOLD +# define FNM_CASEFOLD 0 +#endif +#ifndef FNM_EXTMATCH +# define FNM_EXTMATCH 0 +#endif +#ifndef FNM_LEADING_DIR +# define FNM_LEADING_DIR 0 +#endif + +verify (((EXCLUDE_ANCHORED | EXCLUDE_INCLUDE | EXCLUDE_WILDCARDS) + & (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD | FNM_LEADING_DIR + | FNM_CASEFOLD | FNM_EXTMATCH)) + == 0); + + +/* Exclusion patterns are grouped into a singly-linked list of + "exclusion segments". Each segment represents a set of patterns + that can be matches using the same algorithm. Non-wildcard + patterns are kept in hash tables, to speed up searches. Wildcard + patterns are stored as arrays of patterns. */ + + +/* An exclude pattern-options pair. The options are fnmatch options + ORed with EXCLUDE_* options. */ + +struct patopts + { + char const *pattern; + int options; + }; + +/* An array of pattern-options pairs. */ + +struct exclude_pattern + { + struct patopts *exclude; + size_t exclude_alloc; + size_t exclude_count; + }; + +enum exclude_type + { + exclude_hash, /* a hash table of excluded names */ + exclude_pattern /* an array of exclude patterns */ + }; + +struct exclude_segment + { + struct exclude_segment *next; /* next segment in list */ + enum exclude_type type; /* type of this segment */ + int options; /* common options for this segment */ + union + { + Hash_table *table; /* for type == exclude_hash */ + struct exclude_pattern pat; /* for type == exclude_pattern */ + } v; + }; + +/* The exclude structure keeps a singly-linked list of exclude segments */ +struct exclude + { + struct exclude_segment *head, *tail; + }; + +/* Return true if str has wildcard characters */ +bool +fnmatch_pattern_has_wildcards (const char *str, int options) +{ + const char *cset = "\\?*[]"; + if (options & FNM_NOESCAPE) + cset++; + while (*str) + { + size_t n = strcspn (str, cset); + if (str[n] == 0) + break; + else if (str[n] == '\\') + { + str += n + 1; + if (*str) + str++; + } + else + return true; + } + return false; +} + +static void +unescape_pattern (char *str) +{ + int inset = 0; + char *q = str; + do + { + if (inset) + { + if (*q == ']') + inset = 0; + } + else if (*q == '[') + inset = 1; + else if (*q == '\\') + q++; + } + while ((*str++ = *q++)); +} + +/* Return a newly allocated and empty exclude list. */ + +struct exclude * +new_exclude (void) +{ + return xzalloc (sizeof *new_exclude ()); +} + +/* Calculate the hash of string. */ +static size_t +string_hasher (void const *data, size_t n_buckets) +{ + char const *p = data; + return hash_string (p, n_buckets); +} + +/* Ditto, for case-insensitive hashes */ +static size_t +string_hasher_ci (void const *data, size_t n_buckets) +{ + char const *p = data; + mbui_iterator_t iter; + size_t value = 0; + + for (mbui_init (iter, p); mbui_avail (iter); mbui_advance (iter)) + { + mbchar_t m = mbui_cur (iter); + wchar_t wc; + + if (m.wc_valid) + wc = towlower (m.wc); + else + wc = *m.ptr; + + value = (value * 31 + wc) % n_buckets; + } + + return value; +} + +/* compare two strings for equality */ +static bool +string_compare (void const *data1, void const *data2) +{ + char const *p1 = data1; + char const *p2 = data2; + return strcmp (p1, p2) == 0; +} + +/* compare two strings for equality, case-insensitive */ +static bool +string_compare_ci (void const *data1, void const *data2) +{ + char const *p1 = data1; + char const *p2 = data2; + return mbscasecmp (p1, p2) == 0; +} + +static void +string_free (void *data) +{ + free (data); +} + +/* Create new exclude segment of given TYPE and OPTIONS, and attach it + to the tail of list in EX */ +static struct exclude_segment * +new_exclude_segment (struct exclude *ex, enum exclude_type type, int options) +{ + struct exclude_segment *sp = xzalloc (sizeof (struct exclude_segment)); + sp->type = type; + sp->options = options; + switch (type) + { + case exclude_pattern: + break; + + case exclude_hash: + sp->v.table = hash_initialize (0, NULL, + (options & FNM_CASEFOLD) ? + string_hasher_ci + : string_hasher, + (options & FNM_CASEFOLD) ? + string_compare_ci + : string_compare, + string_free); + break; + } + if (ex->tail) + ex->tail->next = sp; + else + ex->head = sp; + ex->tail = sp; + return sp; +} + +/* Free a single exclude segment */ +static void +free_exclude_segment (struct exclude_segment *seg) +{ + switch (seg->type) + { + case exclude_pattern: + free (seg->v.pat.exclude); + break; + + case exclude_hash: + hash_free (seg->v.table); + break; + } + free (seg); +} + +/* Free the storage associated with an exclude list. */ +void +free_exclude (struct exclude *ex) +{ + struct exclude_segment *seg; + for (seg = ex->head; seg; ) + { + struct exclude_segment *next = seg->next; + free_exclude_segment (seg); + seg = next; + } + free (ex); +} + +/* Return zero if PATTERN matches F, obeying OPTIONS, except that + (unlike fnmatch) wildcards are disabled in PATTERN. */ + +static int +fnmatch_no_wildcards (char const *pattern, char const *f, int options) +{ + if (! (options & FNM_LEADING_DIR)) + return ((options & FNM_CASEFOLD) + ? mbscasecmp (pattern, f) + : strcmp (pattern, f)); + else if (! (options & FNM_CASEFOLD)) + { + size_t patlen = strlen (pattern); + int r = strncmp (pattern, f, patlen); + if (! r) + { + r = f[patlen]; + if (r == '/') + r = 0; + } + return r; + } + else + { + /* Walk through a copy of F, seeing whether P matches any prefix + of F. + + FIXME: This is an O(N**2) algorithm; it should be O(N). + Also, the copy should not be necessary. However, fixing this + will probably involve a change to the mbs* API. */ + + char *fcopy = xstrdup (f); + char *p; + int r; + for (p = fcopy; ; *p++ = '/') + { + p = strchr (p, '/'); + if (p) + *p = '\0'; + r = mbscasecmp (pattern, fcopy); + if (!p || r <= 0) + break; + } + free (fcopy); + return r; + } +} + +bool +exclude_fnmatch (char const *pattern, char const *f, int options) +{ + int (*matcher) (char const *, char const *, int) = + (options & EXCLUDE_WILDCARDS + ? fnmatch + : fnmatch_no_wildcards); + bool matched = ((*matcher) (pattern, f, options) == 0); + char const *p; + + if (! (options & EXCLUDE_ANCHORED)) + for (p = f; *p && ! matched; p++) + if (*p == '/' && p[1] != '/') + matched = ((*matcher) (pattern, p + 1, options) == 0); + + return matched; +} + +/* Return true if the exclude_pattern segment SEG excludes F. */ + +static bool +excluded_file_pattern_p (struct exclude_segment const *seg, char const *f) +{ + size_t exclude_count = seg->v.pat.exclude_count; + struct patopts const *exclude = seg->v.pat.exclude; + size_t i; + bool excluded = !! (exclude[0].options & EXCLUDE_INCLUDE); + + /* Scan through the options, until they change excluded */ + for (i = 0; i < exclude_count; i++) + { + char const *pattern = exclude[i].pattern; + int options = exclude[i].options; + if (exclude_fnmatch (pattern, f, options)) + return !excluded; + } + return excluded; +} + +/* Return true if the exclude_hash segment SEG excludes F. + BUFFER is an auxiliary storage of the same length as F (with nul + terminator included) */ +static bool +excluded_file_name_p (struct exclude_segment const *seg, char const *f, + char *buffer) +{ + int options = seg->options; + bool excluded = !! (options & EXCLUDE_INCLUDE); + Hash_table *table = seg->v.table; + + do + { + /* initialize the pattern */ + strcpy (buffer, f); + + while (1) + { + if (hash_lookup (table, buffer)) + return !excluded; + if (options & FNM_LEADING_DIR) + { + char *p = strrchr (buffer, '/'); + if (p) + { + *p = 0; + continue; + } + } + break; + } + + if (!(options & EXCLUDE_ANCHORED)) + { + f = strchr (f, '/'); + if (f) + f++; + } + else + break; + } + while (f); + return excluded; +} + +/* Return true if EX excludes F. */ + +bool +excluded_file_name (struct exclude const *ex, char const *f) +{ + struct exclude_segment *seg; + bool excluded; + char *filename = NULL; + + /* If no patterns are given, the default is to include. */ + if (!ex->head) + return false; + + /* Otherwise, the default is the opposite of the first option. */ + excluded = !! (ex->head->options & EXCLUDE_INCLUDE); + /* Scan through the segments, seeing whether they change status from + excluded to included or vice versa. */ + for (seg = ex->head; seg; seg = seg->next) + { + bool rc; + + switch (seg->type) + { + case exclude_pattern: + rc = excluded_file_pattern_p (seg, f); + break; + + case exclude_hash: + if (!filename) + filename = xmalloc (strlen (f) + 1); + rc = excluded_file_name_p (seg, f, filename); + break; + + default: + abort (); + } + if (rc != excluded) + { + excluded = rc; + break; + } + } + free (filename); + return excluded; +} + +/* Append to EX the exclusion PATTERN with OPTIONS. */ + +void +add_exclude (struct exclude *ex, char const *pattern, int options) +{ + struct exclude_segment *seg; + + if ((options & EXCLUDE_WILDCARDS) + && fnmatch_pattern_has_wildcards (pattern, options)) + { + struct exclude_pattern *pat; + struct patopts *patopts; + + if (ex->tail && ex->tail->type == exclude_pattern + && ((ex->tail->options & EXCLUDE_INCLUDE) == + (options & EXCLUDE_INCLUDE))) + seg = ex->tail; + else + seg = new_exclude_segment (ex, exclude_pattern, options); + + pat = &seg->v.pat; + if (pat->exclude_count == pat->exclude_alloc) + pat->exclude = x2nrealloc (pat->exclude, &pat->exclude_alloc, + sizeof *pat->exclude); + patopts = &pat->exclude[pat->exclude_count++]; + patopts->pattern = pattern; + patopts->options = options; + } + else + { + char *str, *p; +#define EXCLUDE_HASH_FLAGS (EXCLUDE_INCLUDE|EXCLUDE_ANCHORED|\ + FNM_LEADING_DIR|FNM_CASEFOLD) + if (ex->tail && ex->tail->type == exclude_hash + && ((ex->tail->options & EXCLUDE_HASH_FLAGS) == + (options & EXCLUDE_HASH_FLAGS))) + seg = ex->tail; + else + seg = new_exclude_segment (ex, exclude_hash, options); + + str = xstrdup (pattern); + if (options & EXCLUDE_WILDCARDS) + unescape_pattern (str); + p = hash_insert (seg->v.table, str); + if (p != str) + free (str); + } +} + +/* Use ADD_FUNC to append to EX the patterns in FILE_NAME, each with + OPTIONS. LINE_END terminates each pattern in the file. If + LINE_END is a space character, ignore trailing spaces and empty + lines in FILE. Return -1 on failure, 0 on success. */ + +int +add_exclude_file (void (*add_func) (struct exclude *, char const *, int), + struct exclude *ex, char const *file_name, int options, + char line_end) +{ + bool use_stdin = file_name[0] == '-' && !file_name[1]; + FILE *in; + char *buf = NULL; + char *p; + char const *pattern; + char const *lim; + size_t buf_alloc = 0; + size_t buf_count = 0; + int c; + int e = 0; + + if (use_stdin) + in = stdin; + else if (! (in = fopen (file_name, "r"))) + return -1; + + while ((c = getc (in)) != EOF) + { + if (buf_count == buf_alloc) + buf = x2realloc (buf, &buf_alloc); + buf[buf_count++] = c; + } + + if (ferror (in)) + e = errno; + + if (!use_stdin && fclose (in) != 0) + e = errno; + + buf = xrealloc (buf, buf_count + 1); + buf[buf_count] = line_end; + lim = buf + buf_count + ! (buf_count == 0 || buf[buf_count - 1] == line_end); + pattern = buf; + + for (p = buf; p < lim; p++) + if (*p == line_end) + { + char *pattern_end = p; + + if (isspace ((unsigned char) line_end)) + { + for (; ; pattern_end--) + if (pattern_end == pattern) + goto next_pattern; + else if (! isspace ((unsigned char) pattern_end[-1])) + break; + } + + *pattern_end = '\0'; + (*add_func) (ex, pattern, options); + + next_pattern: + pattern = p + 1; + } + + errno = e; + return e ? -1 : 0; +} diff --git a/gnu/exclude.h b/gnu/exclude.h new file mode 100644 index 00000000..bd5c2ebf --- /dev/null +++ b/gnu/exclude.h @@ -0,0 +1,54 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* exclude.h -- declarations for excluding file names + + Copyright (C) 1992-1994, 1997, 1999, 2001-2003, 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _GL_EXCLUDE_H +#define _GL_EXCLUDE_H 1 + +#include <stdbool.h> + +/* Written by Paul Eggert <eggert@twinsun.com> + and Sergey Poznyakoff <gray@gnu.org> */ + +/* Exclude options, which can be ORed with fnmatch options. */ + +/* Patterns must match the start of file names, instead of matching + anywhere after a '/'. */ +#define EXCLUDE_ANCHORED (1 << 30) + +/* Include instead of exclude. */ +#define EXCLUDE_INCLUDE (1 << 29) + +/* '?', '*', '[', and '\\' are special in patterns. Without this + option, these characters are ordinary and fnmatch is not used. */ +#define EXCLUDE_WILDCARDS (1 << 28) + +struct exclude; + +bool fnmatch_pattern_has_wildcards (const char *, int) _GL_ATTRIBUTE_PURE; + +struct exclude *new_exclude (void); +void free_exclude (struct exclude *); +void add_exclude (struct exclude *, char const *, int); +int add_exclude_file (void (*) (struct exclude *, char const *, int), + struct exclude *, char const *, int, char); +bool excluded_file_name (struct exclude const *, char const *); +bool exclude_fnmatch (char const *pattern, char const *f, int options); + +#endif /* _GL_EXCLUDE_H */ diff --git a/gnu/exitfail.c b/gnu/exitfail.c new file mode 100644 index 00000000..64d27668 --- /dev/null +++ b/gnu/exitfail.c @@ -0,0 +1,26 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Failure exit status + + Copyright (C) 2002-2003, 2005-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "exitfail.h" + +#include <stdlib.h> + +int volatile exit_failure = EXIT_FAILURE; diff --git a/gnu/exitfail.h b/gnu/exitfail.h new file mode 100644 index 00000000..0f63bc57 --- /dev/null +++ b/gnu/exitfail.h @@ -0,0 +1,20 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Failure exit status + + Copyright (C) 2002, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +extern int volatile exit_failure; diff --git a/gnu/fchdir.c b/gnu/fchdir.c new file mode 100644 index 00000000..90f76568 --- /dev/null +++ b/gnu/fchdir.c @@ -0,0 +1,210 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* fchdir replacement. + Copyright (C) 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#include <assert.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "dosname.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. */ +static char * +get_name (char const *dir) +{ + char *cwd; + char *result; + int saved_errno; + + 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); + saved_errno = errno; + free (cwd); + errno = saved_errno; + 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 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; + + assert (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) +{ + assert (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/gnu/fchown-stub.c b/gnu/fchown-stub.c new file mode 100644 index 00000000..b4650031 --- /dev/null +++ b/gnu/fchown-stub.c @@ -0,0 +1,18 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#include <config.h> + +#include <sys/types.h> +#include <errno.h> + +/* A trivial substitute for 'fchown'. + + DJGPP 2.03 and earlier (and perhaps later) don't have 'fchown', + so we pretend no-one has permission for this operation. */ + +int +fchown (int fd, uid_t uid, gid_t gid) +{ + errno = EPERM; + return -1; +} diff --git a/gnu/fcntl.c b/gnu/fcntl.c new file mode 100644 index 00000000..21bd291e --- /dev/null +++ b/gnu/fcntl.c @@ -0,0 +1,313 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Provide file descriptor control. + + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Eric Blake <ebb9@byu.net>. */ + +#include <config.h> + +/* Specification. */ +#include <fcntl.h> + +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#include <unistd.h> + +#if !HAVE_FCNTL +# define rpl_fcntl fcntl +#endif +#undef fcntl + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Get declarations of the native Windows API functions. */ +# define WIN32_LEAN_AND_MEAN +# include <windows.h> + +/* Get _get_osfhandle. */ +# include "msvc-nothrow.h" + +/* 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 */ + { + /* TODO: Translate GetLastError () into errno. */ + errno = EMFILE; + result = -1; + break; + } + duplicated_fd = _open_osfhandle ((long) new_handle, flags); + if (duplicated_fd < 0) + { + CloseHandle (new_handle); + errno = EMFILE; + 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 */ + +/* 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 +rpl_fcntl (int fd, int action, /* arg */...) +{ + va_list arg; + int result = -1; + va_start (arg, action); + switch (action) + { + +#if !HAVE_FCNTL + case F_DUPFD: + { + int target = va_arg (arg, int); + result = dupfd (fd, target, 0); + break; + } +#elif FCNTL_DUPFD_BUGGY || REPLACE_FCHDIR + case F_DUPFD: + { + int target = va_arg (arg, int); + /* Detect invalid target; needed for cygwin 1.5.x. */ + if (target < 0 || getdtablesize () <= target) + errno = EINVAL; + else + { + /* Haiku alpha 2 loses fd flags on original. */ + int flags = fcntl (fd, F_GETFD); + if (flags < 0) + { + result = -1; + break; + } + result = fcntl (fd, action, 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 + } + break; + } /* F_DUPFD */ +#endif /* FCNTL_DUPFD_BUGGY || REPLACE_FCHDIR */ + + case F_DUPFD_CLOEXEC: + { + int target = va_arg (arg, int); + +#if !HAVE_FCNTL + result = dupfd (fd, target, O_CLOEXEC); + break; +#else /* HAVE_FCNTL */ + /* 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, action, 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 (fd, F_DUPFD, target); + if (result < 0) + break; + have_dupfd_cloexec = -1; + } + } + else + result = rpl_fcntl (fd, F_DUPFD, 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; + } + } + break; +#endif /* HAVE_FCNTL */ + } /* F_DUPFD_CLOEXEC */ + +#if !HAVE_FCNTL + case F_GETFD: + { +# if (defined _WIN32 || 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 + void *p = va_arg (arg, void *); + result = fcntl (fd, action, p); +#else + errno = EINVAL; +#endif + break; + } + } + va_end (arg); + return result; +} diff --git a/gnu/fcntl.in.h b/gnu/fcntl.in.h new file mode 100644 index 00000000..57a561ef --- /dev/null +++ b/gnu/fcntl.in.h @@ -0,0 +1,333 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Like <fcntl.h>, but with non-working flags defined to 0. + + Copyright (C) 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Paul Eggert */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined __need_system_fcntl_h +/* Special invocation convention. */ + +#include <sys/types.h> +/* On some systems other than glibc, <sys/stat.h> is a prerequisite of + <fcntl.h>. On glibc systems, we would like to avoid namespace pollution. + But on glibc systems, <fcntl.h> includes <sys/stat.h> inside an + extern "C" { ... } block, which leads to errors in C++ mode with the + overridden <sys/stat.h> from gnulib. These errors are known to be gone + with g++ version >= 4.3. */ +#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) +# include <sys/stat.h> +#endif +#@INCLUDE_NEXT@ @NEXT_FCNTL_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_FCNTL_H + +#include <sys/types.h> +/* On some systems other than glibc, <sys/stat.h> is a prerequisite of + <fcntl.h>. On glibc systems, we would like to avoid namespace pollution. + But on glibc systems, <fcntl.h> includes <sys/stat.h> inside an + extern "C" { ... } block, which leads to errors in C++ mode with the + overridden <sys/stat.h> from gnulib. These errors are known to be gone + with g++ version >= 4.3. */ +#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) +# include <sys/stat.h> +#endif +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_FCNTL_H@ + +#ifndef _@GUARD_PREFIX@_FCNTL_H +#define _@GUARD_PREFIX@_FCNTL_H + +#ifndef __GLIBC__ /* Avoid namespace pollution on glibc systems. */ +# include <unistd.h> +#endif + +/* Native Windows platforms declare open(), creat() in <io.h>. */ +#if (@GNULIB_OPEN@ || defined GNULIB_POSIXCHECK) \ + && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +# include <io.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. */ + + +/* Declare overridden functions. */ + +#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, ...)); +# else +# if !@HAVE_FCNTL@ +_GL_FUNCDECL_SYS (fcntl, int, (int fd, int action, ...)); +# 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, ...)); +# 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"); +#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. */ + +#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 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_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_NOLINKS +# define O_NOLINKS 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/gnu/fd-hook.c b/gnu/fd-hook.c new file mode 100644 index 00000000..86f79e34 --- /dev/null +++ b/gnu/fd-hook.c @@ -0,0 +1,118 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Hook for making making file descriptor functions close(), ioctl() extensible. + Copyright (C) 2009-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2009. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "fd-hook.h" + +#include <stdlib.h> + +/* 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/gnu/fd-hook.h b/gnu/fd-hook.h new file mode 100644 index 00000000..a109df75 --- /dev/null +++ b/gnu/fd-hook.h @@ -0,0 +1,121 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Hook for making making file descriptor functions close(), ioctl() extensible. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + + +#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/gnu/fd-safer.c b/gnu/fd-safer.c new file mode 100644 index 00000000..e3ccd8e7 --- /dev/null +++ b/gnu/fd-safer.c @@ -0,0 +1,51 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Return a safer copy of a file descriptor. + + Copyright (C) 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +#include "unistd-safer.h" + +#include <errno.h> +#include <unistd.h> + +/* 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/gnu/fdopendir.c b/gnu/fdopendir.c new file mode 100644 index 00000000..ca3a8ccc --- /dev/null +++ b/gnu/fdopendir.c @@ -0,0 +1,206 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* provide a replacement fdopendir function + Copyright (C) 2004-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering */ + +#include <config.h> + +#include <dirent.h> + +#include <stdlib.h> +#include <unistd.h> + +#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. */ +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; +} + +/* 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_CHDIR 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); + return (name ? opendir (name) : NULL); + } +# 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 <errno.h> +# include <sys/stat.h> + +# 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/gnu/fdutimensat.c b/gnu/fdutimensat.c new file mode 100644 index 00000000..7ee140e5 --- /dev/null +++ b/gnu/fdutimensat.c @@ -0,0 +1,59 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Set file access and modification times. + + Copyright (C) 2009-2012 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 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Eric Blake. */ + +/* derived from a function in utimens.c */ + +#include <config.h> + +#include "utimens.h" + +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> + +/* Set the access and modification time stamps of FD (a.k.a. FILE) to be + TIMESPEC[0] and TIMESPEC[1], respectively; relative to directory DIR. + 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 time stamps to the current time. + ATFLAG is passed to utimensat if FD is negative or futimens was + unsupported, which can allow operation on FILE as a symlink. + Return 0 on success, -1 (setting errno) on failure. */ + +int +fdutimensat (int fd, int dir, char const *file, struct timespec const ts[2], + int atflag) +{ + int result = 1; + if (0 <= fd) + result = futimens (fd, ts); + if (file && (fd < 0 || (result == -1 && errno == ENOSYS))) + result = utimensat (dir, file, ts, atflag); + if (result == 1) + { + errno = EBADF; + result = -1; + } + return result; +} diff --git a/gnu/fileblocks.c b/gnu/fileblocks.c new file mode 100644 index 00000000..49b0eb6a --- /dev/null +++ b/gnu/fileblocks.c @@ -0,0 +1,76 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert file size to number of blocks on System V-like machines. + + Copyright (C) 1990, 1997-1999, 2004-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Brian L. Matthews, blm@6sceng.UUCP. */ + +#include <config.h> + +#include <sys/types.h> + +#if HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif + +#if !HAVE_STRUCT_STAT_ST_BLOCKS && !defined _POSIX_SOURCE && defined BSIZE + +# include <unistd.h> + +# ifndef NINDIR + +# if defined __DJGPP__ +typedef long daddr_t; /* for disk address */ +# endif + +/* Some SysV's, like Irix, seem to lack this. Hope it's correct. */ +/* Number of inode pointers per indirect block. */ +# define NINDIR (BSIZE / sizeof (daddr_t)) +# endif /* !NINDIR */ + +/* Number of direct block addresses in an inode. */ +# define NDIR 10 + +/* Return the number of 512-byte blocks in a file of SIZE bytes. */ + +off_t +st_blocks (off_t size) +{ + off_t datablks = size / 512 + (size % 512 != 0); + off_t indrblks = 0; + + if (datablks > NDIR) + { + indrblks = (datablks - NDIR - 1) / NINDIR + 1; + + if (datablks > NDIR + NINDIR) + { + indrblks += (datablks - NDIR - NINDIR - 1) / (NINDIR * NINDIR) + 1; + + if (datablks > NDIR + NINDIR + NINDIR * NINDIR) + indrblks++; + } + } + + return datablks + indrblks; +} +#else +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int textutils_fileblocks_unused; +#endif diff --git a/gnu/filename.h b/gnu/filename.h new file mode 100644 index 00000000..bc17d2db --- /dev/null +++ b/gnu/filename.h @@ -0,0 +1,56 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Basic filename support macros. + Copyright (C) 2001-2004, 2007-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _FILENAME_H +#define _FILENAME_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Pathname support. + ISSLASH(C) tests whether C is a directory separator character. + IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, + it may be concatenated to a directory pathname. + IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. + */ +#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ + /* Native Windows, Cygwin, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +# define HAS_DEVICE(P) \ + ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ + && (P)[1] == ':') +# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) +# define IS_PATH_WITH_DIR(P) \ + (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) +# define FILE_SYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) +# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) +# define FILE_SYSTEM_PREFIX_LEN(P) 0 +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _FILENAME_H */ diff --git a/gnu/filenamecat-lgpl.c b/gnu/filenamecat-lgpl.c new file mode 100644 index 00000000..deddcccd --- /dev/null +++ b/gnu/filenamecat-lgpl.c @@ -0,0 +1,90 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Concatenate two arbitrary file names. + + Copyright (C) 1996-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#include <config.h> + +/* Specification. */ +#include "filenamecat.h" + +#include <stdlib.h> +#include <string.h> + +#include "dirname.h" + +#if ! HAVE_MEMPCPY && ! defined mempcpy +# define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) +#endif + +/* Return the longest suffix of F that is a relative file name. + If it has no such suffix, return the empty string. */ + +static char const * _GL_ATTRIBUTE_PURE +longest_relative_suffix (char const *f) +{ + for (f += FILE_SYSTEM_PREFIX_LEN (f); ISSLASH (*f); f++) + continue; + return f; +} + +/* Concatenate two file name components, DIR and ABASE, 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, where BASE is ABASE with any + file system prefixes and leading separators removed. + Arrange for a directory separator if necessary between DIR and BASE + in the result, removing any redundant separators. + In any case, if BASE_IN_RESULT is non-NULL, set + *BASE_IN_RESULT to point to the copy of ABASE in the returned + concatenation. However, if ABASE begins with more than one slash, + set *BASE_IN_RESULT to point to the sole corresponding slash that + is copied into the result buffer. + + Return NULL if malloc fails. */ + +char * +mfile_name_concat (char const *dir, char const *abase, char **base_in_result) +{ + char const *dirbase = last_component (dir); + size_t dirbaselen = base_len (dirbase); + size_t dirlen = dirbase - dir + dirbaselen; + size_t needs_separator = (dirbaselen && ! ISSLASH (dirbase[dirbaselen - 1])); + + char const *base = longest_relative_suffix (abase); + size_t baselen = strlen (base); + + char *p_concat = malloc (dirlen + needs_separator + baselen + 1); + char *p; + + if (p_concat == NULL) + return NULL; + + p = mempcpy (p_concat, dir, dirlen); + *p = DIRECTORY_SEPARATOR; + p += needs_separator; + + if (base_in_result) + *base_in_result = p - IS_ABSOLUTE_FILE_NAME (abase); + + p = mempcpy (p, base, baselen); + *p = '\0'; + + return p_concat; +} diff --git a/gnu/filenamecat.h b/gnu/filenamecat.h new file mode 100644 index 00000000..a9088627 --- /dev/null +++ b/gnu/filenamecat.h @@ -0,0 +1,29 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Concatenate two arbitrary file names. + + Copyright (C) 1996-1997, 2003, 2005, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#if GNULIB_FILENAMECAT +char *file_name_concat (char const *dir, char const *base, + char **base_in_result); +#endif + +char *mfile_name_concat (char const *dir, char const *base, + char **base_in_result); diff --git a/gnu/float+.h b/gnu/float+.h new file mode 100644 index 00000000..0b72de9d --- /dev/null +++ b/gnu/float+.h @@ -0,0 +1,150 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Supplemental information about the floating-point formats. + Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _FLOATPLUS_H +#define _FLOATPLUS_H + +#include <float.h> +#include <limits.h> + +/* 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/gnu/float.c b/gnu/float.c new file mode 100644 index 00000000..656a972d --- /dev/null +++ b/gnu/float.c @@ -0,0 +1,35 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Auxiliary definitions for <float.h>. + Copyright (C) 2011-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2011. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <float.h> + +#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/gnu/float.in.h b/gnu/float.in.h new file mode 100644 index 00000000..0afc8dd0 --- /dev/null +++ b/gnu/float.in.h @@ -0,0 +1,190 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A correct <float.h>. + + Copyright (C) 2007-2012 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 <http://www.gnu.org/licenses/>. */ + +#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 + <http://lists.gnu.org/archive/html/bug-gnulib/2008-07/msg00063.html>. */ +#if defined __i386__ && defined __FreeBSD__ +/* 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.3621031431120935E-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. */ +union gl_long_double_union + { + struct { unsigned int lo; unsigned int hi; unsigned int exponent; } xd; + long double ld; + }; +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.. */ +union gl_long_double_union + { + struct { double hi; double lo; } dd; + long double ld; + }; +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/gnu/fnmatch.c b/gnu/fnmatch.c new file mode 100644 index 00000000..b9c8f3f7 --- /dev/null +++ b/gnu/fnmatch.c @@ -0,0 +1,353 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1991-1993, 1996-2007, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _LIBC +# include <config.h> +#endif + +/* Enable GNU extensions in fnmatch.h. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#if ! defined __builtin_expect && __GNUC__ < 3 +# define __builtin_expect(expr, expected) (expr) +#endif + +#include <fnmatch.h> + +#include <alloca.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <stddef.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#define WIDE_CHAR_SUPPORT \ + (HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \ + && HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY)) + +/* For platform which support the ISO C amendement 1 functionality we + support user defined character classes. */ +#if defined _LIBC || WIDE_CHAR_SUPPORT +# include <wctype.h> +# include <wchar.h> +#endif + +/* 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/elem-hash.h" +# include "../locale/coll-lookup.h" +# include <shlib-compat.h> + +# define CONCAT(a,b) __CONCAT(a,b) +# define mbsrtowcs __mbsrtowcs +# define fnmatch __fnmatch +extern int fnmatch (const char *pattern, const char *string, int flags); +#endif + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#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)) + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself, and have not detected a bug + in the library. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand 'configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU + + +# if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) +# define isblank(c) ((c) == ' ' || (c) == '\t') +# endif + +# define STREQ(s1, s2) (strcmp (s1, s2) == 0) + +# if defined _LIBC || WIDE_CHAR_SUPPORT +/* The GNU C library provides support for user-defined character classes + and the functions from ISO C amendement 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 + +# ifdef _LIBC +# define IS_CHAR_CLASS(string) __wctype (string) +# else +# define IS_CHAR_CLASS(string) wctype (string) +# endif + +# ifdef _LIBC +# define ISWCTYPE(WC, WT) __iswctype (WC, WT) +# else +# define ISWCTYPE(WC, WT) iswctype (WC, WT) +# endif + +# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC +/* In this case we are implementing the multibyte character handling. */ +# define HANDLE_MULTIBYTE 1 +# endif + +# else +# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, 'xdigit'. */ + +# define IS_CHAR_CLASS(string) \ + (STREQ (string, "alpha") || STREQ (string, "upper") \ + || STREQ (string, "lower") || STREQ (string, "digit") \ + || STREQ (string, "alnum") || STREQ (string, "xdigit") \ + || STREQ (string, "space") || STREQ (string, "print") \ + || STREQ (string, "punct") || STREQ (string, "graph") \ + || STREQ (string, "cntrl") || STREQ (string, "blank")) +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +/* Global variable. */ +static int posixly_correct; + +# ifndef internal_function +/* Inside GNU libc we mark some function in a special way. In other + environments simply ignore the marking. */ +# define internal_function +# endif + +/* 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 L_(CS) CS +# ifdef _LIBC +# define BTOWC(C) __btowc (C) +# else +# define BTOWC(C) btowc (C) +# endif +# define STRLEN(S) strlen (S) +# define STRCAT(D, S) strcat (D, S) +# ifdef _LIBC +# define MEMPCPY(D, S, N) __mempcpy (D, S, N) +# else +# if HAVE_MEMPCPY +# define MEMPCPY(D, S, N) mempcpy (D, S, N) +# else +# define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) +# endif +# endif +# define MEMCHR(S, C, N) memchr (S, C, N) +# include "fnmatch_loop.c" + + +# if HANDLE_MULTIBYTE +# 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) +# ifdef _LIBC +# define STRLEN(S) __wcslen (S) +# define STRCAT(D, S) __wcscat (D, S) +# define MEMPCPY(D, S, N) __wmempcpy (D, S, N) +# else +# define STRLEN(S) wcslen (S) +# define STRCAT(D, S) wcscat (D, S) +# if HAVE_WMEMPCPY +# define MEMPCPY(D, S, N) wmempcpy (D, S, N) +# else +# define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N)) +# endif +# endif +# define MEMCHR(S, C, N) wmemchr (S, C, N) +# define WIDE_CHAR_VERSION 1 + +# 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'; + +# ifdef _LIBC + return __wctype (s); +# else + return wctype (s); +# endif +} +# define IS_CHAR_CLASS(string) is_char_class (string) + +# include "fnmatch_loop.c" +# endif + + +int +fnmatch (const char *pattern, const char *string, int flags) +{ +# if HANDLE_MULTIBYTE +# define ALLOCA_LIMIT 2000 + if (__builtin_expect (MB_CUR_MAX, 1) != 1) + { + mbstate_t ps; + size_t patsize; + size_t strsize; + size_t totsize; + wchar_t *wpattern; + wchar_t *wstring; + int res; + + /* Calculate the size needed to convert the strings to + wide characters. */ + memset (&ps, '\0', sizeof (ps)); + patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1; + if (__builtin_expect (patsize != 0, 1)) + { + assert (mbsinit (&ps)); + strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1; + if (__builtin_expect (strsize != 0, 1)) + { + assert (mbsinit (&ps)); + totsize = patsize + strsize; + if (__builtin_expect (! (patsize <= totsize + && totsize <= SIZE_MAX / sizeof (wchar_t)), + 0)) + { + errno = ENOMEM; + return -1; + } + + /* Allocate room for the wide characters. */ + if (__builtin_expect (totsize < ALLOCA_LIMIT, 1)) + wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t)); + else + { + wpattern = malloc (totsize * sizeof (wchar_t)); + if (__builtin_expect (! wpattern, 0)) + { + errno = ENOMEM; + return -1; + } + } + wstring = wpattern + patsize; + + /* Convert the strings into wide characters. */ + mbsrtowcs (wpattern, &pattern, patsize, &ps); + assert (mbsinit (&ps)); + mbsrtowcs (wstring, &string, strsize, &ps); + + res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1, + flags & FNM_PERIOD, flags); + + if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0)) + free (wpattern); + return res; + } + } + } + +# endif /* HANDLE_MULTIBYTE */ + + return internal_fnmatch (pattern, string, string + strlen (string), + flags & FNM_PERIOD, flags); +} + +# ifdef _LIBC +# 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) +# endif + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/gnu/fnmatch.in.h b/gnu/fnmatch.in.h new file mode 100644 index 00000000..839533ba --- /dev/null +++ b/gnu/fnmatch.in.h @@ -0,0 +1,70 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1991-1993, 1996-1999, 2001-2003, 2005, 2007, 2009-2012 Free + Software Foundation, Inc. + + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _FNMATCH_H +#define _FNMATCH_H 1 + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in <unistd.h>. */ +#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 + +/* Match NAME against the file name pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int fnmatch (const char *__pattern, const char *__name, + int __flags) + _GL_ARG_NONNULL ((1, 2)); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff --git a/gnu/fnmatch_loop.c b/gnu/fnmatch_loop.c new file mode 100644 index 00000000..f22741b6 --- /dev/null +++ b/gnu/fnmatch_loop.c @@ -0,0 +1,1222 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1991-1993, 1996-2006, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Match STRING against the file name pattern PATTERN, returning zero if + it matches, nonzero if not. */ +static int EXT (INT opt, const CHAR *pattern, const CHAR *string, + const CHAR *string_end, bool no_leading_period, int flags) + internal_function; +static const CHAR *END (const CHAR *patternp) internal_function; + +static int +internal_function +FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, + bool no_leading_period, int flags) +{ + register const CHAR *p = pattern, *n = string; + register 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 (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') + { + int res; + + res = EXT (c, p, n, string_end, no_leading_period, + flags); + 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 (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') + { + int res; + + res = EXT (c, p, n, string_end, no_leading_period, + flags); + if (res != -1) + return res; + } + + 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_('/') + && __builtin_expect (flags & FNM_FILE_NAME, 0)) + /* 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; + + endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'), + string_end - n); + if (endp == NULL) + endp = string_end; + + if (c == L_('[') + || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0 + && (c == L_('@') || c == L_('+') || c == L_('!')) + && *p == L_('('))) + { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + bool no_leading_period2 = no_leading_period; + + for (--p; n < endp; ++n, no_leading_period2 = false) + if (FCT (p, n, string_end, no_leading_period2, flags2) + == 0) + return 0; + } + 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) + == 0)) + return 0; + } + else + { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + int no_leading_period2 = no_leading_period; + + if (c == L_('\\') && !(flags & FNM_NOESCAPE)) + c = *p; + c = FOLD (c); + for (--p; n < endp; ++n, no_leading_period2 = false) + if (FOLD ((UCHAR) *n) == c + && (FCT (p, n, string_end, no_leading_period2, flags2) + == 0)) + return 0; + } + } + + /* 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; + register 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; +#if defined _LIBC || WIDE_CHAR_SUPPORT + wctype_t wt; +#endif + 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'); + +#if defined _LIBC || WIDE_CHAR_SUPPORT + 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 +#else + if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n)) + || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n)) + || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n)) + || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n)) + || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n)) + || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n)) + || (STREQ (str, L_("lower")) && islower ((UCHAR) *n)) + || (STREQ (str, L_("print")) && isprint ((UCHAR) *n)) + || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n)) + || (STREQ (str, L_("space")) && isspace ((UCHAR) *n)) + || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n)) + || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n))) + goto matched; +#endif + c = *p++; + } +#ifdef _LIBC + else if (c == L_('[') && *p == L_('=')) + { + UCHAR str[1]; + 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[0] = 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[0]) + goto matched; + } + else + { + const int32_t *table; +# if WIDE_CHAR_VERSION + const int32_t *weights; + const int32_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; + + /* This #include defines a local function! */ +# if WIDE_CHAR_VERSION +# include <locale/weightwc.h> +# else +# include <locale/weight.h> +# endif + +# 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 int32_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 (&cp); + if (idx != 0) + { + /* We found a table entry. Now see whether the + character we are currently at has the same + equivalance class value. */ + int len = weights[idx & 0xffffff]; + int32_t idx2; + const UCHAR *np = (const UCHAR *) n; + + idx2 = findidx (&np); + 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; +# ifdef WIDE_CHAR_VERSION + char str[c1]; + size_t strcnt; +# else +# define str (startp + 1) +# endif + const unsigned char *extra; + int32_t idx; + int32_t elem; + int32_t second; + int32_t hash; + +# ifdef WIDE_CHAR_VERSION + /* We have to convert the name to a single-byte + string. This is possible since the names + consist of ASCII characters and the internal + representation is UCS4. */ + for (strcnt = 0; strcnt < c1; ++strcnt) + str[strcnt] = startp[1 + strcnt]; +# 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); + + /* Locate the character in the hashing table. */ + hash = elem_hash (str, c1); + + idx = 0; + elem = hash % table_size; + if (symb_table[2 * elem] != 0) + { + second = hash % (table_size - 2) + 1; + + do + { + /* First compare the hashing value. */ + if (symb_table[2 * elem] == hash + && (c1 + == extra[symb_table[2 * elem + 1]]) + && memcmp (str, + &extra[symb_table[2 * elem + + 1] + + 1], c1) == 0) + { + /* Yep, this is the entry. */ + idx = symb_table[2 * elem + 1]; + idx += 1 + extra[idx]; + break; + } + + /* Next entry. */ + elem += second; + } + while (symb_table[2 * elem] != 0); + } + + if (symb_table[2 * elem] != 0) + { + /* Compare the byte sequence but only if + this is not part of a range. */ +# ifdef WIDE_CHAR_VERSION + int32_t *wextra; + + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + + wextra = (int32_t *) &extra[idx + 4]; +# endif + + if (! is_range) + { +# ifdef WIDE_CHAR_VERSION + for (c1 = 0; + (int32_t) c1 < wextra[idx]; + ++c1) + if (n[c1] != wextra[1 + c1]) + break; + + if ((int32_t) c1 == wextra[idx]) + goto matched; +# else + for (c1 = 0; c1 < extra[idx]; ++c1) + if (n[c1] != extra[1 + c1]) + break; + + if (c1 == extra[idx]) + goto matched; +# endif + } + + /* Get the collation sequence value. */ + is_seqval = true; +# ifdef WIDE_CHAR_VERSION + cold = wextra[1 + wextra[idx]]; +# else + /* Adjust for the alignment. */ + idx += 1 + extra[idx]; + idx = (idx + 3) & ~4; + 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 == str[0]) + goto matched; + + cold = str[0]; + c = *p++; + } + else + return FNM_NOMATCH; + } + } + else +# undef str +#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++; + +# ifdef 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; +# ifdef WIDE_CHAR_VERSION + char str[c1]; + size_t strcnt; +# else +# define str (startp + 1) +# endif + const unsigned char *extra; + int32_t idx; + int32_t elem; + int32_t second; + int32_t hash; + +# ifdef WIDE_CHAR_VERSION + /* We have to convert the name to a single-byte + string. This is possible since the names + consist of ASCII characters and the internal + representation is UCS4. */ + for (strcnt = 0; strcnt < c1; ++strcnt) + str[strcnt] = startp[1 + strcnt]; +# 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); + + /* Locate the character in the hashing + table. */ + hash = elem_hash (str, c1); + + idx = 0; + elem = hash % table_size; + if (symb_table[2 * elem] != 0) + { + second = hash % (table_size - 2) + 1; + + do + { + /* First compare the hashing value. */ + if (symb_table[2 * elem] == hash + && (c1 + == extra[symb_table[2 * elem + 1]]) + && memcmp (str, + &extra[symb_table[2 * elem + 1] + + 1], c1) == 0) + { + /* Yep, this is the entry. */ + idx = symb_table[2 * elem + 1]; + idx += 1 + extra[idx]; + break; + } + + /* Next entry. */ + elem += second; + } + while (symb_table[2 * elem] != 0); + } + + if (symb_table[2 * elem] != 0) + { + /* Compare the byte sequence but only if + this is not part of a range. */ +# ifdef WIDE_CHAR_VERSION + int32_t *wextra; + + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~4; + + wextra = (int32_t *) &extra[idx + 4]; +# endif + /* Get the collation sequence value. */ + is_seqval = true; +# ifdef WIDE_CHAR_VERSION + cend = wextra[1 + wextra[idx]]; +# else + /* Adjust for the alignment. */ + idx += 1 + extra[idx]; + idx = (idx + 3) & ~4; + cend = *((int32_t *) &extra[idx]); +# endif + } + else if (symb_table[2 * elem] != 0 && c1 == 1) + { + cend = str[0]; + c = *p++; + } + else + return FNM_NOMATCH; + } +# undef str + } + 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 ( +# ifdef 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 + { +# ifdef 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; + } +# ifdef 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 (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. */ + do + { + ignore_next: + c = *p++; + + 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; + goto ignore_next; + } + } + p += 2; + c = *p++; + } + 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; + c = *p++; + } + else if (c == L_('[') && *p == L_('.')) + { + ++p; + while (1) + { + c = *++p; + if (c == '\0') + return FNM_NOMATCH; + + if (*p == L_('.') && p[1] == L_(']')) + break; + } + p += 2; + c = *p++; + } + } + while (c != L_(']')); + if (not) + return FNM_NOMATCH; + } + break; + + case L_('+'): + case L_('@'): + case L_('!'): + if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') + { + int res; + + res = EXT (c, p, n, string_end, no_leading_period, flags); + 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 * +internal_function +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); + else if (*p == L_(')')) + break; + + return p + 1; +} + + +static int +internal_function +EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, + bool no_leading_period, int flags) +{ + const CHAR *startp; + size_t level; + struct patternlist + { + struct patternlist *next; + CHAR str[1]; + } *list = NULL; + struct patternlist **lastp = &list; + size_t pattern_len = STRLEN (pattern); + const CHAR *p; + const CHAR *rs; + enum { ALLOCA_LIMIT = 8000 }; + + /* Parse the pattern. Store the individual parts in the list. */ + level = 0; + for (startp = p = pattern + 1; ; ++p) + if (*p == L_('\0')) + /* This is an invalid pattern. */ + return -1; + 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 -1; + } + 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; \ + size_t plensize; \ + size_t newpsize; \ + \ + plen = (opt == L_('?') || opt == L_('@') \ + ? pattern_len \ + : p - startp + 1UL); \ + plensize = plen * sizeof (CHAR); \ + newpsize = offsetof (struct patternlist, str) + plensize; \ + if ((size_t) -1 / sizeof (CHAR) < plen \ + || newpsize < offsetof (struct patternlist, str) \ + || ALLOCA_LIMIT <= newpsize) \ + return -1; \ + newp = (struct patternlist *) alloca (newpsize); \ + *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \ + newp->next = NULL; \ + *lastp = newp; \ + lastp = &newp->next + NEW_PATTERN; + break; + } + } + 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) == 0) + return 0; + /* 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) == 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) == 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) == 0))) + /* It worked. Signal success. */ + return 0; + } + while ((list = list->next) != NULL); + + /* None of the patterns lead to a match. */ + return FNM_NOMATCH; + + case L_('?'): + if (FCT (p, string, string_end, no_leading_period, flags) == 0) + return 0; + /* 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) == 0) + /* It worked. Signal success. */ + return 0; + while ((list = list->next) != NULL); + + /* None of the patterns lead to a match. */ + return FNM_NOMATCH; + + 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) == 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) + == 0)) + /* This is successful. */ + return 0; + } + + /* None of the patterns together with the rest of the pattern + lead to a match. */ + return FNM_NOMATCH; + + default: + assert (! "Invalid extended matching operator"); + break; + } + + return -1; +} + + +#undef FOLD +#undef CHAR +#undef UCHAR +#undef INT +#undef FCT +#undef EXT +#undef END +#undef MEMPCPY +#undef MEMCHR +#undef STRLEN +#undef STRCAT +#undef L_ +#undef BTOWC diff --git a/gnu/fpending.c b/gnu/fpending.c new file mode 100644 index 00000000..2a171654 --- /dev/null +++ b/gnu/fpending.c @@ -0,0 +1,32 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* fpending.c -- return the number of pending output bytes on a stream + Copyright (C) 2000, 2004, 2006-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#include <config.h> + +#include "fpending.h" + +/* Return the number of pending (aka buffered, unflushed) + bytes on the stream, FP, that is open for writing. */ +size_t +__fpending (FILE *fp) +{ + return PENDING_OUTPUT_N_BYTES; +} diff --git a/gnu/fpending.h b/gnu/fpending.h new file mode 100644 index 00000000..b227d140 --- /dev/null +++ b/gnu/fpending.h @@ -0,0 +1,36 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Declare __fpending. + + Copyright (C) 2000, 2003, 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. + + Written by Jim Meyering. */ + +#include <stddef.h> +#include <stdio.h> + +#ifndef HAVE_DECL___FPENDING +"this configure-time declaration test was not run" +#endif + +#if HAVE_DECL___FPENDING +# if HAVE_STDIO_EXT_H +# include <stdio_ext.h> +# endif +#else +size_t __fpending (FILE *); +#endif diff --git a/gnu/fseek.c b/gnu/fseek.c new file mode 100644 index 00000000..234b6cd2 --- /dev/null +++ b/gnu/fseek.c @@ -0,0 +1,32 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* An fseek() function that, together with fflush(), is POSIX compliant. + Copyright (C) 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <stdio.h> + +/* Get off_t. */ +#include <unistd.h> + +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/gnu/fseeko.c b/gnu/fseeko.c new file mode 100644 index 00000000..e0f06d7d --- /dev/null +++ b/gnu/fseeko.c @@ -0,0 +1,145 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* An fseeko() function that, together with fflush(), is POSIX compliant. + Copyright (C) 2007-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include <stdio.h> + +/* Get off_t and lseek. */ +#include <unistd.h> + +#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 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_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__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ +# 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, mingw, NonStop Kernel */ + 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) +#else + #error "Please port gnulib fseeko.c to your platform! Look at the code in fpurge.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__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ + fp_->_flags &= ~__SOFF; +#endif + return -1; + } + +#if 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__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ +# 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; + fp_->_flags &= ~__SEOF; +#elif defined __EMX__ /* emx+gcc */ + fp->_flags &= ~_IOEOF; +#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */ + 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/gnu/fstat.c b/gnu/fstat.c new file mode 100644 index 00000000..f509b4e8 --- /dev/null +++ b/gnu/fstat.c @@ -0,0 +1,84 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* fstat() replacement. + Copyright (C) 2011-2012 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 <http://www.gnu.org/licenses/>. */ + +/* If the user's config.h happens to include <sys/stat.h>, let it include only + the system's <sys/stat.h> here, so that orig_fstat doesn't recurse to + rpl_fstat. */ +#define __need_system_sys_stat_h +#include <config.h> + +/* Get the original definition of fstat. It might be defined as a macro. */ +#include <sys/types.h> +#include <sys/stat.h> +#undef __need_system_sys_stat_h + +static inline int +orig_fstat (int fd, struct stat *buf) +{ + return fstat (fd, buf); +} + +/* Specification. */ +/* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc + eliminates this include because of the preliminary #include <sys/stat.h> + above. */ +#include "sys/stat.h" + +#include <errno.h> +#include <unistd.h> + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +#endif + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static inline int +fstat_nothrow (int fd, struct stat *buf) +{ + int result; + + TRY_MSVC_INVAL + { + result = orig_fstat (fd, buf); + } + CATCH_MSVC_INVAL + { + result = -1; + errno = EBADF; + } + DONE_MSVC_INVAL; + + return result; +} +#else +# define fstat_nothrow orig_fstat +#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 + + return fstat_nothrow (fd, buf); +} diff --git a/gnu/fstatat.c b/gnu/fstatat.c new file mode 100644 index 00000000..9d8a57e8 --- /dev/null +++ b/gnu/fstatat.c @@ -0,0 +1,137 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Work around an fstatat bug on Solaris 9. + + Copyright (C) 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert and Jim Meyering. */ + +/* If the user's config.h happens to include <sys/stat.h>, let it include only + the system's <sys/stat.h> here, so that orig_fstatat doesn't recurse to + rpl_fstatat. */ +#define __need_system_sys_stat_h +#include <config.h> + +/* Get the original definition of fstatat. It might be defined as a macro. */ +#include <sys/types.h> +#include <sys/stat.h> +#undef __need_system_sys_stat_h + +#if HAVE_FSTATAT +static inline int +orig_fstatat (int fd, char const *filename, struct stat *buf, int flags) +{ + return fstatat (fd, filename, buf, flags); +} +#endif + +/* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc + eliminates this include because of the preliminary #include <sys/stat.h> + above. */ +#include "sys/stat.h" + +#include <errno.h> +#include <fcntl.h> +#include <string.h> + +#if HAVE_FSTATAT && HAVE_WORKING_FSTATAT_ZERO_FLAG + +# ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK +# define LSTAT_FOLLOWS_SLASHED_SYMLINK 0 +# endif + +/* 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 = orig_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 = orig_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 <sys/stat.h> 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 inline int +stat_func (char const *name, struct stat *st) +{ + return stat (name, st); +} + +/* Likewise, if there is no native 'lstat', then the gnulib + <sys/stat.h> 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. + <http://www.google.com/search?q=fstatat+site:docs.sun.com> + 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/gnu/full-write.c b/gnu/full-write.c new file mode 100644 index 00000000..5bca726f --- /dev/null +++ b/gnu/full-write.c @@ -0,0 +1,81 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* An interface to read and write that retries (if necessary) until complete. + + Copyright (C) 1993-1994, 1997-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#ifdef FULL_READ +# include "full-read.h" +#else +# include "full-write.h" +#endif + +#include <errno.h> + +#ifdef FULL_READ +# include "safe-read.h" +# define safe_rw safe_read +# define full_rw full_read +# undef const +# define const /* empty */ +#else +# include "safe-write.h" +# define safe_rw safe_write +# define full_rw full_write +#endif + +#ifdef FULL_READ +/* Set errno to zero upon EOF. */ +# define ZERO_BYTE_TRANSFER_ERRNO 0 +#else +/* Some buggy drivers return 0 when one tries to write beyond + a device's end. (Example: Linux 1.2.13 on /dev/fd0.) + Set errno to ENOSPC so they get a sensible diagnostic. */ +# define ZERO_BYTE_TRANSFER_ERRNO ENOSPC +#endif + +/* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if + interrupted or if a partial write(read) occurs. Return the number + of bytes transferred. + When writing, set errno if fewer than COUNT bytes are written. + When reading, if fewer than COUNT bytes are read, you must examine + errno to distinguish failure from EOF (errno == 0). */ +size_t +full_rw (int fd, const void *buf, size_t count) +{ + size_t total = 0; + const char *ptr = (const char *) buf; + + while (count > 0) + { + size_t n_rw = safe_rw (fd, ptr, count); + if (n_rw == (size_t) -1) + break; + if (n_rw == 0) + { + errno = ZERO_BYTE_TRANSFER_ERRNO; + break; + } + total += n_rw; + ptr += n_rw; + count -= n_rw; + } + + return total; +} diff --git a/gnu/full-write.h b/gnu/full-write.h new file mode 100644 index 00000000..30e4efb8 --- /dev/null +++ b/gnu/full-write.h @@ -0,0 +1,36 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* An interface to write() that writes all it is asked to write. + + Copyright (C) 2002-2003, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <stddef.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Write COUNT bytes at BUF to descriptor FD, retrying if interrupted + or if partial writes occur. Return the number of bytes successfully + written, setting errno if that is less than COUNT. */ +extern size_t full_write (int fd, const void *buf, size_t count); + + +#ifdef __cplusplus +} +#endif diff --git a/gnu/futimens.c b/gnu/futimens.c new file mode 100644 index 00000000..99556a5b --- /dev/null +++ b/gnu/futimens.c @@ -0,0 +1,39 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Set the access and modification time of an open fd. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <sys/stat.h> + +#include "utimens.h" + +/* Set the access and modification time stamps 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 time stamps 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/gnu/getcwd-lgpl.c b/gnu/getcwd-lgpl.c new file mode 100644 index 00000000..a27be830 --- /dev/null +++ b/gnu/getcwd-lgpl.c @@ -0,0 +1,127 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 2011-2012 Free Software Foundation, Inc. + This file is part of gnulib. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification */ +#include <unistd.h> + +#include <errno.h> +#include <string.h> + +#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 +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) + { + int saved_errno = errno; + free (buf); + errno = saved_errno; + } + 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) + { + int saved_errno = errno; + free (buf); + errno = saved_errno; + } + else + { + /* Trim to fit, if possible. */ + result = realloc (buf, strlen (buf) + 1); + if (!result) + result = buf; + } + return result; +} + +#endif diff --git a/gnu/getcwd.c b/gnu/getcwd.c new file mode 100644 index 00000000..0982cd9b --- /dev/null +++ b/gnu/getcwd.c @@ -0,0 +1,444 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1991-1999, 2004-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#if !_LIBC +# include <config.h> +# include <unistd.h> +#endif + +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdbool.h> +#include <stddef.h> + +#include <fcntl.h> /* For AT_FDCWD on Solaris 9. */ + +/* If this host provides the openat function or if we're using the + gnulib replacement function, then enable code below to make getcwd + more efficient and robust. */ +#if defined HAVE_OPENAT || defined GNULIB_OPENAT +# define HAVE_OPENAT_SUPPORT 1 +#else +# define HAVE_OPENAT_SUPPORT 0 +#endif + +#ifndef __set_errno +# define __set_errno(val) (errno = (val)) +#endif + +#include <dirent.h> +#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 <unistd.h> +#include <stdlib.h> +#include <string.h> + +#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 + +#include "pathmax.h" + +/* 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 !_LIBC +# define __getcwd rpl_getcwd +# define __lstat lstat +# define __closedir closedir +# define __opendir opendir +# define __readdir readdir +#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. */ +#undef opendir +#undef closedir + +/* 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 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. */ + +char * +__getcwd (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 stat st; + size_t allocated = size; + size_t used; + +#if HAVE_RAW_DECL_GETCWD && 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 (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 (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 (__lstat (".", &st) < 0) + goto lose; + thisdev = st.st_dev; + thisino = st.st_ino; + + if (__lstat ("/", &st) < 0) + goto lose; + rootdev = st.st_dev; + rootino = st.st_ino; + + while (!(thisdev == rootdev && thisino == rootino)) + { + struct dirent *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 = openat (fd, "..", O_RDONLY); + if (fd < 0) + goto lose; + fd_needs_closing = true; + parent_status = fstat (fd, &st); +#else + dotlist[dotlen++] = '.'; + dotlist[dotlen++] = '.'; + dotlist[dotlen] = '\0'; + parent_status = __lstat (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 = __readdir (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 = __readdir (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 = fstatat (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 = __lstat (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 = realloc (dir, used); + + 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 (fd); +#else + if (dotlist != dots) + free (dotlist); +#endif + if (buf == NULL) + free (dir); + __set_errno (save); + } + return NULL; +} + +#ifdef weak_alias +weak_alias (__getcwd, getcwd) +#endif diff --git a/gnu/getdelim.c b/gnu/getdelim.c new file mode 100644 index 00000000..5736076d --- /dev/null +++ b/gnu/getdelim.c @@ -0,0 +1,139 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* getdelim.c --- Implementation of replacement getdelim function. + Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2012 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Ported from glibc by Simon Josefsson. */ + +#include <config.h> + +/* 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 <stdio.h> + +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <errno.h> + +#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 + +/* 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) + { + 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) + { + 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/gnu/getdtablesize.c b/gnu/getdtablesize.c new file mode 100644 index 00000000..10603694 --- /dev/null +++ b/gnu/getdtablesize.c @@ -0,0 +1,88 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* getdtablesize() function for platforms that don't have it. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +#include <stdio.h> + +#include "msvc-inval.h" + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static inline int +_setmaxstdio_nothrow (int newmax) +{ + int result; + + TRY_MSVC_INVAL + { + result = _setmaxstdio (newmax); + } + CATCH_MSVC_INVAL + { + result = -1; + } + DONE_MSVC_INVAL; + + return result; +} +# define _setmaxstdio _setmaxstdio_nothrow +#endif + +/* Cache for the previous getdtablesize () result. */ +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 (bound) < 0; bound = bound / 2) + ; + _setmaxstdio (orig_max_stdio); + dtablesize = bound; + } + return dtablesize; +} + +#endif diff --git a/gnu/getline.c b/gnu/getline.c new file mode 100644 index 00000000..01a9329f --- /dev/null +++ b/gnu/getline.c @@ -0,0 +1,31 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* getline.c --- Implementation of replacement getline function. + Copyright (C) 2005-2007, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Written by Simon Josefsson. */ + +#include <config.h> + +#include <stdio.h> + +ssize_t +getline (char **lineptr, size_t *n, FILE *stream) +{ + return getdelim (lineptr, n, '\n', stream); +} diff --git a/gnu/getopt.c b/gnu/getopt.c new file mode 100644 index 00000000..afe9f640 --- /dev/null +++ b/gnu/getopt.c @@ -0,0 +1,1247 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Getopt for GNU. + NOTE: getopt is part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2012 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _LIBC +# include <config.h> +#endif + +#include "getopt.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifdef _LIBC +# include <libintl.h> +#else +# include "gettext.h" +# define _(msgid) gettext (msgid) +#endif + +#if defined _LIBC && defined USE_IN_LIBIO +# include <wchar.h> +#endif + +/* This version of 'getopt' appears to the caller like standard Unix 'getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As 'getopt_long' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Using 'getopt' or setting the environment variable POSIXLY_CORRECT + disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#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; + + +#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV +extern char *getenv (); +#endif + +#ifdef _LIBC +/* Stored original parameters. + XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ +extern int __libc_argc; +extern char **__libc_argv; + +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +# ifdef USE_NONOPTION_FLAGS +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; +# endif + +# ifdef USE_NONOPTION_FLAGS +# define SWAP_FLAGS(ch1, ch2) \ + if (d->__nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + 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. */ + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the '__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + d->__nonoption_flags_max_len), + '\0', top + 1 - d->__nonoption_flags_max_len); + d->__nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + d->__first_nonopt += (d->optind - d->__last_nonopt); + d->__last_nonopt = d->optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (int argc _GL_UNUSED, + char **argv _GL_UNUSED, 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. */ + + d->__first_nonopt = d->__last_nonopt = d->optind; + + d->__nextchar = NULL; + + d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + d->__ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + d->__ordering = REQUIRE_ORDER; + ++optstring; + } + else if (d->__posixly_correct) + d->__ordering = REQUIRE_ORDER; + else + d->__ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (!d->__posixly_correct + && argc == __libc_argc && argv == __libc_argv) + { + if (d->__nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + d->__nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = d->__nonoption_flags_max_len = strlen (orig_str); + if (d->__nonoption_flags_max_len < argc) + d->__nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (d->__nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + d->__nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', d->__nonoption_flags_max_len - len); + } + } + d->__nonoption_flags_len = d->__nonoption_flags_max_len; + } + else + d->__nonoption_flags_len = 0; +#endif + + 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) + { + if (d->optind == 0) + d->optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring, d, + posixly_correct); + d->__initialized = 1; + } + else if (optstring[0] == '-' || optstring[0] == '+') + optstring++; + if (optstring[0] == ':') + print_errors = 0; + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ + || (d->optind < d->__nonoption_flags_len \ + && __getopt_nonoption_flags[d->optind] == '1')) +#else +# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') +#endif + + 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 ((char **) 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 ((char **) 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. + Skip the initial punctuation. */ + + d->__nextchar = (argv[d->optind] + 1 + + (longopts != NULL && argv[d->optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[d->optind][1] == '-' + || (long_only && (argv[d->optind][2] + || !strchr (optstring, argv[d->optind][1]))))) + { + char *nameend; + unsigned int namelen; + const struct option *p; + const struct option *pfound = NULL; + struct option_list + { + const struct option *p; + struct option_list *next; + } *ambig_list = NULL; + int exact = 0; + int indfound = -1; + int option_index; + + for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + namelen = nameend - d->__nextchar; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, d->__nextchar, namelen)) + { + if (namelen == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + { + /* Second or later nonexact match found. */ + struct option_list *newp = malloc (sizeof (*newp)); + newp->p = p; + newp->next = ambig_list; + ambig_list = newp; + } + } + + if (ambig_list != NULL && !exact) + { + if (print_errors) + { + struct option_list first; + first.p = pfound; + first.next = ambig_list; + ambig_list = &first; + +#if defined _LIBC && defined USE_IN_LIBIO + char *buf = NULL; + size_t buflen = 0; + + FILE *fp = open_memstream (&buf, &buflen); + if (fp != NULL) + { + fprintf (fp, + _("%s: option '%s' is ambiguous; possibilities:"), + argv[0], argv[d->optind]); + + do + { + fprintf (fp, " '--%s'", ambig_list->p->name); + ambig_list = ambig_list->next; + } + while (ambig_list != NULL); + + fputc_unlocked ('\n', fp); + + if (__builtin_expect (fclose (fp) != EOF, 1)) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } + } +#else + fprintf (stderr, + _("%s: option '%s' is ambiguous; possibilities:"), + argv[0], argv[d->optind]); + do + { + fprintf (stderr, " '--%s'", ambig_list->p->name); + ambig_list = ambig_list->next; + } + while (ambig_list != NULL); + + fputc ('\n', stderr); +#endif + } + d->__nextchar += strlen (d->__nextchar); + d->optind++; + d->optopt = 0; + return '?'; + } + + while (ambig_list != NULL) + { + struct option_list *pn = ambig_list->next; + free (ambig_list); + ambig_list = pn; + } + + if (pfound != NULL) + { + option_index = indfound; + d->optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + + if (argv[d->optind - 1][1] == '-') + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option '--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#else + fprintf (stderr, _("\ +%s: option '--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option '%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); +#else + fprintf (stderr, _("\ +%s: option '%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif + } + + d->__nextchar += strlen (d->__nextchar); + + d->optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option '--%s' requires an argument\n"), + argv[0], pfound->name) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option '--%s' requires an argument\n"), + argv[0], pfound->name); +#endif + } + d->__nextchar += strlen (d->__nextchar); + d->optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + d->__nextchar += strlen (d->__nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[d->optind][1] == '-' + || strchr (optstring, *d->__nextchar) == NULL) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + + if (argv[d->optind][1] == '-') + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"), + argv[0], d->__nextchar); +#else + fprintf (stderr, _("%s: unrecognized option '--%s'\n"), + argv[0], d->__nextchar); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); +#else + fprintf (stderr, _("%s: unrecognized option '%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif + } + d->__nextchar = (char *) ""; + d->optind++; + d->optopt = 0; + return '?'; + } + } + + /* 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) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); +#endif + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif + } + d->optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + if (longopts == NULL) + goto no_longs; + + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); +#endif + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented 'd->optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; + nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) + { + if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"), + argv[0], d->optarg) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"), + argv[0], d->optarg); +#endif + } + d->__nextchar += strlen (d->__nextchar); + d->optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option '-W %s' doesn't allow an argument\n"), + argv[0], pfound->name) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("\ +%s: option '-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + + d->__nextchar += strlen (d->__nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option '-W %s' requires an argument\n"), + argv[0], pfound->name) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("\ +%s: option '-W %s' requires an argument\n"), + argv[0], pfound->name); +#endif + } + d->__nextchar += strlen (d->__nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + else + d->optarg = NULL; + d->__nextchar += strlen (d->__nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + no_longs: + d->__nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + d->optind++; + } + else + d->optarg = NULL; + d->__nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option requires an argument -- '%c'\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); +#endif + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented 'optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + d->__nextchar = NULL; + } + } + 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. + Standalone applications get a POSIX-compliant getopt. */ +#if _LIBC +enum { POSIXLY_CORRECT = 0 }; +#else +enum { POSIXLY_CORRECT = 1 }; +#endif + +int +getopt (int argc, char *const *argv, const char *optstring) +{ + return _getopt_internal (argc, (char **) argv, optstring, + (const struct option *) 0, + (int *) 0, + 0, POSIXLY_CORRECT); +} + +#ifdef _LIBC +int +__posix_getopt (int argc, char *const *argv, const char *optstring) +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0, 1); +} +#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/gnu/getopt.in.h b/gnu/getopt.in.h new file mode 100644 index 00000000..c27f99a9 --- /dev/null +++ b/gnu/getopt.in.h @@ -0,0 +1,255 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Declarations for getopt. + Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2007, 2009-2012 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#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 + <getopt.h>; 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 + +#ifndef _@GUARD_PREFIX@_GETOPT_H + +#ifndef __need_getopt +# define _@GUARD_PREFIX@_GETOPT_H 1 +#endif + +/* Standalone applications should #define __GETOPT_PREFIX to an + identifier that prefixes the external functions and variables + defined in this header. When this happens, include the + headers that might declare getopt so that they will not cause + confusion if included after this file (if the system had <getopt.h>, + we have already included it). Then systematically rename + identifiers so that they do not collide with the system functions + and variables. Renaming avoids problems with some compilers and + linkers. */ +#if defined __GETOPT_PREFIX && !defined __need_getopt +# if !@HAVE_GETOPT_H@ +# include <stdlib.h> +# include <stdio.h> +# include <unistd.h> +# endif +# undef __need_getopt +# undef getopt +# undef getopt_long +# undef getopt_long_only +# undef optarg +# undef opterr +# undef optind +# undef optopt +# undef option +# define __GETOPT_CONCAT(x, y) x ## y +# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) +# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) +# define getopt __GETOPT_ID (getopt) +# define getopt_long __GETOPT_ID (getopt_long) +# define getopt_long_only __GETOPT_ID (getopt_long_only) +# define optarg __GETOPT_ID (optarg) +# define opterr __GETOPT_ID (opterr) +# define optind __GETOPT_ID (optind) +# define optopt __GETOPT_ID (optopt) +# define option __GETOPT_ID (option) +# define _getopt_internal __GETOPT_ID (getopt_internal) +#endif + +/* Standalone applications get correct prototypes for getopt_long and + getopt_long_only; they declare "char **argv". libc uses prototypes + with "char *const *argv" that are incorrect because getopt_long and + getopt_long_only can permute argv; this is required for backward + compatibility (e.g., for LSB 2.0.1). + + This used to be '#if defined __GETOPT_PREFIX && !defined __need_getopt', + but it caused redefinition warnings if both unistd.h and getopt.h were + included, since unistd.h includes getopt.h having previously defined + __need_getopt. + + The only place where __getopt_argv_const is used is in definitions + of getopt_long and getopt_long_only below, but these are visible + only if __need_getopt is not defined, so it is quite safe to rewrite + the conditional as follows: +*/ +#if !defined __need_getopt +# if defined __GETOPT_PREFIX +# define __getopt_argv_const /* empty */ +# else +# define __getopt_argv_const const +# endif +#endif + +/* If __GNU_LIBRARY__ is not already defined, either we are being used + standalone, or this is the first header included in the source file. + If we are being used with glibc, we need to include <features.h>, but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include <ctype.h>, which will pull in <features.h> for us + if it's from glibc. (Why ctype.h? It's guaranteed to exist and it + doesn't flood the namespace with stuff the way some other headers do.) */ +#if !defined __GNU_LIBRARY__ +# include <ctype.h> +#endif + +#ifndef __THROW +# ifndef __GNUC_PREREQ +# define __GNUC_PREREQ(maj, min) (0) +# endif +# if defined __cplusplus && __GNUC_PREREQ (2,8) +# define __THROW throw () +# else +# define __THROW +# endif +#endif + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from 'getopt' to the caller. + When 'getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when 'ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to 'getopt'. + + On entry to 'getopt', zero means this is the first call; initialize. + + When 'getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, 'optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message 'getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of 'struct option' terminated by an element containing a name which is + zero. + + The field 'has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field 'flag' is not NULL, it points to a variable that is set + to the value given in the field 'val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an 'int' to + a compiled-in constant, such as set a value from 'optarg', set the + option's 'flag' field to zero and its 'val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero 'flag' field, 'getopt' + returns the contents of the 'val' field. */ + +# if !GNULIB_defined_struct_option +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; +# define GNULIB_defined_struct_option 1 +# endif + +/* Names for the values of the 'has_arg' field of 'struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, 'optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in 'optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU 'getopt'. + + The argument '--' causes premature termination of argument + scanning, explicitly telling 'getopt' that there are no more + options. + + If OPTS begins with '-', then non-option arguments are treated as + arguments to the option '\1'. This behavior is specific to the GNU + 'getopt'. If OPTS begins with '+', or POSIXLY_CORRECT is set in + the environment, then do not permute arguments. */ + +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) + __THROW _GL_ARG_NONNULL ((2, 3)); + +#ifndef __need_getopt +extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW _GL_ARG_NONNULL ((2, 3)); +extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW _GL_ARG_NONNULL ((2, 3)); + +#endif + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* _@GUARD_PREFIX@_GETOPT_H */ +#endif /* _@GUARD_PREFIX@_GETOPT_H */ diff --git a/gnu/getopt1.c b/gnu/getopt1.c new file mode 100644 index 00000000..a769430d --- /dev/null +++ b/gnu/getopt1.c @@ -0,0 +1,172 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987-1994, 1996-1998, 2004, 2006, 2009-2012 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#ifdef _LIBC +# include <getopt.h> +#else +# include <config.h> +# include "getopt.h" +#endif +#include "getopt_int.h" + +#include <stdio.h> + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include <stdlib.h> +#endif + +#ifndef NULL +#define NULL 0 +#endif + +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 <stdio.h> + +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/gnu/getopt_int.h b/gnu/getopt_int.h new file mode 100644 index 00000000..b93a5384 --- /dev/null +++ b/gnu/getopt_int.h @@ -0,0 +1,137 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Internal declarations for getopt. + Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2004, 2009-2012 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _GETOPT_INT_H +#define _GETOPT_INT_H 1 + +#include <getopt.h> + +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. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using '+' as the first character + of the list of option characters, or by calling getopt. + + PERMUTE is the default. We permute the contents of ARGV as we + scan, so that eventually all the non-options are at the end. + This allows options to be given in any order, even with programs + that were not written to expect this. + + RETURN_IN_ORDER is an option available to programs that were + written to expect options and other ARGV-elements in any order + and that care about the ordering of the two. We describe each + non-option ARGV-element as if it were the argument of an option + with character code 1. Using '-' as the first character of the + list of option characters selects this mode of operation. + + 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; + + /* If the POSIXLY_CORRECT environment variable is set + or getopt was called. */ + int __posixly_correct; + + + /* Handle permutation of arguments. */ + + /* Describe the part of ARGV that contains non-options that have + 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; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + int __nonoption_flags_max_len; + int __nonoption_flags_len; +#endif +}; + +/* The initializer is necessary to set OPTIND and OPTERR to their + default values and to clear the initialization flag. */ +#define _GETOPT_DATA_INITIALIZER { 1, 1 } + +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/gnu/getpagesize.c b/gnu/getpagesize.c new file mode 100644 index 00000000..61ba89c5 --- /dev/null +++ b/gnu/getpagesize.c @@ -0,0 +1,41 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* getpagesize emulation for systems where it cannot be done in a C macro. + + Copyright (C) 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible and Martin Lambers. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +/* This implementation is only for native Windows systems. */ +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN +# include <windows.h> + +int +getpagesize (void) +{ + SYSTEM_INFO system_info; + GetSystemInfo (&system_info); + return system_info.dwPageSize; +} + +#endif diff --git a/gnu/gettext.h b/gnu/gettext.h new file mode 100644 index 00000000..f9274c3b --- /dev/null +++ b/gnu/gettext.h @@ -0,0 +1,288 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convenience header for conditional use of GNU <libintl.h>. + Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2012 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include <libintl.h> + +/* 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 <locale.h> a NOP. We don't include <libintl.h> + as well because people using "gettext.h" will not include <libintl.h>, + and also including <libintl.h> would fail on SunOS 4, whereas <locale.h> + is OK. */ +#if defined(__sun) +# include <locale.h> +#endif + +/* Many header files from the libstdc++ coming with g++ 3.3 or newer include + <libintl.h>, which chokes if dcgettext is defined as a macro. So include + it now, to make later inclusions of <libintl.h> a NOP. */ +#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) +# include <cstdlib> +# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H +# include <libintl.h> +# 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) + +#ifdef __GNUC__ +__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; +} + +#ifdef __GNUC__ +__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 <string.h> + +#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ + (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ + /* || __STDC_VERSION__ >= 199901L */ ) + +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS +#include <stdlib.h> +#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) + +#ifdef __GNUC__ +__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 + { + 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); +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + if (msg_ctxt_id != buf) + free (msg_ctxt_id); +#endif + if (translation != msg_ctxt_id) + 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) + +#ifdef __GNUC__ +__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 + { + 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); +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + if (msg_ctxt_id != buf) + free (msg_ctxt_id); +#endif + if (!(translation == msg_ctxt_id || translation == msgid_plural)) + return translation; + } + return (n == 1 ? msgid : msgid_plural); +} + +#endif /* _LIBGETTEXT_H */ diff --git a/gnu/gettime.c b/gnu/gettime.c new file mode 100644 index 00000000..4fc74064 --- /dev/null +++ b/gnu/gettime.c @@ -0,0 +1,50 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* gettime -- get the system clock + + Copyright (C) 2002, 2004-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +#include "timespec.h" + +#include <sys/time.h> + +/* Get the system time into *TS. */ + +void +gettime (struct timespec *ts) +{ +#if HAVE_NANOTIME + nanotime (ts); +#else + +# if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME + if (clock_gettime (CLOCK_REALTIME, ts) == 0) + return; +# endif + + { + struct timeval tv; + gettimeofday (&tv, NULL); + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; + } + +#endif +} diff --git a/gnu/gettimeofday.c b/gnu/gettimeofday.c new file mode 100644 index 00000000..85462ea9 --- /dev/null +++ b/gnu/gettimeofday.c @@ -0,0 +1,146 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Provide gettimeofday for systems that don't have it or for which it's broken. + + Copyright (C) 2001-2003, 2005-2007, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* written by Jim Meyering */ + +#include <config.h> + +/* Specification. */ +#include <sys/time.h> + +#include <time.h> + +#if HAVE_SYS_TIMEB_H +# include <sys/timeb.h> +#endif + +#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME + +/* 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. The tzset replacement is necessary for at least + Solaris 2.5, 2.5.1, and 2.6. */ + +static struct tm tm_zero_buffer; +static struct tm *localtime_buffer_addr = &tm_zero_buffer; + +# undef localtime +extern struct tm *localtime (time_t const *); + +# undef gmtime +extern struct tm *gmtime (time_t const *); + +/* This is a wrapper for localtime. It is used only on systems for which + gettimeofday clobbers the static buffer used for localtime's result. + + On the first call, record the address of the static buffer that + localtime uses for its result. */ + +struct tm * +rpl_localtime (time_t const *timep) +{ + struct tm *tm = localtime (timep); + + if (localtime_buffer_addr == &tm_zero_buffer) + localtime_buffer_addr = tm; + + return tm; +} + +/* Same as above, since gmtime and localtime use the same buffer. */ +struct tm * +rpl_gmtime (time_t const *timep) +{ + struct tm *tm = gmtime (timep); + + if (localtime_buffer_addr == &tm_zero_buffer) + localtime_buffer_addr = tm; + + return tm; +} + +#endif /* GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME */ + +#if TZSET_CLOBBERS_LOCALTIME + +# undef tzset +extern void tzset (void); + +/* This is a wrapper for tzset, for systems on which tzset may clobber + the static buffer used for localtime's result. */ +void +rpl_tzset (void) +{ + /* Save and restore the contents of the buffer used for localtime's + result around the call to tzset. */ + struct tm save = *localtime_buffer_addr; + tzset (); + *localtime_buffer_addr = save; +} +#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. */ + +int +gettimeofday (struct timeval *restrict tv, void *restrict tz) +{ +#undef gettimeofday +#if HAVE_GETTIMEOFDAY +# if GETTIMEOFDAY_CLOBBERS_LOCALTIME + /* Save and restore the contents of the buffer used for localtime's + result around the call to gettimeofday. */ + struct tm save = *localtime_buffer_addr; +# endif + + int result = gettimeofday (tv, (struct timezone *) tz); + +# if GETTIMEOFDAY_CLOBBERS_LOCALTIME + *localtime_buffer_addr = save; +# endif + + return result; + +#else + +# if HAVE__FTIME + + struct _timeb timebuf; + _ftime (&timebuf); + tv->tv_sec = timebuf.time; + tv->tv_usec = timebuf.millitm * 1000; + +# 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; + +# endif + + return 0; + +#endif +} diff --git a/gnu/hash.c b/gnu/hash.c new file mode 100644 index 00000000..66df08dd --- /dev/null +++ b/gnu/hash.c @@ -0,0 +1,1235 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* hash - hashing table processing. + + Copyright (C) 1998-2004, 2006-2007, 2009-2012 Free Software Foundation, Inc. + + Written by Jim Meyering, 1992. + + 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 <http://www.gnu.org/licenses/>. */ + +/* 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 <config.h> + +#include "hash.h" + +#include "bitrotate.h" +#include "xalloc-oversized.h" + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#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. */ + +/* 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. */ + +size_t +hash_get_n_buckets (const Hash_table *table) +{ + return table->n_buckets; +} + +/* Return the number of slots in use (non-empty buckets). */ + +size_t +hash_get_n_buckets_used (const Hash_table *table) +{ + return table->n_buckets_used; +} + +/* Return the number of active entries. */ + +size_t +hash_get_n_entries (const Hash_table *table) +{ + return table->n_entries; +} + +/* Return the length of the longest chain (bucket). */ + +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; +} + +/* Do a mild validation of a hash table, by traversing it and checking two + statistics. */ + +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; +} + +/* If ENTRY matches an entry already in the hash table, return the + entry from the table. Otherwise, return NULL. */ + +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. */ + +/* 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. */ + +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; +} + +/* 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. */ + +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; +} + +/* 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. */ + +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; +} + +/* 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. */ + +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. */ + +/* 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. */ + +#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 (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; +} + +/* 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. */ + +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; +} + +/* 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. */ + +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; +} + +/* 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. */ + +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; +} + +/* 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. */ + +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; +} + +/* 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. */ +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 (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; +} + +/* hash_insert0 is the deprecated name for hash_insert_if_absent. + . */ +int +hash_insert0 (Hash_table *table, void const *entry, void const **matched_ent) +{ + return hash_insert_if_absent (table, entry, matched_ent); +} + +/* 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. */ + +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)); +} + +/* 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. */ + +void * +hash_delete (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; +} + +/* 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/gnu/hash.h b/gnu/hash.h new file mode 100644 index 00000000..27aa86a6 --- /dev/null +++ b/gnu/hash.h @@ -0,0 +1,109 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* hash - hashing table processing. + Copyright (C) 1998-1999, 2001, 2003, 2009-2012 Free Software Foundation, + Inc. + Written by Jim Meyering <meyering@ascend.com>, 1998. + + 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 <http://www.gnu.org/licenses/>. */ + +/* 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 <stdio.h> +# include <stdbool.h> + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The warn_unused_result attribute appeared first in gcc-3.4.0. */ +# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# define _GL_ATTRIBUTE_WUR __attribute__ ((__warn_unused_result__)) +# else +# define _GL_ATTRIBUTE_WUR /* empty */ +# endif + +# ifndef _GL_ATTRIBUTE_DEPRECATED +/* The __attribute__((__deprecated__)) feature + is available in gcc versions 3.1 and newer. */ +# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 1) +# define _GL_ATTRIBUTE_DEPRECATED /* empty */ +# else +# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) +# endif +# endif + +typedef size_t (*Hash_hasher) (const void *, size_t); +typedef bool (*Hash_comparator) (const void *, const void *); +typedef void (*Hash_data_freer) (void *); +typedef bool (*Hash_processor) (void *, void *); + +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. */ +size_t hash_get_n_buckets (const Hash_table *) _GL_ATTRIBUTE_PURE; +size_t hash_get_n_buckets_used (const Hash_table *) _GL_ATTRIBUTE_PURE; +size_t hash_get_n_entries (const Hash_table *) _GL_ATTRIBUTE_PURE; +size_t hash_get_max_bucket_length (const Hash_table *) _GL_ATTRIBUTE_PURE; +bool hash_table_ok (const Hash_table *) _GL_ATTRIBUTE_PURE; +void hash_print_statistics (const Hash_table *, FILE *); +void *hash_lookup (const Hash_table *, const void *); + +/* Walking. */ +void *hash_get_first (const Hash_table *) _GL_ATTRIBUTE_PURE; +void *hash_get_next (const Hash_table *, const void *); +size_t hash_get_entries (const Hash_table *, void **, size_t); +size_t hash_do_for_each (const Hash_table *, Hash_processor, void *); + +/* Allocation and clean-up. */ +size_t hash_string (const char *, size_t) _GL_ATTRIBUTE_PURE; +void hash_reset_tuning (Hash_tuning *); +Hash_table *hash_initialize (size_t, const Hash_tuning *, + Hash_hasher, Hash_comparator, + Hash_data_freer) _GL_ATTRIBUTE_WUR; +void hash_clear (Hash_table *); +void hash_free (Hash_table *); + +/* Insertion and deletion. */ +bool hash_rehash (Hash_table *, size_t) _GL_ATTRIBUTE_WUR; +void *hash_insert (Hash_table *, const void *) _GL_ATTRIBUTE_WUR; + +/* Deprecate this interface. It has been renamed to hash_insert_if_absent. */ +int hash_insert0 (Hash_table *table, /* FIXME: remove in 2013 */ + const void *entry, + const void **matched_ent) _GL_ATTRIBUTE_DEPRECATED; +int hash_insert_if_absent (Hash_table *table, const void *entry, + const void **matched_ent); +void *hash_delete (Hash_table *, const void *); + +#endif diff --git a/gnu/human.c b/gnu/human.c new file mode 100644 index 00000000..41dcb444 --- /dev/null +++ b/gnu/human.c @@ -0,0 +1,472 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* human.c -- print human readable file size + + Copyright (C) 1996-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert and Larry McVoy. */ + +#include <config.h> + +#include "human.h" + +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <argmatch.h> +#include <error.h> +#include <intprops.h> + +/* The maximum length of a suffix like "KiB". */ +#define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3 + +static const char power_letter[] = +{ + 0, /* not used */ + 'K', /* kibi ('k' for kilo is a special case) */ + 'M', /* mega or mebi */ + 'G', /* giga or gibi */ + 'T', /* tera or tebi */ + 'P', /* peta or pebi */ + 'E', /* exa or exbi */ + 'Z', /* zetta or 2**70 */ + 'Y' /* yotta or 2**80 */ +}; + + +/* If INEXACT_STYLE is not human_round_to_nearest, and if easily + possible, adjust VALUE according to the style. */ + +static long double +adjust_value (int inexact_style, long double value) +{ + /* Do not use the floorl or ceill functions, as that would mean + checking for their presence and possibly linking with the + standard math library, which is a porting pain. So leave the + value alone if it is too large to easily round. */ + if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX) + { + uintmax_t u = value; + value = u + (inexact_style == human_ceiling && u != value); + } + + return value; +} + +/* Group the digits of NUMBER according to the grouping rules of the + current locale. NUMBER contains NUMBERLEN digits. Modify the + bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for + each byte inserted. Return the starting address of the modified + number. + + To group the digits, use GROUPING and THOUSANDS_SEP as in 'struct + lconv' from <locale.h>. */ + +static char * +group_number (char *number, size_t numberlen, + char const *grouping, char const *thousands_sep) +{ + register char *d; + size_t grouplen = SIZE_MAX; + size_t thousands_seplen = strlen (thousands_sep); + size_t i = numberlen; + + /* The maximum possible value for NUMBERLEN is the number of digits + in the square of the largest uintmax_t, so double the size needed. */ + char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1]; + + memcpy (buf, number, numberlen); + d = number + numberlen; + + for (;;) + { + unsigned char g = *grouping; + + if (g) + { + grouplen = g < CHAR_MAX ? g : i; + grouping++; + } + + if (i < grouplen) + grouplen = i; + + d -= grouplen; + i -= grouplen; + memcpy (d, buf + i, grouplen); + if (i == 0) + return d; + + d -= thousands_seplen; + memcpy (d, thousands_sep, thousands_seplen); + } +} + +/* Convert N to a human readable format in BUF, using the options OPTS. + + N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must + be nonnegative. + + Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE + must be positive. + + Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling)) + to determine whether to take the ceiling or floor of any result + that cannot be expressed exactly. + + If (OPTS & human_group_digits), group the thousands digits + according to the locale, e.g., "1,000,000" in an American English + locale. + + If (OPTS & human_autoscale), deduce the output block size + automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the + output. Use powers of 1024 if (OPTS & human_base_1024), and powers + of 1000 otherwise. For example, assuming powers of 1024, 8500 + would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and + so on. Numbers smaller than the power aren't modified. + human_autoscale is normally used together with human_SI. + + If (OPTS & human_space_before_unit), use a space to separate the + number from any suffix that is appended as described below. + + If (OPTS & human_SI), append an SI prefix indicating which power is + being used. If in addition (OPTS & human_B), append "B" (if base + 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS & + human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a + power of 1024 or of 1000, depending on (OPTS & + human_base_1024). */ + +char * +human_readable (uintmax_t n, char *buf, int opts, + uintmax_t from_block_size, uintmax_t to_block_size) +{ + int inexact_style = + opts & (human_round_to_nearest | human_floor | human_ceiling); + unsigned int base = opts & human_base_1024 ? 1024 : 1000; + uintmax_t amt; + int tenths; + int exponent = -1; + int exponent_max = sizeof power_letter - 1; + char *p; + char *psuffix; + char const *integerlim; + + /* 0 means adjusted N == AMT.TENTHS; + 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05; + 2 means adjusted N == AMT.TENTHS + 0.05; + 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */ + int rounding; + + char const *decimal_point = "."; + size_t decimal_pointlen = 1; + char const *grouping = ""; + char const *thousands_sep = ""; + struct lconv const *l = localeconv (); + size_t pointlen = strlen (l->decimal_point); + if (0 < pointlen && pointlen <= MB_LEN_MAX) + { + decimal_point = l->decimal_point; + decimal_pointlen = pointlen; + } + grouping = l->grouping; + if (strlen (l->thousands_sep) <= MB_LEN_MAX) + thousands_sep = l->thousands_sep; + + psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX; + p = psuffix; + + /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE + units. If this can be done exactly with integer arithmetic, do + not use floating point operations. */ + if (to_block_size <= from_block_size) + { + if (from_block_size % to_block_size == 0) + { + uintmax_t multiplier = from_block_size / to_block_size; + amt = n * multiplier; + if (amt / multiplier == n) + { + tenths = 0; + rounding = 0; + goto use_integer_arithmetic; + } + } + } + else if (from_block_size != 0 && to_block_size % from_block_size == 0) + { + uintmax_t divisor = to_block_size / from_block_size; + uintmax_t r10 = (n % divisor) * 10; + uintmax_t r2 = (r10 % divisor) * 2; + amt = n / divisor; + tenths = r10 / divisor; + rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2); + goto use_integer_arithmetic; + } + + { + /* Either the result cannot be computed easily using uintmax_t, + or from_block_size is zero. Fall back on floating point. + FIXME: This can yield answers that are slightly off. */ + + long double dto_block_size = to_block_size; + long double damt = n * (from_block_size / dto_block_size); + size_t buflen; + size_t nonintegerlen; + + if (! (opts & human_autoscale)) + { + sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt)); + buflen = strlen (buf); + nonintegerlen = 0; + } + else + { + long double e = 1; + exponent = 0; + + do + { + e *= base; + exponent++; + } + while (e * base <= damt && exponent < exponent_max); + + damt /= e; + + sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt)); + buflen = strlen (buf); + nonintegerlen = decimal_pointlen + 1; + + if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen + || ((opts & human_suppress_point_zero) + && buf[buflen - 1] == '0')) + { + sprintf (buf, "%.0Lf", + adjust_value (inexact_style, damt * 10) / 10); + buflen = strlen (buf); + nonintegerlen = 0; + } + } + + p = psuffix - buflen; + memmove (p, buf, buflen); + integerlim = p + buflen - nonintegerlen; + } + goto do_grouping; + + use_integer_arithmetic: + { + /* The computation can be done exactly, with integer arithmetic. + + Use power of BASE notation if requested and if adjusted AMT is + large enough. */ + + if (opts & human_autoscale) + { + exponent = 0; + + if (base <= amt) + { + do + { + unsigned int r10 = (amt % base) * 10 + tenths; + unsigned int r2 = (r10 % base) * 2 + (rounding >> 1); + amt /= base; + tenths = r10 / base; + rounding = (r2 < base + ? (r2 + rounding) != 0 + : 2 + (base < r2 + rounding)); + exponent++; + } + while (base <= amt && exponent < exponent_max); + + if (amt < 10) + { + if (inexact_style == human_round_to_nearest + ? 2 < rounding + (tenths & 1) + : inexact_style == human_ceiling && 0 < rounding) + { + tenths++; + rounding = 0; + + if (tenths == 10) + { + amt++; + tenths = 0; + } + } + + if (amt < 10 + && (tenths || ! (opts & human_suppress_point_zero))) + { + *--p = '0' + tenths; + p -= decimal_pointlen; + memcpy (p, decimal_point, decimal_pointlen); + tenths = rounding = 0; + } + } + } + } + + if (inexact_style == human_round_to_nearest + ? 5 < tenths + (0 < rounding + (amt & 1)) + : inexact_style == human_ceiling && 0 < tenths + rounding) + { + amt++; + + if ((opts & human_autoscale) + && amt == base && exponent < exponent_max) + { + exponent++; + if (! (opts & human_suppress_point_zero)) + { + *--p = '0'; + p -= decimal_pointlen; + memcpy (p, decimal_point, decimal_pointlen); + } + amt = 1; + } + } + + integerlim = p; + + do + { + int digit = amt % 10; + *--p = digit + '0'; + } + while ((amt /= 10) != 0); + } + + do_grouping: + if (opts & human_group_digits) + p = group_number (p, integerlim - p, grouping, thousands_sep); + + if (opts & human_SI) + { + if (exponent < 0) + { + uintmax_t power; + exponent = 0; + for (power = 1; power < to_block_size; power *= base) + if (++exponent == exponent_max) + break; + } + + if ((exponent | (opts & human_B)) && (opts & human_space_before_unit)) + *psuffix++ = ' '; + + if (exponent) + *psuffix++ = (! (opts & human_base_1024) && exponent == 1 + ? 'k' + : power_letter[exponent]); + + if (opts & human_B) + { + if ((opts & human_base_1024) && exponent) + *psuffix++ = 'i'; + *psuffix++ = 'B'; + } + } + + *psuffix = '\0'; + + return p; +} + + +/* The default block size used for output. This number may change in + the future as disks get larger. */ +#ifndef DEFAULT_BLOCK_SIZE +# define DEFAULT_BLOCK_SIZE 1024 +#endif + +static char const *const block_size_args[] = { "human-readable", "si", 0 }; +static int const block_size_opts[] = + { + human_autoscale + human_SI + human_base_1024, + human_autoscale + human_SI + }; + +static uintmax_t +default_block_size (void) +{ + return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE; +} + +static strtol_error +humblock (char const *spec, uintmax_t *block_size, int *options) +{ + int i; + int opts = 0; + + if (! spec + && ! (spec = getenv ("BLOCK_SIZE")) + && ! (spec = getenv ("BLOCKSIZE"))) + *block_size = default_block_size (); + else + { + if (*spec == '\'') + { + opts |= human_group_digits; + spec++; + } + + if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts))) + { + opts |= block_size_opts[i]; + *block_size = 1; + } + else + { + char *ptr; + strtol_error e = xstrtoumax (spec, &ptr, 0, block_size, + "eEgGkKmMpPtTyYzZ0"); + if (e != LONGINT_OK) + { + *options = 0; + return e; + } + for (; ! ('0' <= *spec && *spec <= '9'); spec++) + if (spec == ptr) + { + opts |= human_SI; + if (ptr[-1] == 'B') + opts |= human_B; + if (ptr[-1] != 'B' || ptr[-2] == 'i') + opts |= human_base_1024; + break; + } + } + } + + *options = opts; + return LONGINT_OK; +} + +enum strtol_error +human_options (char const *spec, int *opts, uintmax_t *block_size) +{ + strtol_error e = humblock (spec, block_size, opts); + if (*block_size == 0) + { + *block_size = default_block_size (); + e = LONGINT_INVALID; + } + return e; +} diff --git a/gnu/human.h b/gnu/human.h new file mode 100644 index 00000000..6dbc40b6 --- /dev/null +++ b/gnu/human.h @@ -0,0 +1,85 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* human.h -- print human readable file size + + Copyright (C) 1996-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert and Larry McVoy. */ + +#ifndef HUMAN_H_ +# define HUMAN_H_ 1 + +# include <limits.h> +# include <stdbool.h> +# include <stdint.h> +# include <unistd.h> + +# include <xstrtol.h> + +/* A conservative bound on the maximum length of a human-readable string. + The output can be the square of the largest uintmax_t, so double + its size before converting to a bound. + log10 (2.0) < 146/485. Add 1 for integer division truncation. + Also, the output can have a thousands separator between every digit, + so multiply by MB_LEN_MAX + 1 and then subtract MB_LEN_MAX. + Append 1 for a space before the suffix. + Finally, append 3, the maximum length of a suffix. */ +# define LONGEST_HUMAN_READABLE \ + ((2 * sizeof (uintmax_t) * CHAR_BIT * 146 / 485 + 1) * (MB_LEN_MAX + 1) \ + - MB_LEN_MAX + 1 + 3) + +/* Options for human_readable. */ +enum +{ + /* Unless otherwise specified these options may be ORed together. */ + + /* The following three options are mutually exclusive. */ + /* Round to plus infinity (default). */ + human_ceiling = 0, + /* Round to nearest, ties to even. */ + human_round_to_nearest = 1, + /* Round to minus infinity. */ + human_floor = 2, + + /* Group digits together, e.g. "1,000,000". This uses the + locale-defined grouping; the traditional C locale does not group, + so this has effect only if some other locale is in use. */ + human_group_digits = 4, + + /* When autoscaling, suppress ".0" at end. */ + human_suppress_point_zero = 8, + + /* Scale output and use SI-style units, ignoring the output block size. */ + human_autoscale = 16, + + /* Prefer base 1024 to base 1000. */ + human_base_1024 = 32, + + /* Prepend " " before unit symbol. */ + human_space_before_unit = 64, + + /* Append SI prefix, e.g. "k" or "M". */ + human_SI = 128, + + /* Append "B" (if base 1000) or "iB" (if base 1024) to SI prefix. */ + human_B = 256 +}; + +char *human_readable (uintmax_t, char *, int, uintmax_t, uintmax_t); + +enum strtol_error human_options (char const *, int *, uintmax_t *); + +#endif /* HUMAN_H_ */ diff --git a/gnu/imaxtostr.c b/gnu/imaxtostr.c new file mode 100644 index 00000000..68c18a53 --- /dev/null +++ b/gnu/imaxtostr.c @@ -0,0 +1,5 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define anytostr imaxtostr +#define inttype intmax_t +#include "anytostr.c" diff --git a/gnu/intprops.h b/gnu/intprops.h new file mode 100644 index 00000000..b1f703bb --- /dev/null +++ b/gnu/intprops.h @@ -0,0 +1,321 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* intprops.h -- properties of integer types + + Copyright (C) 2001-2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#ifndef _GL_INTPROPS_H +#define _GL_INTPROPS_H + +#include <limits.h> + +/* Return an integer value, converted to the same type as the integer + expression E after integer type promotion. V is the unconverted value. */ +#define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) + +/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see + <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00406.html>. */ +#define _GL_INT_NEGATE_CONVERT(e, v) (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 negative values of the signed integer type T use two's + complement, ones' complement, or signed magnitude representation, + respectively. Much GNU code assumes two's complement, but some + people like to be portable to all possible C hosts. */ +#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) +#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) +#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) + +/* True if the signed integer expression E uses two's complement. */ +#define _GL_INT_TWOS_COMPLEMENT(e) (~ _GL_INT_CONVERT (e, 0) == -1) + +/* True if the arithmetic type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* Return 1 if the integer expression E, after integer promotion, has + a signed type. */ +#define _GL_INT_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) + + +/* Minimum and maximum values for integer types and expressions. These + macros have undefined behavior if T is signed and has padding bits. + If this is a problem for you, please let us know how to fix it for + your host. */ + +/* The maximum and minimum values for the integer type T. */ +#define TYPE_MINIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) 0 \ + : TYPE_SIGNED_MAGNITUDE (t) \ + ? ~ (t) 0 \ + : ~ TYPE_MAXIMUM (t))) +#define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) + +/* The maximum and minimum values for the type of the expression E, + after integer promotion. E should not have side effects. */ +#define _GL_INT_MINIMUM(e) \ + (_GL_INT_SIGNED (e) \ + ? - _GL_INT_TWOS_COMPLEMENT (e) - _GL_SIGNED_INT_MAXIMUM (e) \ + : _GL_INT_CONVERT (e, 0)) +#define _GL_INT_MAXIMUM(e) \ + (_GL_INT_SIGNED (e) \ + ? _GL_SIGNED_INT_MAXIMUM (e) \ + : _GL_INT_NEGATE_CONVERT (e, 1)) +#define _GL_SIGNED_INT_MAXIMUM(e) \ + (((_GL_INT_CONVERT (e, 1) << (sizeof ((e) + 0) * CHAR_BIT - 2)) - 1) * 2 + 1) + + +/* Return 1 if the __typeof__ keyword works. This could be done by + 'configure', but for now it's easier to do it by hand. */ +#if 2 <= __GNUC__ || 0x5110 <= __SUNPRO_C +# define _GL_HAVE___TYPEOF__ 1 +#else +# define _GL_HAVE___TYPEOF__ 0 +#endif + +/* Return 1 if the integer type or expression T might be signed. Return 0 + if it is definitely unsigned. This macro does not evaluate its argument, + and expands to an integer constant expression. */ +#if _GL_HAVE___TYPEOF__ +# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) +#else +# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 +#endif + +/* 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. + Subtract 1 for the sign bit if T is signed, and then add 1 more for + a minus sign if needed. + + Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is + signed, this macro may overestimate the true bound by one byte when + applied to unsigned types of size 2, 4, 16, ... bytes. */ +#define INT_STRLEN_BOUND(t) \ + (INT_BITS_STRLEN_BOUND (sizeof (t) * CHAR_BIT \ + - _GL_SIGNED_TYPE_OR_EXPR (t)) \ + + _GL_SIGNED_TYPE_OR_EXPR (t)) + +/* Bound on buffer size needed to represent an integer type or expression T, + including the terminating null. */ +#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) + + +/* Range overflow checks. + + The INT_<op>_RANGE_OVERFLOW macros return 1 if the corresponding C + operators might not yield numerically correct answers due to + arithmetic overflow. They do not rely on undefined or + implementation-defined behavior. Their implementations are simple + and straightforward, but they are a bit harder to use than the + INT_<op>_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. + + 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 + <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>. */ +#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)) + + +/* The _GL*_OVERFLOW macros have the same restrictions as the + *_RANGE_OVERFLOW macros, except that they do not assume that operands + (e.g., A and B) have the same type as MIN and MAX. Instead, they assume + that the result (e.g., A + B) has that type. */ +#define _GL_ADD_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ + : (a) < 0 ? (b) <= (a) + (b) \ + : (b) < 0 ? (a) <= (a) + (b) \ + : (a) + (b) < (b)) +#define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \ + : (a) < 0 ? 1 \ + : (b) < 0 ? (a) - (b) <= (a) \ + : (a) < (b)) +#define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ + (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ + || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) +#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) + + +/* Integer overflow checks. + + The INT_<op>_OVERFLOW macros return 1 if the corresponding C operators + might not yield numerically correct answers due to arithmetic overflow. + They work correctly on all known practical hosts, and do not rely + on undefined behavior due to signed arithmetic overflow. + + Example usage: + + long int i = ...; + long int j = ...; + if (INT_MULTIPLY_OVERFLOW (i, j)) + printf ("multiply would overflow"); + else + printf ("product is %ld", i * j); + + 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. + + These macros are tuned for their last 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) +#define INT_NEGATE_OVERFLOW(a) \ + INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) +#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 <op> 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 (0 * (b) + (a)), \ + _GL_INT_MAXIMUM (0 * (b) + (a))) + +#endif /* _GL_INTPROPS_H */ diff --git a/gnu/inttostr.c b/gnu/inttostr.c new file mode 100644 index 00000000..696b03c7 --- /dev/null +++ b/gnu/inttostr.c @@ -0,0 +1,5 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define anytostr inttostr +#define inttype int +#include "anytostr.c" diff --git a/gnu/inttostr.h b/gnu/inttostr.h new file mode 100644 index 00000000..3804d92a --- /dev/null +++ b/gnu/inttostr.h @@ -0,0 +1,48 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* inttostr.h -- convert integers to printable strings + + Copyright (C) 2001-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert */ + +#include <stdint.h> +#include <sys/types.h> + +#include "intprops.h" + +#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 + +#if __GNUC_PREREQ (3,4) +# undef __attribute_warn_unused_result__ +# define __attribute_warn_unused_result__ \ + __attribute__ ((__warn_unused_result__)) +#else +# define __attribute_warn_unused_result__ /* empty */ +#endif + +char *imaxtostr (intmax_t, char *) __attribute_warn_unused_result__; +char *inttostr (int, char *) __attribute_warn_unused_result__; +char *offtostr (off_t, char *) __attribute_warn_unused_result__; +char *uinttostr (unsigned int, char *) __attribute_warn_unused_result__; +char *umaxtostr (uintmax_t, char *) __attribute_warn_unused_result__; diff --git a/gnu/inttypes.in.h b/gnu/inttypes.in.h new file mode 100644 index 00000000..d9f3df3d --- /dev/null +++ b/gnu/inttypes.in.h @@ -0,0 +1,1132 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 2006-2012 Free Software Foundation, Inc. + Written by Paul Eggert, Bruno Haible, Derek Price. + This file is part of gnulib. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 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 <http://www.gnu.org/licenses/>. */ + +/* + * ISO C 99 <inttypes.h> for platforms that lack it. + * <http://www.opengroup.org/susv3xbd/inttypes.h.html> + */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* Include the original <inttypes.h> 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 <stdint.h> implementations need this. */ +# if defined __cplusplus && ! defined __STDC_FORMAT_MACROS +# define __STDC_FORMAT_MACROS 1 +# endif + +# @INCLUDE_NEXT@ @NEXT_INTTYPES_H@ +# endif +#endif + +#if ! defined INTTYPES_H && ! defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H +#define INTTYPES_H + +/* Include <stdint.h> or the gnulib replacement. + But avoid namespace pollution on glibc systems. */ +#ifndef __GLIBC__ +# include <stdint.h> +#endif +/* Get CHAR_BIT. */ +#include <limits.h> + +#if !(INT_MIN == INT32_MIN && INT_MAX == INT32_MAX) +# error "This file assumes that 'int' has exactly 32 bits. Please report your platform and compiler to <bug-gnulib@gnu.org>." +#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 || @PRI_MACROS_BROKEN@ +# undef PRId8 +# ifdef INT8_MAX +# define PRId8 "d" +# endif +#endif +#if !defined PRIi8 || @PRI_MACROS_BROKEN@ +# undef PRIi8 +# ifdef INT8_MAX +# define PRIi8 "i" +# endif +#endif +#if !defined PRIo8 || @PRI_MACROS_BROKEN@ +# undef PRIo8 +# ifdef UINT8_MAX +# define PRIo8 "o" +# endif +#endif +#if !defined PRIu8 || @PRI_MACROS_BROKEN@ +# undef PRIu8 +# ifdef UINT8_MAX +# define PRIu8 "u" +# endif +#endif +#if !defined PRIx8 || @PRI_MACROS_BROKEN@ +# undef PRIx8 +# ifdef UINT8_MAX +# define PRIx8 "x" +# endif +#endif +#if !defined PRIX8 || @PRI_MACROS_BROKEN@ +# undef PRIX8 +# ifdef UINT8_MAX +# define PRIX8 "X" +# endif +#endif +#if !defined PRId16 || @PRI_MACROS_BROKEN@ +# undef PRId16 +# ifdef INT16_MAX +# define PRId16 "d" +# endif +#endif +#if !defined PRIi16 || @PRI_MACROS_BROKEN@ +# undef PRIi16 +# ifdef INT16_MAX +# define PRIi16 "i" +# endif +#endif +#if !defined PRIo16 || @PRI_MACROS_BROKEN@ +# undef PRIo16 +# ifdef UINT16_MAX +# define PRIo16 "o" +# endif +#endif +#if !defined PRIu16 || @PRI_MACROS_BROKEN@ +# undef PRIu16 +# ifdef UINT16_MAX +# define PRIu16 "u" +# endif +#endif +#if !defined PRIx16 || @PRI_MACROS_BROKEN@ +# undef PRIx16 +# ifdef UINT16_MAX +# define PRIx16 "x" +# endif +#endif +#if !defined PRIX16 || @PRI_MACROS_BROKEN@ +# undef PRIX16 +# ifdef UINT16_MAX +# define PRIX16 "X" +# endif +#endif +#if !defined PRId32 || @PRI_MACROS_BROKEN@ +# undef PRId32 +# ifdef INT32_MAX +# define PRId32 "d" +# endif +#endif +#if !defined PRIi32 || @PRI_MACROS_BROKEN@ +# undef PRIi32 +# ifdef INT32_MAX +# define PRIi32 "i" +# endif +#endif +#if !defined PRIo32 || @PRI_MACROS_BROKEN@ +# undef PRIo32 +# ifdef UINT32_MAX +# define PRIo32 "o" +# endif +#endif +#if !defined PRIu32 || @PRI_MACROS_BROKEN@ +# undef PRIu32 +# ifdef UINT32_MAX +# define PRIu32 "u" +# endif +#endif +#if !defined PRIx32 || @PRI_MACROS_BROKEN@ +# undef PRIx32 +# ifdef UINT32_MAX +# define PRIx32 "x" +# endif +#endif +#if !defined PRIX32 || @PRI_MACROS_BROKEN@ +# undef 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 @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +# define _PRI64_PREFIX _LONG_LONG_FORMAT_PREFIX +# endif +# if !defined PRId64 || @PRI_MACROS_BROKEN@ +# undef PRId64 +# define PRId64 _PRI64_PREFIX "d" +# endif +# if !defined PRIi64 || @PRI_MACROS_BROKEN@ +# undef 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 @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +# define _PRIu64_PREFIX _LONG_LONG_FORMAT_PREFIX +# endif +# if !defined PRIo64 || @PRI_MACROS_BROKEN@ +# undef PRIo64 +# define PRIo64 _PRIu64_PREFIX "o" +# endif +# if !defined PRIu64 || @PRI_MACROS_BROKEN@ +# undef PRIu64 +# define PRIu64 _PRIu64_PREFIX "u" +# endif +# if !defined PRIx64 || @PRI_MACROS_BROKEN@ +# undef PRIx64 +# define PRIx64 _PRIu64_PREFIX "x" +# endif +# if !defined PRIX64 || @PRI_MACROS_BROKEN@ +# undef PRIX64 +# define PRIX64 _PRIu64_PREFIX "X" +# endif +#endif + +#if !defined PRIdLEAST8 || @PRI_MACROS_BROKEN@ +# undef PRIdLEAST8 +# define PRIdLEAST8 "d" +#endif +#if !defined PRIiLEAST8 || @PRI_MACROS_BROKEN@ +# undef PRIiLEAST8 +# define PRIiLEAST8 "i" +#endif +#if !defined PRIoLEAST8 || @PRI_MACROS_BROKEN@ +# undef PRIoLEAST8 +# define PRIoLEAST8 "o" +#endif +#if !defined PRIuLEAST8 || @PRI_MACROS_BROKEN@ +# undef PRIuLEAST8 +# define PRIuLEAST8 "u" +#endif +#if !defined PRIxLEAST8 || @PRI_MACROS_BROKEN@ +# undef PRIxLEAST8 +# define PRIxLEAST8 "x" +#endif +#if !defined PRIXLEAST8 || @PRI_MACROS_BROKEN@ +# undef PRIXLEAST8 +# define PRIXLEAST8 "X" +#endif +#if !defined PRIdLEAST16 || @PRI_MACROS_BROKEN@ +# undef PRIdLEAST16 +# define PRIdLEAST16 "d" +#endif +#if !defined PRIiLEAST16 || @PRI_MACROS_BROKEN@ +# undef PRIiLEAST16 +# define PRIiLEAST16 "i" +#endif +#if !defined PRIoLEAST16 || @PRI_MACROS_BROKEN@ +# undef PRIoLEAST16 +# define PRIoLEAST16 "o" +#endif +#if !defined PRIuLEAST16 || @PRI_MACROS_BROKEN@ +# undef PRIuLEAST16 +# define PRIuLEAST16 "u" +#endif +#if !defined PRIxLEAST16 || @PRI_MACROS_BROKEN@ +# undef PRIxLEAST16 +# define PRIxLEAST16 "x" +#endif +#if !defined PRIXLEAST16 || @PRI_MACROS_BROKEN@ +# undef PRIXLEAST16 +# define PRIXLEAST16 "X" +#endif +#if !defined PRIdLEAST32 || @PRI_MACROS_BROKEN@ +# undef PRIdLEAST32 +# define PRIdLEAST32 "d" +#endif +#if !defined PRIiLEAST32 || @PRI_MACROS_BROKEN@ +# undef PRIiLEAST32 +# define PRIiLEAST32 "i" +#endif +#if !defined PRIoLEAST32 || @PRI_MACROS_BROKEN@ +# undef PRIoLEAST32 +# define PRIoLEAST32 "o" +#endif +#if !defined PRIuLEAST32 || @PRI_MACROS_BROKEN@ +# undef PRIuLEAST32 +# define PRIuLEAST32 "u" +#endif +#if !defined PRIxLEAST32 || @PRI_MACROS_BROKEN@ +# undef PRIxLEAST32 +# define PRIxLEAST32 "x" +#endif +#if !defined PRIXLEAST32 || @PRI_MACROS_BROKEN@ +# undef PRIXLEAST32 +# define PRIXLEAST32 "X" +#endif +#ifdef INT64_MAX +# if !defined PRIdLEAST64 || @PRI_MACROS_BROKEN@ +# undef PRIdLEAST64 +# define PRIdLEAST64 PRId64 +# endif +# if !defined PRIiLEAST64 || @PRI_MACROS_BROKEN@ +# undef PRIiLEAST64 +# define PRIiLEAST64 PRIi64 +# endif +#endif +#ifdef UINT64_MAX +# if !defined PRIoLEAST64 || @PRI_MACROS_BROKEN@ +# undef PRIoLEAST64 +# define PRIoLEAST64 PRIo64 +# endif +# if !defined PRIuLEAST64 || @PRI_MACROS_BROKEN@ +# undef PRIuLEAST64 +# define PRIuLEAST64 PRIu64 +# endif +# if !defined PRIxLEAST64 || @PRI_MACROS_BROKEN@ +# undef PRIxLEAST64 +# define PRIxLEAST64 PRIx64 +# endif +# if !defined PRIXLEAST64 || @PRI_MACROS_BROKEN@ +# undef PRIXLEAST64 +# define PRIXLEAST64 PRIX64 +# endif +#endif + +#if !defined PRIdFAST8 || @PRI_MACROS_BROKEN@ +# undef PRIdFAST8 +# if INT_FAST8_MAX > INT32_MAX +# define PRIdFAST8 PRId64 +# else +# define PRIdFAST8 "d" +# endif +#endif +#if !defined PRIiFAST8 || @PRI_MACROS_BROKEN@ +# undef PRIiFAST8 +# if INT_FAST8_MAX > INT32_MAX +# define PRIiFAST8 PRIi64 +# else +# define PRIiFAST8 "i" +# endif +#endif +#if !defined PRIoFAST8 || @PRI_MACROS_BROKEN@ +# undef PRIoFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define PRIoFAST8 PRIo64 +# else +# define PRIoFAST8 "o" +# endif +#endif +#if !defined PRIuFAST8 || @PRI_MACROS_BROKEN@ +# undef PRIuFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define PRIuFAST8 PRIu64 +# else +# define PRIuFAST8 "u" +# endif +#endif +#if !defined PRIxFAST8 || @PRI_MACROS_BROKEN@ +# undef PRIxFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define PRIxFAST8 PRIx64 +# else +# define PRIxFAST8 "x" +# endif +#endif +#if !defined PRIXFAST8 || @PRI_MACROS_BROKEN@ +# undef PRIXFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define PRIXFAST8 PRIX64 +# else +# define PRIXFAST8 "X" +# endif +#endif +#if !defined PRIdFAST16 || @PRI_MACROS_BROKEN@ +# undef PRIdFAST16 +# if INT_FAST16_MAX > INT32_MAX +# define PRIdFAST16 PRId64 +# else +# define PRIdFAST16 "d" +# endif +#endif +#if !defined PRIiFAST16 || @PRI_MACROS_BROKEN@ +# undef PRIiFAST16 +# if INT_FAST16_MAX > INT32_MAX +# define PRIiFAST16 PRIi64 +# else +# define PRIiFAST16 "i" +# endif +#endif +#if !defined PRIoFAST16 || @PRI_MACROS_BROKEN@ +# undef PRIoFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define PRIoFAST16 PRIo64 +# else +# define PRIoFAST16 "o" +# endif +#endif +#if !defined PRIuFAST16 || @PRI_MACROS_BROKEN@ +# undef PRIuFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define PRIuFAST16 PRIu64 +# else +# define PRIuFAST16 "u" +# endif +#endif +#if !defined PRIxFAST16 || @PRI_MACROS_BROKEN@ +# undef PRIxFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define PRIxFAST16 PRIx64 +# else +# define PRIxFAST16 "x" +# endif +#endif +#if !defined PRIXFAST16 || @PRI_MACROS_BROKEN@ +# undef PRIXFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define PRIXFAST16 PRIX64 +# else +# define PRIXFAST16 "X" +# endif +#endif +#if !defined PRIdFAST32 || @PRI_MACROS_BROKEN@ +# undef PRIdFAST32 +# if INT_FAST32_MAX > INT32_MAX +# define PRIdFAST32 PRId64 +# else +# define PRIdFAST32 "d" +# endif +#endif +#if !defined PRIiFAST32 || @PRI_MACROS_BROKEN@ +# undef PRIiFAST32 +# if INT_FAST32_MAX > INT32_MAX +# define PRIiFAST32 PRIi64 +# else +# define PRIiFAST32 "i" +# endif +#endif +#if !defined PRIoFAST32 || @PRI_MACROS_BROKEN@ +# undef PRIoFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define PRIoFAST32 PRIo64 +# else +# define PRIoFAST32 "o" +# endif +#endif +#if !defined PRIuFAST32 || @PRI_MACROS_BROKEN@ +# undef PRIuFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define PRIuFAST32 PRIu64 +# else +# define PRIuFAST32 "u" +# endif +#endif +#if !defined PRIxFAST32 || @PRI_MACROS_BROKEN@ +# undef PRIxFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define PRIxFAST32 PRIx64 +# else +# define PRIxFAST32 "x" +# endif +#endif +#if !defined PRIXFAST32 || @PRI_MACROS_BROKEN@ +# undef PRIXFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define PRIXFAST32 PRIX64 +# else +# define PRIXFAST32 "X" +# endif +#endif +#ifdef INT64_MAX +# if !defined PRIdFAST64 || @PRI_MACROS_BROKEN@ +# undef PRIdFAST64 +# define PRIdFAST64 PRId64 +# endif +# if !defined PRIiFAST64 || @PRI_MACROS_BROKEN@ +# undef PRIiFAST64 +# define PRIiFAST64 PRIi64 +# endif +#endif +#ifdef UINT64_MAX +# if !defined PRIoFAST64 || @PRI_MACROS_BROKEN@ +# undef PRIoFAST64 +# define PRIoFAST64 PRIo64 +# endif +# if !defined PRIuFAST64 || @PRI_MACROS_BROKEN@ +# undef PRIuFAST64 +# define PRIuFAST64 PRIu64 +# endif +# if !defined PRIxFAST64 || @PRI_MACROS_BROKEN@ +# undef PRIxFAST64 +# define PRIxFAST64 PRIx64 +# endif +# if !defined PRIXFAST64 || @PRI_MACROS_BROKEN@ +# undef PRIXFAST64 +# define PRIXFAST64 PRIX64 +# endif +#endif + +#if !defined PRIdMAX || @PRI_MACROS_BROKEN@ +# undef PRIdMAX +# if @INT32_MAX_LT_INTMAX_MAX@ +# define PRIdMAX PRId64 +# else +# define PRIdMAX "ld" +# endif +#endif +#if !defined PRIiMAX || @PRI_MACROS_BROKEN@ +# undef PRIiMAX +# if @INT32_MAX_LT_INTMAX_MAX@ +# define PRIiMAX PRIi64 +# else +# define PRIiMAX "li" +# endif +#endif +#if !defined PRIoMAX || @PRI_MACROS_BROKEN@ +# undef PRIoMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define PRIoMAX PRIo64 +# else +# define PRIoMAX "lo" +# endif +#endif +#if !defined PRIuMAX || @PRI_MACROS_BROKEN@ +# undef PRIuMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define PRIuMAX PRIu64 +# else +# define PRIuMAX "lu" +# endif +#endif +#if !defined PRIxMAX || @PRI_MACROS_BROKEN@ +# undef PRIxMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define PRIxMAX PRIx64 +# else +# define PRIxMAX "lx" +# endif +#endif +#if !defined PRIXMAX || @PRI_MACROS_BROKEN@ +# undef PRIXMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define PRIXMAX PRIX64 +# else +# define PRIXMAX "lX" +# endif +#endif + +#if !defined PRIdPTR || @PRI_MACROS_BROKEN@ +# undef PRIdPTR +# ifdef INTPTR_MAX +# define PRIdPTR @PRIPTR_PREFIX@ "d" +# endif +#endif +#if !defined PRIiPTR || @PRI_MACROS_BROKEN@ +# undef PRIiPTR +# ifdef INTPTR_MAX +# define PRIiPTR @PRIPTR_PREFIX@ "i" +# endif +#endif +#if !defined PRIoPTR || @PRI_MACROS_BROKEN@ +# undef PRIoPTR +# ifdef UINTPTR_MAX +# define PRIoPTR @PRIPTR_PREFIX@ "o" +# endif +#endif +#if !defined PRIuPTR || @PRI_MACROS_BROKEN@ +# undef PRIuPTR +# ifdef UINTPTR_MAX +# define PRIuPTR @PRIPTR_PREFIX@ "u" +# endif +#endif +#if !defined PRIxPTR || @PRI_MACROS_BROKEN@ +# undef PRIxPTR +# ifdef UINTPTR_MAX +# define PRIxPTR @PRIPTR_PREFIX@ "x" +# endif +#endif +#if !defined PRIXPTR || @PRI_MACROS_BROKEN@ +# undef PRIXPTR +# ifdef UINTPTR_MAX +# define PRIXPTR @PRIPTR_PREFIX@ "X" +# endif +#endif + +#if !defined SCNd8 || @PRI_MACROS_BROKEN@ +# undef SCNd8 +# ifdef INT8_MAX +# define SCNd8 "hhd" +# endif +#endif +#if !defined SCNi8 || @PRI_MACROS_BROKEN@ +# undef SCNi8 +# ifdef INT8_MAX +# define SCNi8 "hhi" +# endif +#endif +#if !defined SCNo8 || @PRI_MACROS_BROKEN@ +# undef SCNo8 +# ifdef UINT8_MAX +# define SCNo8 "hho" +# endif +#endif +#if !defined SCNu8 || @PRI_MACROS_BROKEN@ +# undef SCNu8 +# ifdef UINT8_MAX +# define SCNu8 "hhu" +# endif +#endif +#if !defined SCNx8 || @PRI_MACROS_BROKEN@ +# undef SCNx8 +# ifdef UINT8_MAX +# define SCNx8 "hhx" +# endif +#endif +#if !defined SCNd16 || @PRI_MACROS_BROKEN@ +# undef SCNd16 +# ifdef INT16_MAX +# define SCNd16 "hd" +# endif +#endif +#if !defined SCNi16 || @PRI_MACROS_BROKEN@ +# undef SCNi16 +# ifdef INT16_MAX +# define SCNi16 "hi" +# endif +#endif +#if !defined SCNo16 || @PRI_MACROS_BROKEN@ +# undef SCNo16 +# ifdef UINT16_MAX +# define SCNo16 "ho" +# endif +#endif +#if !defined SCNu16 || @PRI_MACROS_BROKEN@ +# undef SCNu16 +# ifdef UINT16_MAX +# define SCNu16 "hu" +# endif +#endif +#if !defined SCNx16 || @PRI_MACROS_BROKEN@ +# undef SCNx16 +# ifdef UINT16_MAX +# define SCNx16 "hx" +# endif +#endif +#if !defined SCNd32 || @PRI_MACROS_BROKEN@ +# undef SCNd32 +# ifdef INT32_MAX +# define SCNd32 "d" +# endif +#endif +#if !defined SCNi32 || @PRI_MACROS_BROKEN@ +# undef SCNi32 +# ifdef INT32_MAX +# define SCNi32 "i" +# endif +#endif +#if !defined SCNo32 || @PRI_MACROS_BROKEN@ +# undef SCNo32 +# ifdef UINT32_MAX +# define SCNo32 "o" +# endif +#endif +#if !defined SCNu32 || @PRI_MACROS_BROKEN@ +# undef SCNu32 +# ifdef UINT32_MAX +# define SCNu32 "u" +# endif +#endif +#if !defined SCNx32 || @PRI_MACROS_BROKEN@ +# undef 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 @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +# define _SCN64_PREFIX _LONG_LONG_FORMAT_PREFIX +# endif +# if !defined SCNd64 || @PRI_MACROS_BROKEN@ +# undef SCNd64 +# define SCNd64 _SCN64_PREFIX "d" +# endif +# if !defined SCNi64 || @PRI_MACROS_BROKEN@ +# undef 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 @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +# define _SCNu64_PREFIX _LONG_LONG_FORMAT_PREFIX +# endif +# if !defined SCNo64 || @PRI_MACROS_BROKEN@ +# undef SCNo64 +# define SCNo64 _SCNu64_PREFIX "o" +# endif +# if !defined SCNu64 || @PRI_MACROS_BROKEN@ +# undef SCNu64 +# define SCNu64 _SCNu64_PREFIX "u" +# endif +# if !defined SCNx64 || @PRI_MACROS_BROKEN@ +# undef SCNx64 +# define SCNx64 _SCNu64_PREFIX "x" +# endif +#endif + +#if !defined SCNdLEAST8 || @PRI_MACROS_BROKEN@ +# undef SCNdLEAST8 +# define SCNdLEAST8 "hhd" +#endif +#if !defined SCNiLEAST8 || @PRI_MACROS_BROKEN@ +# undef SCNiLEAST8 +# define SCNiLEAST8 "hhi" +#endif +#if !defined SCNoLEAST8 || @PRI_MACROS_BROKEN@ +# undef SCNoLEAST8 +# define SCNoLEAST8 "hho" +#endif +#if !defined SCNuLEAST8 || @PRI_MACROS_BROKEN@ +# undef SCNuLEAST8 +# define SCNuLEAST8 "hhu" +#endif +#if !defined SCNxLEAST8 || @PRI_MACROS_BROKEN@ +# undef SCNxLEAST8 +# define SCNxLEAST8 "hhx" +#endif +#if !defined SCNdLEAST16 || @PRI_MACROS_BROKEN@ +# undef SCNdLEAST16 +# define SCNdLEAST16 "hd" +#endif +#if !defined SCNiLEAST16 || @PRI_MACROS_BROKEN@ +# undef SCNiLEAST16 +# define SCNiLEAST16 "hi" +#endif +#if !defined SCNoLEAST16 || @PRI_MACROS_BROKEN@ +# undef SCNoLEAST16 +# define SCNoLEAST16 "ho" +#endif +#if !defined SCNuLEAST16 || @PRI_MACROS_BROKEN@ +# undef SCNuLEAST16 +# define SCNuLEAST16 "hu" +#endif +#if !defined SCNxLEAST16 || @PRI_MACROS_BROKEN@ +# undef SCNxLEAST16 +# define SCNxLEAST16 "hx" +#endif +#if !defined SCNdLEAST32 || @PRI_MACROS_BROKEN@ +# undef SCNdLEAST32 +# define SCNdLEAST32 "d" +#endif +#if !defined SCNiLEAST32 || @PRI_MACROS_BROKEN@ +# undef SCNiLEAST32 +# define SCNiLEAST32 "i" +#endif +#if !defined SCNoLEAST32 || @PRI_MACROS_BROKEN@ +# undef SCNoLEAST32 +# define SCNoLEAST32 "o" +#endif +#if !defined SCNuLEAST32 || @PRI_MACROS_BROKEN@ +# undef SCNuLEAST32 +# define SCNuLEAST32 "u" +#endif +#if !defined SCNxLEAST32 || @PRI_MACROS_BROKEN@ +# undef SCNxLEAST32 +# define SCNxLEAST32 "x" +#endif +#ifdef INT64_MAX +# if !defined SCNdLEAST64 || @PRI_MACROS_BROKEN@ +# undef SCNdLEAST64 +# define SCNdLEAST64 SCNd64 +# endif +# if !defined SCNiLEAST64 || @PRI_MACROS_BROKEN@ +# undef SCNiLEAST64 +# define SCNiLEAST64 SCNi64 +# endif +#endif +#ifdef UINT64_MAX +# if !defined SCNoLEAST64 || @PRI_MACROS_BROKEN@ +# undef SCNoLEAST64 +# define SCNoLEAST64 SCNo64 +# endif +# if !defined SCNuLEAST64 || @PRI_MACROS_BROKEN@ +# undef SCNuLEAST64 +# define SCNuLEAST64 SCNu64 +# endif +# if !defined SCNxLEAST64 || @PRI_MACROS_BROKEN@ +# undef SCNxLEAST64 +# define SCNxLEAST64 SCNx64 +# endif +#endif + +#if !defined SCNdFAST8 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef 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 || @PRI_MACROS_BROKEN@ +# undef SCNdFAST32 +# if INT_FAST32_MAX > INT32_MAX +# define SCNdFAST32 SCNd64 +# else +# define SCNdFAST32 "d" +# endif +#endif +#if !defined SCNiFAST32 || @PRI_MACROS_BROKEN@ +# undef SCNiFAST32 +# if INT_FAST32_MAX > INT32_MAX +# define SCNiFAST32 SCNi64 +# else +# define SCNiFAST32 "i" +# endif +#endif +#if !defined SCNoFAST32 || @PRI_MACROS_BROKEN@ +# undef SCNoFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define SCNoFAST32 SCNo64 +# else +# define SCNoFAST32 "o" +# endif +#endif +#if !defined SCNuFAST32 || @PRI_MACROS_BROKEN@ +# undef SCNuFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define SCNuFAST32 SCNu64 +# else +# define SCNuFAST32 "u" +# endif +#endif +#if !defined SCNxFAST32 || @PRI_MACROS_BROKEN@ +# undef SCNxFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define SCNxFAST32 SCNx64 +# else +# define SCNxFAST32 "x" +# endif +#endif +#ifdef INT64_MAX +# if !defined SCNdFAST64 || @PRI_MACROS_BROKEN@ +# undef SCNdFAST64 +# define SCNdFAST64 SCNd64 +# endif +# if !defined SCNiFAST64 || @PRI_MACROS_BROKEN@ +# undef SCNiFAST64 +# define SCNiFAST64 SCNi64 +# endif +#endif +#ifdef UINT64_MAX +# if !defined SCNoFAST64 || @PRI_MACROS_BROKEN@ +# undef SCNoFAST64 +# define SCNoFAST64 SCNo64 +# endif +# if !defined SCNuFAST64 || @PRI_MACROS_BROKEN@ +# undef SCNuFAST64 +# define SCNuFAST64 SCNu64 +# endif +# if !defined SCNxFAST64 || @PRI_MACROS_BROKEN@ +# undef SCNxFAST64 +# define SCNxFAST64 SCNx64 +# endif +#endif + +#if !defined SCNdMAX || @PRI_MACROS_BROKEN@ +# undef SCNdMAX +# if @INT32_MAX_LT_INTMAX_MAX@ +# define SCNdMAX SCNd64 +# else +# define SCNdMAX "ld" +# endif +#endif +#if !defined SCNiMAX || @PRI_MACROS_BROKEN@ +# undef SCNiMAX +# if @INT32_MAX_LT_INTMAX_MAX@ +# define SCNiMAX SCNi64 +# else +# define SCNiMAX "li" +# endif +#endif +#if !defined SCNoMAX || @PRI_MACROS_BROKEN@ +# undef SCNoMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define SCNoMAX SCNo64 +# else +# define SCNoMAX "lo" +# endif +#endif +#if !defined SCNuMAX || @PRI_MACROS_BROKEN@ +# undef SCNuMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define SCNuMAX SCNu64 +# else +# define SCNuMAX "lu" +# endif +#endif +#if !defined SCNxMAX || @PRI_MACROS_BROKEN@ +# undef SCNxMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define SCNxMAX SCNx64 +# else +# define SCNxMAX "lx" +# endif +#endif + +#if !defined SCNdPTR || @PRI_MACROS_BROKEN@ +# undef SCNdPTR +# ifdef INTPTR_MAX +# define SCNdPTR @PRIPTR_PREFIX@ "d" +# endif +#endif +#if !defined SCNiPTR || @PRI_MACROS_BROKEN@ +# undef SCNiPTR +# ifdef INTPTR_MAX +# define SCNiPTR @PRIPTR_PREFIX@ "i" +# endif +#endif +#if !defined SCNoPTR || @PRI_MACROS_BROKEN@ +# undef SCNoPTR +# ifdef UINTPTR_MAX +# define SCNoPTR @PRIPTR_PREFIX@ "o" +# endif +#endif +#if !defined SCNuPTR || @PRI_MACROS_BROKEN@ +# undef SCNuPTR +# ifdef UINTPTR_MAX +# define SCNuPTR @PRIPTR_PREFIX@ "u" +# endif +#endif +#if !defined SCNxPTR || @PRI_MACROS_BROKEN@ +# undef 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_DECL_IMAXDIV@ +# if !GNULIB_defined_imaxdiv_t +typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t; +# define GNULIB_defined_imaxdiv_t 1 +# endif +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 *, char **, int) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtoimax, intmax_t, (const char *, char **, int)); +# else +# if !@HAVE_DECL_STRTOIMAX@ +# undef strtoimax +_GL_FUNCDECL_SYS (strtoimax, intmax_t, + (const char *, char **, int) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoimax, intmax_t, (const char *, char **, 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 !@HAVE_DECL_STRTOUMAX@ +# undef strtoumax +_GL_FUNCDECL_SYS (strtoumax, uintmax_t, + (const char *, char **, int) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoumax, uintmax_t, (const char *, char **, int)); +_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/gnu/iswblank.c b/gnu/iswblank.c new file mode 100644 index 00000000..2c689708 --- /dev/null +++ b/gnu/iswblank.c @@ -0,0 +1,29 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Test wide character for being blank. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include <wctype.h> + +int +iswblank (wint_t wc) +{ + return wc == ' ' || wc == '\t'; +} diff --git a/gnu/itold.c b/gnu/itold.c new file mode 100644 index 00000000..ecdeaa6a --- /dev/null +++ b/gnu/itold.c @@ -0,0 +1,30 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Replacement for 'int' to 'long double' conversion routine. + Copyright (C) 2011-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2011. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <float.h> + +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/gnu/langinfo.in.h b/gnu/langinfo.in.h new file mode 100644 index 00000000..d92332d5 --- /dev/null +++ b/gnu/langinfo.in.h @@ -0,0 +1,179 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Substitute for and wrapper around <langinfo.h>. + Copyright (C) 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* + * POSIX <langinfo.h> for platforms that lack it or have an incomplete one. + * <http://www.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html> + */ + +#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 <langinfo.h>. */ + +/* Assume that it also lacks <nl_types.h> 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 THOUSEP 10002 +/* 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 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 +/* nl_langinfo items of the LC_MESSAGES category */ +# define YESEXPR 10053 +# define NOEXPR 10054 + +#else + +/* A platform that has <langinfo.h>. */ + +# 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_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/gnu/lchown.c b/gnu/lchown.c new file mode 100644 index 00000000..350d1654 --- /dev/null +++ b/gnu/lchown.c @@ -0,0 +1,119 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Provide a stub lchown function for systems that lack it. + + Copyright (C) 1998-1999, 2002, 2004, 2006-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering */ + +#include <config.h> + +#include <unistd.h> + +#include <errno.h> +#include <stdbool.h> +#include <string.h> +#include <sys/stat.h> + +#if !HAVE_LCHOWN + +/* If the system chown does not follow symlinks, we don't want it + replaced by gnulib's chown, which does follow symlinks. */ +# if CHOWN_MODIFIES_SYMLINK +# undef chown +# endif + +/* Work just like chown, except when FILE is a symbolic link. + In that case, set errno to EOPNOTSUPP and return -1. + But if autoconf tests determined that chown modifies + symlinks, then just call chown. */ + +int +lchown (const char *file, uid_t uid, gid_t gid) +{ +# if HAVE_CHOWN +# if ! CHOWN_MODIFIES_SYMLINK + struct stat stats; + + if (lstat (file, &stats) == 0 && S_ISLNK (stats.st_mode)) + { + errno = EOPNOTSUPP; + return -1; + } +# endif + + return chown (file, uid, gid); + +# else /* !HAVE_CHOWN */ + errno = ENOSYS; + return -1; +# endif +} + +#else /* HAVE_LCHOWN */ + +# undef lchown + +/* Work around trailing slash bugs in lchown. */ +int +rpl_lchown (const char *file, uid_t uid, gid_t gid) +{ + bool stat_valid = false; + int result; + +# if CHOWN_CHANGE_TIME_BUG + struct stat st; + + if (gid != (gid_t) -1 || uid != (uid_t) -1) + { + if (lstat (file, &st)) + return -1; + stat_valid = true; + if (!S_ISLNK (st.st_mode)) + return chown (file, uid, gid); + } +# endif + +# if CHOWN_TRAILING_SLASH_BUG + if (!stat_valid) + { + size_t len = strlen (file); + if (len && file[len - 1] == '/') + return chown (file, uid, gid); + } +# endif + + result = lchown (file, uid, gid); + +# if CHOWN_CHANGE_TIME_BUG && HAVE_LCHMOD + if (result == 0 && stat_valid + && (uid == st.st_uid || uid == (uid_t) -1) + && (gid == st.st_gid || gid == (gid_t) -1)) + { + /* No change in ownership, but at least one argument was not -1, + so we are required to update ctime. Since lchown succeeded, + we assume that lchmod will do likewise. But if the system + lacks lchmod and lutimes, we are out of luck. Oh well. */ + result = lchmod (file, st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO + | S_ISUID | S_ISGID | S_ISVTX)); + } +# endif + + return result; +} + +#endif /* HAVE_LCHOWN */ diff --git a/gnu/link.c b/gnu/link.c new file mode 100644 index 00000000..8460a5f3 --- /dev/null +++ b/gnu/link.c @@ -0,0 +1,214 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Emulate link on platforms that lack it, namely native Windows platforms. + + Copyright (C) 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +#include <unistd.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +#if !HAVE_LINK +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN +# include <windows.h> + +/* CreateHardLink was introduced only in Windows 2000. */ +typedef BOOL (WINAPI * CreateHardLinkFuncType) (LPCTSTR lpFileName, + LPCTSTR 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; +} + +int +link (const char *file1, const char *file2) +{ + char *dir; + size_t len1 = strlen (file1); + size_t len2 = strlen (file2); + if (!initialized) + initialize (); + if (CreateHardLinkFunc == NULL) + { + /* System does not support hard links. */ + errno = EPERM; + return -1; + } + /* Reject trailing slashes on non-directories; mingw does not + support hard-linking directories. */ + if ((len1 && (file1[len1 - 1] == '/' || file1[len1 - 1] == '\\')) + || (len2 && (file2[len2 - 1] == '/' || file2[len2 - 1] == '\\'))) + { + struct stat st; + if (stat (file1, &st) == 0 && S_ISDIR (st.st_mode)) + errno = EPERM; + else + errno = ENOTDIR; + 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) == -1) + { + int saved_errno = errno; + free (dir); + errno = saved_errno; + 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)) + { + 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) == -1) + { + int saved_errno = errno; + free (dir); + errno = saved_errno; + return -1; + } + } + free (dir); + } + return link (file1, file2); +} +#endif /* HAVE_LINK */ diff --git a/gnu/linkat.c b/gnu/linkat.c new file mode 100644 index 00000000..d4ae7678 --- /dev/null +++ b/gnu/linkat.c @@ -0,0 +1,345 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Create a hard link relative to open directories. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <unistd.h> + +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +#include "areadlink.h" +#include "dirname.h" +#include "filenamecat.h" +#include "openat-priv.h" + +#if HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif +#ifndef MAXSYMLINKS +# ifdef SYMLOOP_MAX +# define MAXSYMLINKS SYMLOOP_MAX +# else +# define MAXSYMLINKS 20 +# endif +#endif + +#if !HAVE_LINKAT + +/* Create a link. If FILE1 is a symlink, either create a hardlink to + that symlink, or fake it by creating an identical symlink. */ +# if LINK_FOLLOWS_SYMLINKS == 0 +# define link_immediate link +# else +static int +link_immediate (char const *file1, char const *file2) +{ + char *target = areadlink (file1); + if (target) + { + /* A symlink cannot be modified in-place. Therefore, creating + an identical symlink behaves like a hard link to a symlink, + except for incorrect st_ino and st_nlink. However, we must + be careful of EXDEV. */ + struct stat st1; + struct stat st2; + char *dir = mdir_name (file2); + if (!dir) + { + free (target); + errno = ENOMEM; + return -1; + } + if (lstat (file1, &st1) == 0 && stat (dir, &st2) == 0) + { + if (st1.st_dev == st2.st_dev) + { + int result = symlink (target, file2); + int saved_errno = errno; + free (target); + free (dir); + errno = saved_errno; + return result; + } + free (target); + free (dir); + errno = EXDEV; + return -1; + } + free (target); + free (dir); + } + if (errno == ENOMEM) + return -1; + return link (file1, file2); +} +# endif /* LINK_FOLLOWS_SYMLINKS == 0 */ + +/* Create a link. If FILE1 is a symlink, create a hardlink to the + canonicalized file. */ +# if 0 < LINK_FOLLOWS_SYMLINKS +# define link_follow link +# else +static int +link_follow (char const *file1, char const *file2) +{ + char *name = (char *) file1; + char *target; + int result; + int i = MAXSYMLINKS; + + /* Using realpath or canonicalize_file_name is too heavy-handed: we + don't need an absolute name, and we don't need to resolve + intermediate symlinks, just the basename of each iteration. */ + while (i-- && (target = areadlink (name))) + { + if (IS_ABSOLUTE_FILE_NAME (target)) + { + if (name != file1) + free (name); + name = target; + } + else + { + char *dir = mdir_name (name); + if (name != file1) + free (name); + if (!dir) + { + free (target); + errno = ENOMEM; + return -1; + } + name = mfile_name_concat (dir, target, NULL); + free (dir); + free (target); + if (!name) + { + errno = ENOMEM; + return -1; + } + } + } + if (i < 0) + { + target = NULL; + errno = ELOOP; + } + if (!target && errno != EINVAL) + { + if (name != file1) + { + int saved_errno = errno; + free (name); + errno = saved_errno; + } + return -1; + } + result = link (name, file2); + if (name != file1) + { + int saved_errno = errno; + free (name); + errno = saved_errno; + } + return result; +} +# endif /* 0 < LINK_FOLLOWS_SYMLINKS */ + +/* On Solaris, link() doesn't follow symlinks by default, but does so as soon + as a library or executable takes part in the program that has been compiled + with "c99" or "cc -xc99=all" or "cc ... /usr/lib/values-xpg4.o ...". */ +# if LINK_FOLLOWS_SYMLINKS == -1 + +/* Reduce the penalty of link_immediate and link_follow by incorporating the + knowledge that link()'s behaviour depends on the __xpg4 variable. */ +extern int __xpg4; + +static int +solaris_optimized_link_immediate (char const *file1, char const *file2) +{ + if (__xpg4 == 0) + return link (file1, file2); + return link_immediate (file1, file2); +} + +static int +solaris_optimized_link_follow (char const *file1, char const *file2) +{ + if (__xpg4 != 0) + return link (file1, file2); + return link_follow (file1, file2); +} + +# define link_immediate solaris_optimized_link_immediate +# define link_follow solaris_optimized_link_follow + +# endif + +/* Create a link to FILE1, in the directory open on descriptor FD1, to FILE2, + in the directory open on descriptor FD2. If FILE1 is a symlink, FLAG + controls whether to dereference FILE1 first. If possible, do it without + changing the working directory. Otherwise, resort to using + save_cwd/fchdir, then rename/restore_cwd. If either the save_cwd or + the restore_cwd fails, then give a diagnostic and exit nonzero. */ + +int +linkat (int fd1, char const *file1, int fd2, char const *file2, int flag) +{ + if (flag & ~AT_SYMLINK_FOLLOW) + { + errno = EINVAL; + return -1; + } + return at_func2 (fd1, file1, fd2, file2, + flag ? link_follow : link_immediate); +} + +#else /* HAVE_LINKAT */ + +# undef linkat + +/* Create a link. If FILE1 is a symlink, create a hardlink to the + canonicalized file. */ + +static int +linkat_follow (int fd1, char const *file1, int fd2, char const *file2) +{ + char *name = (char *) file1; + char *target; + int result; + int i = MAXSYMLINKS; + + /* There is no realpathat. */ + while (i-- && (target = areadlinkat (fd1, name))) + { + if (IS_ABSOLUTE_FILE_NAME (target)) + { + if (name != file1) + free (name); + name = target; + } + else + { + char *dir = mdir_name (name); + if (name != file1) + free (name); + if (!dir) + { + free (target); + errno = ENOMEM; + return -1; + } + name = mfile_name_concat (dir, target, NULL); + free (dir); + free (target); + if (!name) + { + errno = ENOMEM; + return -1; + } + } + } + if (i < 0) + { + target = NULL; + errno = ELOOP; + } + if (!target && errno != EINVAL) + { + if (name != file1) + { + int saved_errno = errno; + free (name); + errno = saved_errno; + } + return -1; + } + result = linkat (fd1, name, fd2, file2, 0); + if (name != file1) + { + int saved_errno = errno; + free (name); + errno = saved_errno; + } + return result; +} + + +/* Like linkat, but guarantee that AT_SYMLINK_FOLLOW works even on + older Linux kernels. */ + +int +rpl_linkat (int fd1, char const *file1, int fd2, char const *file2, int flag) +{ + if (flag & ~AT_SYMLINK_FOLLOW) + { + errno = EINVAL; + return -1; + } + +# if LINKAT_TRAILING_SLASH_BUG + /* Reject trailing slashes on non-directories. */ + { + size_t len1 = strlen (file1); + size_t len2 = strlen (file2); + if ((len1 && file1[len1 - 1] == '/') + || (len2 && file2[len2 - 1] == '/')) + { + /* Let linkat() decide whether hard-linking directories is legal. + If fstatat() fails, then linkat() should fail for the same reason; + if fstatat() succeeds, require a directory. */ + struct stat st; + if (fstatat (fd1, file1, &st, flag ? 0 : AT_SYMLINK_NOFOLLOW)) + return -1; + if (!S_ISDIR (st.st_mode)) + { + errno = ENOTDIR; + return -1; + } + } + } +# endif + + if (!flag) + return linkat (fd1, file1, fd2, file2, flag); + + /* Cache the information on whether the system call really works. */ + { + static int have_follow_really; /* 0 = unknown, 1 = yes, -1 = no */ + if (0 <= have_follow_really) + { + int result = linkat (fd1, file1, fd2, file2, flag); + if (!(result == -1 && errno == EINVAL)) + { + have_follow_really = 1; + return result; + } + have_follow_really = -1; + } + } + return linkat_follow (fd1, file1, fd2, file2); +} + +#endif /* HAVE_LINKAT */ diff --git a/gnu/localcharset.c b/gnu/localcharset.c new file mode 100644 index 00000000..f645c18c --- /dev/null +++ b/gnu/localcharset.c @@ -0,0 +1,549 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Determine a canonical name for the current locale's character encoding. + + Copyright (C) 2000-2006, 2008-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Bruno Haible <bruno@clisp.org>. */ + +#include <config.h> + +/* Specification. */ +#include "localcharset.h" + +#include <fcntl.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET +# define DARWIN7 /* Darwin 7 or newer, i.e. MacOS X 10.3 or newer */ +#endif + +#if defined _WIN32 || defined __WIN32__ +# define WINDOWS_NATIVE +#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 +# include <unistd.h> +# if HAVE_LANGINFO_CODESET +# include <langinfo.h> +# else +# if 0 /* see comment below */ +# include <locale.h> +# endif +# endif +# ifdef __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +# endif +#elif defined WINDOWS_NATIVE +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +#endif +#if defined OS2 +# define INCL_DOS +# include <os2.h> +#endif + +#if ENABLE_RELOCATABLE +# include "relocatable.h" +#else +# define relocate(pathname) (pathname) +#endif + +/* Get LIBDIR. */ +#ifndef LIBDIR +# include "configmake.h" +#endif + +/* Define O_NOFOLLOW to 0 on platforms where it does not exist. */ +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif + +#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ + /* Native Windows, Cygwin, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +#endif + +#ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +#endif + +#ifndef ISSLASH +# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +#endif + +#if HAVE_DECL_GETC_UNLOCKED +# undef getc +# define getc getc_unlocked +#endif + +/* The following static variable is declared 'volatile' to avoid a + possible multithread problem in the function get_charset_aliases. If we + are running in a threaded environment, and if two threads initialize + 'charset_aliases' simultaneously, both will produce the same value, + and everything will be ok if the two assignments to 'charset_aliases' + are atomic. But I don't know what will happen if the two assignments mix. */ +#if __STDC__ != 1 +# define volatile /* empty */ +#endif +/* Pointer to the contents of the charset.alias file, if it has already been + read, else NULL. Its format is: + ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ +static const char * volatile charset_aliases; + +/* Return a pointer to the contents of the charset.alias file. */ +static const char * +get_charset_aliases (void) +{ + const char *cp; + + cp = charset_aliases; + if (cp == NULL) + { +#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__) + const char *dir; + const char *base = "charset.alias"; + char *file_name; + + /* Make it possible to override the charset.alias location. This is + necessary for running the testsuite before "make install". */ + dir = getenv ("CHARSETALIASDIR"); + if (dir == NULL || dir[0] == '\0') + dir = relocate (LIBDIR); + + /* Concatenate dir and base into freshly allocated file_name. */ + { + size_t dir_len = strlen (dir); + size_t base_len = strlen (base); + int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); + file_name = (char *) malloc (dir_len + add_slash + base_len + 1); + if (file_name != NULL) + { + memcpy (file_name, dir, dir_len); + if (add_slash) + file_name[dir_len] = DIRECTORY_SEPARATOR; + memcpy (file_name + dir_len + add_slash, base, base_len + 1); + } + } + + if (file_name == NULL) + /* Out of memory. Treat the file as empty. */ + cp = ""; + else + { + int fd; + + /* Open the file. Reject symbolic links on platforms that support + O_NOFOLLOW. This is a security feature. Without it, an attacker + could retrieve parts of the contents (namely, the tail of the + first line that starts with "* ") of an arbitrary file by placing + a symbolic link to that file under the name "charset.alias" in + some writable directory and defining the environment variable + CHARSETALIASDIR to point to that directory. */ + fd = open (file_name, + O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0)); + if (fd < 0) + /* File not found. Treat it as empty. */ + cp = ""; + else + { + FILE *fp; + + fp = fdopen (fd, "r"); + if (fp == NULL) + { + /* Out of memory. Treat the file as empty. */ + close (fd); + cp = ""; + } + else + { + /* Parse the file's contents. */ + char *res_ptr = NULL; + size_t res_size = 0; + + for (;;) + { + int c; + char buf1[50+1]; + char buf2[50+1]; + size_t l1, l2; + char *old_res_ptr; + + c = getc (fp); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') + { + /* Skip comment, to end of line. */ + do + c = getc (fp); + while (!(c == EOF || c == '\n')); + if (c == EOF) + break; + continue; + } + ungetc (c, fp); + if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) + break; + l1 = strlen (buf1); + l2 = strlen (buf2); + old_res_ptr = res_ptr; + if (res_size == 0) + { + res_size = l1 + 1 + l2 + 1; + res_ptr = (char *) malloc (res_size + 1); + } + else + { + res_size += l1 + 1 + l2 + 1; + res_ptr = (char *) realloc (res_ptr, res_size + 1); + } + if (res_ptr == NULL) + { + /* Out of memory. */ + res_size = 0; + free (old_res_ptr); + break; + } + strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); + strcpy (res_ptr + res_size - (l2 + 1), buf2); + } + fclose (fp); + if (res_size == 0) + cp = ""; + else + { + *(res_ptr + res_size) = '\0'; + cp = res_ptr; + } + } + } + + free (file_name); + } + +#else + +# if defined DARWIN7 + /* To avoid the trouble of installing a file that is shared by many + GNU packages -- many packaging systems have problems with this --, + simply inline the aliases here. */ + cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" + "ISO8859-2" "\0" "ISO-8859-2" "\0" + "ISO8859-4" "\0" "ISO-8859-4" "\0" + "ISO8859-5" "\0" "ISO-8859-5" "\0" + "ISO8859-7" "\0" "ISO-8859-7" "\0" + "ISO8859-9" "\0" "ISO-8859-9" "\0" + "ISO8859-13" "\0" "ISO-8859-13" "\0" + "ISO8859-15" "\0" "ISO-8859-15" "\0" + "KOI8-R" "\0" "KOI8-R" "\0" + "KOI8-U" "\0" "KOI8-U" "\0" + "CP866" "\0" "CP866" "\0" + "CP949" "\0" "CP949" "\0" + "CP1131" "\0" "CP1131" "\0" + "CP1251" "\0" "CP1251" "\0" + "eucCN" "\0" "GB2312" "\0" + "GB2312" "\0" "GB2312" "\0" + "eucJP" "\0" "EUC-JP" "\0" + "eucKR" "\0" "EUC-KR" "\0" + "Big5" "\0" "BIG5" "\0" + "Big5HKSCS" "\0" "BIG5-HKSCS" "\0" + "GBK" "\0" "GBK" "\0" + "GB18030" "\0" "GB18030" "\0" + "SJIS" "\0" "SHIFT_JIS" "\0" + "ARMSCII-8" "\0" "ARMSCII-8" "\0" + "PT154" "\0" "PT154" "\0" + /*"ISCII-DEV" "\0" "?" "\0"*/ + "*" "\0" "UTF-8" "\0"; +# endif + +# if defined VMS + /* To avoid the troubles of an extra file charset.alias_vms in the + sources of many GNU packages, simply inline the aliases here. */ + /* The list of encodings is taken from the OpenVMS 7.3-1 documentation + "Compaq C Run-Time Library Reference Manual for OpenVMS systems" + section 10.7 "Handling Different Character Sets". */ + cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" + "ISO8859-2" "\0" "ISO-8859-2" "\0" + "ISO8859-5" "\0" "ISO-8859-5" "\0" + "ISO8859-7" "\0" "ISO-8859-7" "\0" + "ISO8859-8" "\0" "ISO-8859-8" "\0" + "ISO8859-9" "\0" "ISO-8859-9" "\0" + /* Japanese */ + "eucJP" "\0" "EUC-JP" "\0" + "SJIS" "\0" "SHIFT_JIS" "\0" + "DECKANJI" "\0" "DEC-KANJI" "\0" + "SDECKANJI" "\0" "EUC-JP" "\0" + /* Chinese */ + "eucTW" "\0" "EUC-TW" "\0" + "DECHANYU" "\0" "DEC-HANYU" "\0" + "DECHANZI" "\0" "GB2312" "\0" + /* Korean */ + "DECKOREAN" "\0" "EUC-KR" "\0"; +# endif + +# if defined WINDOWS_NATIVE || defined __CYGWIN__ + /* To avoid the troubles of installing a separate file in the same + directory as the DLL and of retrieving the DLL's directory at + runtime, simply inline the aliases here. */ + + cp = "CP936" "\0" "GBK" "\0" + "CP1361" "\0" "JOHAB" "\0" + "CP20127" "\0" "ASCII" "\0" + "CP20866" "\0" "KOI8-R" "\0" + "CP20936" "\0" "GB2312" "\0" + "CP21866" "\0" "KOI8-RU" "\0" + "CP28591" "\0" "ISO-8859-1" "\0" + "CP28592" "\0" "ISO-8859-2" "\0" + "CP28593" "\0" "ISO-8859-3" "\0" + "CP28594" "\0" "ISO-8859-4" "\0" + "CP28595" "\0" "ISO-8859-5" "\0" + "CP28596" "\0" "ISO-8859-6" "\0" + "CP28597" "\0" "ISO-8859-7" "\0" + "CP28598" "\0" "ISO-8859-8" "\0" + "CP28599" "\0" "ISO-8859-9" "\0" + "CP28605" "\0" "ISO-8859-15" "\0" + "CP38598" "\0" "ISO-8859-8" "\0" + "CP51932" "\0" "EUC-JP" "\0" + "CP51936" "\0" "GB2312" "\0" + "CP51949" "\0" "EUC-KR" "\0" + "CP51950" "\0" "EUC-TW" "\0" + "CP54936" "\0" "GB18030" "\0" + "CP65001" "\0" "UTF-8" "\0"; +# endif +#endif + + charset_aliases = cp; + } + + return cp; +} + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + 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; + const char *aliases; + +#if !(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 buf[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 (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + } + + /* 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. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + } +# 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 SunOS 4 or DJGPP) have only the C locale. Therefore we don't + use setlocale here; it would return "C" when it doesn't support the + locale name the user has set. */ +# if 0 + locale = setlocale (LC_CTYPE, NULL); +# endif + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + } + + /* On some old systems, one used to set locale = "iso8859_1". On others, + you set it to "language_COUNTRY.charset". In any case, we resolve it + through the charset.alias file. */ + codeset = locale; + +# endif + +#elif defined WINDOWS_NATIVE + + static char buf[2 + 10 + 1]; + + /* The Windows API has a function returning the locale's codepage as a + number: GetACP(). + When the output goes to a console window, it needs to be provided in + GetOEMCP() encoding if the console is using a raster font, or in + GetConsoleOutputCP() encoding if it is using a TrueType font. + But in GUI programs and for output sent to files and pipes, GetACP() + encoding is the best bet. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + +#elif defined OS2 + + const char *locale; + static char buf[2 + 10 + 1]; + ULONG cp[3]; + ULONG cplen; + + /* 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 (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + + /* Resolve through the charset.alias file. */ + codeset = locale; + } + else + { + /* OS/2 has a function returning the locale's codepage as a number. */ + if (DosQueryCp (sizeof (cp), cp, &cplen)) + codeset = ""; + else + { + sprintf (buf, "CP%u", cp[0]); + codeset = buf; + } + } + +#endif + + if (codeset == NULL) + /* The canonical name cannot be determined. */ + codeset = ""; + + /* Resolve alias. */ + for (aliases = get_charset_aliases (); + *aliases != '\0'; + aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) + if (strcmp (codeset, aliases) == 0 + || (aliases[0] == '*' && aliases[1] == '\0')) + { + codeset = aliases + strlen (aliases) + 1; + break; + } + + /* 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"; + + return codeset; +} diff --git a/gnu/localcharset.h b/gnu/localcharset.h new file mode 100644 index 00000000..ed36b00a --- /dev/null +++ b/gnu/localcharset.h @@ -0,0 +1,43 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Determine a canonical name for the current locale's character encoding. + Copyright (C) 2000-2003, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU CHARSET Library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#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 in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ +extern const char * locale_charset (void); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _LOCALCHARSET_H */ diff --git a/gnu/lseek.c b/gnu/lseek.c new file mode 100644 index 00000000..9928769d --- /dev/null +++ b/gnu/lseek.c @@ -0,0 +1,66 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* An lseek() function that detects pipes. + Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Windows platforms. */ +/* Get GetFileType. */ +# include <windows.h> +/* Get _get_osfhandle. */ +# include "msvc-nothrow.h" +#else +# include <sys/stat.h> +#endif +#include <errno.h> + +#undef lseek + +off_t +rpl_lseek (int fd, off_t offset, int whence) +{ +#if (defined _WIN32 || 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; + } +#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 + return lseek (fd, offset, whence); +} diff --git a/gnu/lstat.c b/gnu/lstat.c new file mode 100644 index 00000000..93579951 --- /dev/null +++ b/gnu/lstat.c @@ -0,0 +1,99 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Work around a bug of lstat on some systems + + Copyright (C) 1997-2006, 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering */ + +/* If the user's config.h happens to include <sys/stat.h>, let it include only + the system's <sys/stat.h> here, so that orig_lstat doesn't recurse to + rpl_lstat. */ +#define __need_system_sys_stat_h +#include <config.h> + +#if !HAVE_LSTAT +/* On systems that lack symlinks, our replacement <sys/stat.h> 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 <sys/types.h> +# include <sys/stat.h> +# undef __need_system_sys_stat_h + +static inline int +orig_lstat (const char *filename, struct stat *buf) +{ + return lstat (filename, buf); +} + +/* Specification. */ +/* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc + eliminates this include because of the preliminary #include <sys/stat.h> + above. */ +# include "sys/stat.h" + +# include <string.h> +# include <errno.h> + +/* 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) +{ + size_t len; + int lstat_result = orig_lstat (file, sbuf); + + if (lstat_result != 0) + return lstat_result; + + /* 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. */ + len = strlen (file); + if (file[len - 1] != '/' || S_ISDIR (sbuf->st_mode)) + return 0; + + /* At this point, a trailing slash is only permitted 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; + } + return stat (file, sbuf); +} + +#endif /* HAVE_LSTAT */ diff --git a/gnu/malloc.c b/gnu/malloc.c new file mode 100644 index 00000000..bf75a300 --- /dev/null +++ b/gnu/malloc.c @@ -0,0 +1,59 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* malloc() function that is glibc compatible. + + Copyright (C) 1997-1998, 2006-2007, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* written by Jim Meyering and Bruno Haible */ + +#define _GL_USE_STDLIB_ALLOC 1 +#include <config.h> +/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */ +#ifdef malloc +# define NEED_MALLOC_GNU 1 +# undef malloc +/* Whereas the gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */ +#elif GNULIB_MALLOC_GNU && !HAVE_MALLOC_GNU +# define NEED_MALLOC_GNU 1 +#endif + +#include <stdlib.h> + +#include <errno.h> + +/* Allocate an N-byte block of memory from the heap. + If N is zero, allocate a 1-byte block. */ + +void * +rpl_malloc (size_t n) +{ + void *result; + +#if NEED_MALLOC_GNU + if (n == 0) + n = 1; +#endif + + result = malloc (n); + +#if !HAVE_MALLOC_POSIX + if (result == NULL) + errno = ENOMEM; +#endif + + return result; +} diff --git a/gnu/malloca.c b/gnu/malloca.c new file mode 100644 index 00000000..601866dd --- /dev/null +++ b/gnu/malloca.c @@ -0,0 +1,141 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Safe automatic memory allocation. + Copyright (C) 2003, 2006-2007, 2009-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#define _GL_USE_STDLIB_ALLOC 1 +#include <config.h> + +/* Specification. */ +#include "malloca.h" + +#include "verify.h" + +/* The speed critical point in this file is freea() applied to an alloca() + result: it must be fast, to match the speed of alloca(). The speed of + mmalloca() and freea() in the other case are not critical, because they + are only invoked for big memory sizes. */ + +#if HAVE_ALLOCA + +/* Store the mmalloca() results in a hash table. This is needed to reliably + distinguish a mmalloca() result and an alloca() result. + + Although it is possible that the same pointer is returned by alloca() and + by mmalloca() at different times in the same application, it does not lead + to a bug in freea(), because: + - Before a pointer returned by alloca() can point into malloc()ed memory, + the function must return, and once this has happened the programmer must + not call freea() on it anyway. + - Before a pointer returned by mmalloca() can point into the stack, it + must be freed. The only function that can free it is freea(), and + when freea() frees it, it also removes it from the hash table. */ + +#define MAGIC_NUMBER 0x1415fb4a +#define MAGIC_SIZE sizeof (int) +/* This is how the header info would look like without any alignment + considerations. */ +struct preliminary_header { void *next; char room[MAGIC_SIZE]; }; +/* But the header's size must be a multiple of sa_alignment_max. */ +#define HEADER_SIZE \ + (((sizeof (struct preliminary_header) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max) +struct header { void *next; char room[HEADER_SIZE - sizeof (struct preliminary_header) + MAGIC_SIZE]; }; +verify (HEADER_SIZE == sizeof (struct header)); +/* We make the hash table quite big, so that during lookups the probability + of empty hash buckets is quite high. There is no need to make the hash + table resizable, because when the hash table gets filled so much that the + lookup becomes slow, it means that the application has memory leaks. */ +#define HASH_TABLE_SIZE 257 +static void * mmalloca_results[HASH_TABLE_SIZE]; + +#endif + +void * +mmalloca (size_t n) +{ +#if HAVE_ALLOCA + /* Allocate one more word, that serves as an indicator for malloc()ed + memory, so that freea() of an alloca() result is fast. */ + size_t nplus = n + HEADER_SIZE; + + if (nplus >= n) + { + char *p = (char *) malloc (nplus); + + if (p != NULL) + { + size_t slot; + + p += HEADER_SIZE; + + /* Put a magic number into the indicator word. */ + ((int *) p)[-1] = MAGIC_NUMBER; + + /* Enter p into the hash table. */ + slot = (unsigned long) p % HASH_TABLE_SIZE; + ((struct header *) (p - HEADER_SIZE))->next = mmalloca_results[slot]; + mmalloca_results[slot] = p; + + 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) +{ + /* mmalloca() may have returned NULL. */ + if (p != NULL) + { + /* Attempt to quickly distinguish the mmalloca() result - which has + a magic indicator word - and the alloca() result - which has an + uninitialized indicator word. It is for this test that sa_increment + additional bytes are allocated in the alloca() case. */ + if (((int *) p)[-1] == MAGIC_NUMBER) + { + /* Looks like a mmalloca() result. To see whether it really is one, + perform a lookup in the hash table. */ + size_t slot = (unsigned long) p % HASH_TABLE_SIZE; + void **chain = &mmalloca_results[slot]; + for (; *chain != NULL;) + { + if (*chain == p) + { + /* Found it. Remove it from the hash table and free it. */ + char *p_begin = (char *) p - HEADER_SIZE; + *chain = ((struct header *) p_begin)->next; + free (p_begin); + return; + } + chain = &((struct header *) ((char *) *chain - HEADER_SIZE))->next; + } + } + /* At this point, we know it was not a mmalloca() result. */ + } +} +#endif diff --git a/gnu/malloca.h b/gnu/malloca.h new file mode 100644 index 00000000..a789590b --- /dev/null +++ b/gnu/malloca.h @@ -0,0 +1,136 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Safe automatic memory allocation. + Copyright (C) 2003-2007, 2009-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _MALLOCA_H +#define _MALLOCA_H + +#include <alloca.h> +#include <stddef.h> +#include <stdlib.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 an inline function. */ +# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL) +#else +# define safe_alloca(N) ((void) (N), NULL) +#endif + +/* malloca(N) is a safe variant of alloca(N). It allocates N bytes of + memory allocated on the stack, that must be freed using freea() before + the function returns. Upon failure, it returns NULL. */ +#if HAVE_ALLOCA +# define malloca(N) \ + ((N) < 4032 - sa_increment \ + ? (void *) ((char *) alloca ((N) + sa_increment) + sa_increment) \ + : mmalloca (N)) +#else +# define malloca(N) \ + mmalloca (N) +#endif +extern void * mmalloca (size_t n); + +/* Free a block of memory allocated through malloca(). */ +#if HAVE_ALLOCA +extern void freea (void *p); +#else +# define freea free +#endif + +/* nmalloca(N,S) is an overflow-safe variant of malloca (N * S). + It allocates an array of N objects, each with S bytes of memory, + on the stack. S must be positive and N must be nonnegative. + The array must be freed using freea() before the function returns. */ +#if 1 +/* Cf. the definition of xalloc_oversized. */ +# define nmalloca(n, s) \ + ((n) > (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) \ + ? NULL \ + : malloca ((n) * (s))) +#else +extern void * nmalloca (size_t n, size_t s); +#endif + + +#ifdef __cplusplus +} +#endif + + +/* ------------------- Auxiliary, non-public definitions ------------------- */ + +/* Determine the alignment of a type at compile time. */ +#if defined __GNUC__ +# define sa_alignof __alignof__ +#elif defined __cplusplus + template <class type> struct sa_alignof_helper { char __slot1; type __slot2; }; +# define sa_alignof(type) offsetof (sa_alignof_helper<type>, __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), +#if HAVE_LONG_LONG_INT + sa_alignment_longlong = sa_alignof (long long), +#endif + sa_alignment_longdouble = sa_alignof (long double), + sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1) +#if HAVE_LONG_LONG_INT + | (sa_alignment_longlong - 1) +#endif + | (sa_alignment_longdouble - 1) + ) + 1, +/* The increment that guarantees room for a magic word must be >= sizeof (int) + and a multiple of sa_alignment_max. */ + sa_increment = ((sizeof (int) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max +}; + +#endif /* _MALLOCA_H */ diff --git a/gnu/malloca.valgrind b/gnu/malloca.valgrind new file mode 100644 index 00000000..52f0a50f --- /dev/null +++ b/gnu/malloca.valgrind @@ -0,0 +1,7 @@ +# Suppress a valgrind message about use of uninitialized memory in freea(). +# This use is OK because it provides only a speedup. +{ + freea + Memcheck:Cond + fun:freea +} diff --git a/gnu/mbchar.c b/gnu/mbchar.c new file mode 100644 index 00000000..2fe81f28 --- /dev/null +++ b/gnu/mbchar.c @@ -0,0 +1,37 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 2001, 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + + +#include <config.h> + +#include <limits.h> + +#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/gnu/mbchar.h b/gnu/mbchar.h new file mode 100644 index 00000000..61886660 --- /dev/null +++ b/gnu/mbchar.h @@ -0,0 +1,352 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Multibyte character data type. + Copyright (C) 2001, 2005-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>. */ + +/* 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 <stdbool.h> +#include <string.h> + +/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before + <wchar.h>. + BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before + <wchar.h>. */ +#include <stdio.h> +#include <time.h> +#include <wchar.h> +#include <wctype.h> + +#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) + +/* <ctype.h>, <wctype.h> 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 <wchar.h> function. */ + +/* Unprintable characters appear as a small box of width 1. */ +#define MB_UNPRINTABLE_WIDTH 1 + +static 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. */ +static 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[]; + +static inline bool +is_basic (char c) +{ + return (is_basic_table [(unsigned char) c >> 5] >> ((unsigned char) c & 31)) + & 1; +} + +#else + +static 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 + +#endif /* _MBCHAR_H */ diff --git a/gnu/mbrtowc.c b/gnu/mbrtowc.c new file mode 100644 index 00000000..5a5d0eac --- /dev/null +++ b/gnu/mbrtowc.c @@ -0,0 +1,398 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert multibyte character to wide character. + Copyright (C) 1999-2002, 2005-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <wchar.h> + +#if GNULIB_defined_mbstate_t +/* Implement mbrtowc() on top of mbtowc(). */ + +# include <errno.h> +# include <stdlib.h> + +# include "localcharset.h" +# include "streq.h" +# include "verify.h" + + +verify (sizeof (mbstate_t) >= 4); + +static char internal_state[4]; + +size_t +mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) +{ + char *pstate = (char *)ps; + + if (s == NULL) + { + pwc = NULL; + s = ""; + n = 1; + } + + if (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; + + 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. */ + +# if __GLIBC__ || defined __UCLIBC__ + /* Work around bug <http://sourceware.org/bugzilla/show_bug.cgi?id=9674> */ + mbtowc (NULL, NULL, 0); +# endif + { + int res = mbtowc (pwc, p, m); + + if (res >= 0) + { + if (pwc != NULL && ((*pwc == 0) != (res == 0))) + abort (); + if (nstate >= (res > 0 ? res : 1)) + abort (); + res -= nstate; + pstate[0] = 0; + return res; + } + + /* mbtowc does not distinguish between invalid and incomplete multibyte + sequences. But mbrtowc needs to make this distinction. + There are two possible approaches: + - Use iconv() and its return value. + - Use built-in knowledge about the possible encodings. + Given the low quality of implementation of iconv() on the systems that + lack mbrtowc(), we use the second approach. + The possible encodings are: + - 8-bit encodings, + - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS, + - UTF-8. + Use specialized code for each. */ + if (m >= 4 || m >= MB_CUR_MAX) + goto invalid; + /* Here MB_CUR_MAX > 1 and 0 < m < 4. */ + { + const char *encoding = locale_charset (); + + if (STREQ (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) + { + /* Cf. unistr/u8-mblen.c. */ + unsigned char c = (unsigned char) p[0]; + + if (c >= 0xc2) + { + if (c < 0xe0) + { + if (m == 1) + goto incomplete; + } + else if (c < 0xf0) + { + if (m == 1) + goto incomplete; + if (m == 2) + { + unsigned char c2 = (unsigned char) p[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xe1 || c2 >= 0xa0) + && (c != 0xed || c2 < 0xa0)) + goto incomplete; + } + } + else if (c <= 0xf4) + { + if (m == 1) + goto incomplete; + else /* m == 2 || m == 3 */ + { + unsigned char c2 = (unsigned char) p[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xf1 || c2 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) + { + if (m == 2) + goto incomplete; + else /* m == 3 */ + { + unsigned char c3 = (unsigned char) p[2]; + + if ((c3 ^ 0x80) < 0x40) + goto incomplete; + } + } + } + } + } + goto invalid; + } + + /* As a reference for this code, you can use the GNU libiconv + implementation. Look for uses of the RET_TOOFEW macro. */ + + if (STREQ (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0xa1 && c < 0xff) || c == 0x8e || c == 0x8f) + goto incomplete; + } + if (m == 2) + { + unsigned char c = (unsigned char) p[0]; + + if (c == 0x8f) + { + unsigned char c2 = (unsigned char) p[1]; + + if (c2 >= 0xa1 && c2 < 0xff) + goto incomplete; + } + } + goto invalid; + } + if (STREQ (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) + || STREQ (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) + || STREQ (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if (c >= 0xa1 && c < 0xff) + goto incomplete; + } + goto invalid; + } + if (STREQ (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0xa1 && c < 0xff) || c == 0x8e) + goto incomplete; + } + else /* m == 2 || m == 3 */ + { + unsigned char c = (unsigned char) p[0]; + + if (c == 0x8e) + goto incomplete; + } + goto invalid; + } + if (STREQ (encoding, "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe)) + goto incomplete; + } + else /* m == 2 || m == 3 */ + { + unsigned char c = (unsigned char) p[0]; + + if (c >= 0x90 && c <= 0xe3) + { + unsigned char c2 = (unsigned char) p[1]; + + if (c2 >= 0x30 && c2 <= 0x39) + { + if (m == 2) + goto incomplete; + else /* m == 3 */ + { + unsigned char c3 = (unsigned char) p[2]; + + if (c3 >= 0x81 && c3 <= 0xfe) + goto incomplete; + } + } + } + } + goto invalid; + } + if (STREQ (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea) + || (c >= 0xf0 && c <= 0xf9)) + goto incomplete; + } + goto invalid; + } + + /* An unknown multibyte encoding. */ + goto incomplete; + } + + 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); + } + } +} + +#else +/* Override the system's mbrtowc() function. */ + +# undef mbrtowc + +size_t +rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) +{ +# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG + if (s == NULL) + { + pwc = NULL; + s = ""; + n = 1; + } +# endif + +# 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--) + { + wchar_t wc; + size_t 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. */ + if (pwc != NULL) + *pwc = wc; + return (wc == 0 ? 0 : count); + } + } + return (size_t)(-2); + } + } +# endif + +# if MBRTOWC_NUL_RETVAL_BUG + { + wchar_t wc; + size_t ret = mbrtowc (&wc, s, n, ps); + + if (ret != (size_t)(-1) && ret != (size_t)(-2)) + { + if (pwc != NULL) + *pwc = wc; + if (wc == 0) + ret = 0; + } + return ret; + } +# else + { +# if MBRTOWC_NULL_ARG1_BUG + wchar_t dummy; + + if (pwc == NULL) + pwc = &dummy; +# endif + + return mbrtowc (pwc, s, n, ps); + } +# endif +} + +#endif diff --git a/gnu/mbscasecmp.c b/gnu/mbscasecmp.c new file mode 100644 index 00000000..e674bc75 --- /dev/null +++ b/gnu/mbscasecmp.c @@ -0,0 +1,100 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Case-insensitive string comparison function. + Copyright (C) 1998-1999, 2005-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2005, + based on earlier glibc code. + + 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <string.h> + +#include <ctype.h> +#include <limits.h> + +#include "mbuiter.h" + +#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) + +/* 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! */ +int +mbscasecmp (const char *s1, const char *s2) +{ + if (s1 == s2) + return 0; + + /* Be careful not to look at the entire extent of s1 or s2 until needed. + This is useful because when two strings differ, the difference is + most often already in the very few first characters. */ + if (MB_CUR_MAX > 1) + { + mbui_iterator_t iter1; + mbui_iterator_t iter2; + + mbui_init (iter1, s1); + mbui_init (iter2, s2); + + while (mbui_avail (iter1) && mbui_avail (iter2)) + { + int cmp = mb_casecmp (mbui_cur (iter1), mbui_cur (iter2)); + + if (cmp != 0) + return cmp; + + mbui_advance (iter1); + mbui_advance (iter2); + } + if (mbui_avail (iter1)) + /* s2 terminated before s1. */ + return 1; + if (mbui_avail (iter2)) + /* s1 terminated before s2. */ + return -1; + return 0; + } + else + { + const unsigned char *p1 = (const unsigned char *) s1; + const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + 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 (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); + } +} diff --git a/gnu/mbsinit.c b/gnu/mbsinit.c new file mode 100644 index 00000000..5b520014 --- /dev/null +++ b/gnu/mbsinit.c @@ -0,0 +1,63 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Test for initial conversion state. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <wchar.h> + +#include "verify.h" + +#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ + +/* On native Windows, 'mbstate_t' is defined as 'int'. */ + +int +mbsinit (const mbstate_t *ps) +{ + return ps == NULL || *ps == 0; +} + +#else + +/* 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. + - 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; +} + +#endif diff --git a/gnu/mbsrtowcs-impl.h b/gnu/mbsrtowcs-impl.h new file mode 100644 index 00000000..079104ef --- /dev/null +++ b/gnu/mbsrtowcs-impl.h @@ -0,0 +1,124 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert string to wide string. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +size_t +mbsrtowcs (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) +{ + if (ps == NULL) + ps = &_gl_mbsrtowcs_state; + { + const char *src = *srcp; + + if (dest != NULL) + { + wchar_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/gnu/mbsrtowcs-state.c b/gnu/mbsrtowcs-state.c new file mode 100644 index 00000000..715ea126 --- /dev/null +++ b/gnu/mbsrtowcs-state.c @@ -0,0 +1,39 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert string to wide string. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include <wchar.h> + +/* 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 MacOS X 10.3, + see <http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00329.html>. + 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/gnu/mbsrtowcs.c b/gnu/mbsrtowcs.c new file mode 100644 index 00000000..2c62e665 --- /dev/null +++ b/gnu/mbsrtowcs.c @@ -0,0 +1,34 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert string to wide string. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <wchar.h> + +#include <errno.h> +#include <limits.h> +#include <stdlib.h> + +#include "strnlen1.h" + + +extern mbstate_t _gl_mbsrtowcs_state; + +#include "mbsrtowcs-impl.h" diff --git a/gnu/mbtowc-impl.h b/gnu/mbtowc-impl.h new file mode 100644 index 00000000..2bcf91ab --- /dev/null +++ b/gnu/mbtowc-impl.h @@ -0,0 +1,46 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert multibyte character to wide character. + Copyright (C) 2011-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2011. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* 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/gnu/mbtowc.c b/gnu/mbtowc.c new file mode 100644 index 00000000..55515ee1 --- /dev/null +++ b/gnu/mbtowc.c @@ -0,0 +1,28 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert multibyte character to wide character. + Copyright (C) 2011-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2011. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include <stdlib.h> + +#include <errno.h> +#include <string.h> +#include <wchar.h> + +#include "mbtowc-impl.h" diff --git a/gnu/mbuiter.h b/gnu/mbuiter.h new file mode 100644 index 00000000..fe29896b --- /dev/null +++ b/gnu/mbuiter.h @@ -0,0 +1,224 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Iterating through multibyte strings: macros for multi-byte encodings. + Copyright (C) 2001, 2005, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>. */ + +/* The macros in this file implement forward iteration through a + multi-byte string, without knowing its length a-priori. + + With these macros, an iteration loop that looks like + + char *iter; + for (iter = buf; *iter != '\0'; iter++) + { + do_something (*iter); + } + + becomes + + mbui_iterator_t iter; + for (mbui_init (iter, buf); mbui_avail (iter); mbui_advance (iter)) + { + do_something (mbui_cur_ptr (iter), mb_len (mbui_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. + + Compared to mbiter.h, the macros here don't need to know the string's + length a-priori. The downside is that at each step, the look-ahead + that guards against overrunning the terminating '\0' is more expensive. + The mbui_* macros are therefore suitable when there is a high probability + that only the first few multibyte characters need to be inspected. + Whereas the mbi_* macros are better if usually the iteration runs + through the entire string. + + mbui_iterator_t + is a type usable for variable declarations. + + mbui_init (iter, startptr) + initializes the iterator, starting at startptr. + + mbui_avail (iter) + returns true if there are more multibyte chracters available before + the end of string is reached. In this case, mbui_cur (iter) is + initialized to the next multibyte chracter. + + mbui_advance (iter) + advances the iterator by one multibyte character. + + mbui_cur (iter) + returns the current multibyte character, of type mbchar_t. All the + macros defined in mbchar.h can be used on it. + + mbui_cur_ptr (iter) + return a pointer to the beginning of the current multibyte character. + + mbui_reloc (iter, ptrdiff) + relocates iterator when the string is moved by ptrdiff bytes. + + mbui_copy (&destiter, &srciter) + copies srciter to destiter. + + Here are the function prototypes of the macros. + + extern void mbui_init (mbui_iterator_t iter, const char *startptr); + extern bool mbui_avail (mbui_iterator_t iter); + extern void mbui_advance (mbui_iterator_t iter); + extern mbchar_t mbui_cur (mbui_iterator_t iter); + extern const char * mbui_cur_ptr (mbui_iterator_t iter); + extern void mbui_reloc (mbui_iterator_t iter, ptrdiff_t ptrdiff); + extern void mbui_copy (mbui_iterator_t *new, const mbui_iterator_t *old); + */ + +#ifndef _MBUITER_H +#define _MBUITER_H 1 + +#include <assert.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before + <wchar.h>. + BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before + <wchar.h>. */ +#include <stdio.h> +#include <time.h> +#include <wchar.h> + +#include "mbchar.h" +#include "strnlen1.h" + +struct mbuiter_multi +{ + 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 mbui_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 mbui_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 + */ +}; + +static inline void +mbuiter_multi_next (struct mbuiter_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, + strnlen1 (iter->cur.ptr, MB_CUR_MAX), + &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 = strlen (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; +} + +static inline void +mbuiter_multi_reloc (struct mbuiter_multi *iter, ptrdiff_t ptrdiff) +{ + iter->cur.ptr += ptrdiff; +} + +static inline void +mbuiter_multi_copy (struct mbuiter_multi *new_iter, const struct mbuiter_multi *old_iter) +{ + 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 mbuiter_multi mbui_iterator_t; +#define mbui_init(iter, startptr) \ + ((iter).cur.ptr = (startptr), \ + (iter).in_shift = false, memset (&(iter).state, '\0', sizeof (mbstate_t)), \ + (iter).next_done = false) +#define mbui_avail(iter) \ + (mbuiter_multi_next (&(iter)), !mb_isnul ((iter).cur)) +#define mbui_advance(iter) \ + ((iter).cur.ptr += (iter).cur.bytes, (iter).next_done = false) + +/* Access to the current character. */ +#define mbui_cur(iter) (iter).cur +#define mbui_cur_ptr(iter) (iter).cur.ptr + +/* Relocation. */ +#define mbui_reloc(iter, ptrdiff) mbuiter_multi_reloc (&iter, ptrdiff) + +/* Copying an iterator. */ +#define mbui_copy mbuiter_multi_copy + +#endif /* _MBUITER_H */ diff --git a/gnu/memchr.c b/gnu/memchr.c new file mode 100644 index 00000000..3cff1408 --- /dev/null +++ b/gnu/memchr.c @@ -0,0 +1,174 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2012 + 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 program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or any +later version. + +This 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _LIBC +# include <config.h> +#endif + +#include <string.h> + +#include <stddef.h> + +#if defined _LIBC +# include <memcopy.h> +#else +# define reg_char char +#endif + +#include <limits.h> + +#if HAVE_BP_SYM_H || defined _LIBC +# include <bp-sym.h> +#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/gnu/memchr.valgrind b/gnu/memchr.valgrind new file mode 100644 index 00000000..60f247e1 --- /dev/null +++ b/gnu/memchr.valgrind @@ -0,0 +1,14 @@ +# Suppress a valgrind message about use of uninitialized memory in memchr(). +# 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/gnu/mempcpy.c b/gnu/mempcpy.c new file mode 100644 index 00000000..4698fe56 --- /dev/null +++ b/gnu/mempcpy.c @@ -0,0 +1,31 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copy memory area and return pointer after last written byte. + Copyright (C) 2003, 2007, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include <string.h> + +/* 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; +} diff --git a/gnu/memrchr.c b/gnu/memrchr.c new file mode 100644 index 00000000..98197041 --- /dev/null +++ b/gnu/memrchr.c @@ -0,0 +1,163 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* memrchr -- find the last occurrence of a byte in a memory block + + Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2012 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 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 <http://www.gnu.org/licenses/>. */ + +#if defined _LIBC +# include <memcopy.h> +#else +# include <config.h> +# define reg_char char +#endif + +#include <string.h> +#include <limits.h> + +#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 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) + { + 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/gnu/mkdtemp.c b/gnu/mkdtemp.c new file mode 100644 index 00000000..5d09133f --- /dev/null +++ b/gnu/mkdtemp.c @@ -0,0 +1,41 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1999, 2001-2003, 2006-2007, 2009-2012 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +/* Extracted from misc/mkdtemp.c. */ + +#include <config.h> + +/* Specification. */ +#include <stdlib.h> + +#include "tempname.h" + +/* Generate a unique temporary directory from XTEMPLATE. + The last six characters of XTEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. + The directory is created, mode 700, and its name is returned. + (This function comes from OpenBSD.) */ +char * +mkdtemp (char *xtemplate) +{ + if (gen_tempname (xtemplate, 0, 0, GT_DIR)) + return NULL; + else + return xtemplate; +} diff --git a/gnu/mkfifo.c b/gnu/mkfifo.c new file mode 100644 index 00000000..f905c078 --- /dev/null +++ b/gnu/mkfifo.c @@ -0,0 +1,60 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Create a named fifo. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <sys/stat.h> + +#include <errno.h> +#include <string.h> + +#if !HAVE_MKFIFO +/* Mingw lacks mkfifo; always fail with ENOSYS. */ + +int +mkfifo (char const *name _GL_UNUSED, mode_t mode _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} + +#else /* HAVE_MKFIFO */ + +# undef mkfifo + +/* Create a named fifo FILE, with access permissions in MODE. Work +around trailing slash bugs. */ + +int +rpl_mkfifo (char const *name, mode_t mode) +{ +# if MKFIFO_TRAILING_SLASH_BUG + size_t len = strlen (name); + if (len && name[len - 1] == '/') + { + struct stat st; + if (stat (name, &st) == 0) + errno = EEXIST; + return -1; + } +# endif + return mkfifo (name, mode); +} +#endif /* HAVE_MKFIFO */ diff --git a/gnu/mkfifoat.c b/gnu/mkfifoat.c new file mode 100644 index 00000000..cc670fe1 --- /dev/null +++ b/gnu/mkfifoat.c @@ -0,0 +1,57 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Create a named fifo relative to an open directory. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <sys/stat.h> + +#if !HAVE_MKFIFO + +# include <errno.h> + +/* Mingw lacks mkfifo, so this wrapper is trivial. */ + +int +mkfifoat (int fd _GL_UNUSED, char const *path _GL_UNUSED, + mode_t mode _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} + +#else /* HAVE_MKFIFO */ + +/* Create a named fifo FILE relative to directory FD, with access + permissions in MODE. If possible, do it without changing the + working directory. Otherwise, resort to using save_cwd/fchdir, + then mkfifo/restore_cwd. If either the save_cwd or the restore_cwd + fails, then give a diagnostic and exit nonzero. */ + +# define AT_FUNC_NAME mkfifoat +# define AT_FUNC_F1 mkfifo +# define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode +# define AT_FUNC_POST_FILE_ARGS , mode +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS + +#endif /* HAVE_MKFIFO */ diff --git a/gnu/mknod.c b/gnu/mknod.c new file mode 100644 index 00000000..3b9921b2 --- /dev/null +++ b/gnu/mknod.c @@ -0,0 +1,76 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Create a device inode. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <sys/stat.h> + +#include <errno.h> +#include <string.h> + +#if !HAVE_MKNOD +/* Mingw lacks mknod; always fail with ENOSYS. */ + +int +mknod (char const *name _GL_UNUSED, mode_t mode _GL_UNUSED, + dev_t dev _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} + +#else /* HAVE_MKNOD */ + +# undef mknod + +/* Create a file system node FILE, with access permissions and file + type in MODE, and device type in DEV. Usually, non-root + applications can only create named fifos (mode includes S_IFIFO), + with DEV set to 0. Also work around trailing slash bugs. */ + +int +rpl_mknod (char const *name, mode_t mode, dev_t dev) +{ +# if MKFIFO_TRAILING_SLASH_BUG + /* Trailing slash only makes sense for directories. Of course, + using mknod to create a directory is not very portable, so it may + still fail later on. */ + if (!S_ISDIR (mode)) + { + size_t len = strlen (name); + if (len && name[len - 1] == '/') + { + struct stat st; + if (stat (name, &st) == 0) + errno = EEXIST; + return -1; + } + } +# endif +# if MKNOD_FIFO_BUG + /* POSIX requires mknod to create fifos for non-privileged + processes, but BSD implementations fail with EPERM. */ + if (S_ISFIFO (mode) && dev == 0) + return mkfifo (name, mode & ~S_IFIFO); +# endif + return mknod (name, mode, dev); +} + +#endif /* HAVE_MKNOD */ diff --git a/gnu/mknodat.c b/gnu/mknodat.c new file mode 100644 index 00000000..d6f5941c --- /dev/null +++ b/gnu/mknodat.c @@ -0,0 +1,59 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Create an inode relative to an open directory. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <sys/stat.h> + +#if !HAVE_MKNOD + +# include <errno.h> + +/* Mingw lacks mknod, so this wrapper is trivial. */ + +int +mknodat (int fd _GL_UNUSED, char const *path _GL_UNUSED, + mode_t mode _GL_UNUSED, dev_t dev _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} + +#else /* HAVE_MKFIFO */ + +/* Create a file system node FILE relative to directory FD, with + access permissions and file type in MODE, and device type in DEV. + Usually, non-root applications can only create named fifos, with + DEV set to 0. If possible, create the node without changing the + working directory. Otherwise, resort to using save_cwd/fchdir, + then mknod/restore_cwd. If either the save_cwd or the restore_cwd + fails, then give a diagnostic and exit nonzero. */ + +# define AT_FUNC_NAME mknodat +# define AT_FUNC_F1 mknod +# define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode, dev_t dev +# define AT_FUNC_POST_FILE_ARGS , mode, dev +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS + +#endif /* HAVE_MKFIFO */ diff --git a/gnu/mktime-internal.h b/gnu/mktime-internal.h new file mode 100644 index 00000000..8a1259ef --- /dev/null +++ b/gnu/mktime-internal.h @@ -0,0 +1,6 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#include <time.h> +time_t mktime_internal (struct tm *, + struct tm * (*) (time_t const *, struct tm *), + time_t *); diff --git a/gnu/mktime.c b/gnu/mktime.c new file mode 100644 index 00000000..3d75137e --- /dev/null +++ b/gnu/mktime.c @@ -0,0 +1,741 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert a 'struct tm' to a time_t value. + Copyright (C) 1993-1999, 2002-2007, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Paul Eggert <eggert@twinsun.com>. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Define this to have a standalone program to test this implementation of + mktime. */ +/* #define DEBUG 1 */ + +#ifndef _LIBC +# include <config.h> +#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 <time.h> + +#include <limits.h> + +#include <string.h> /* For the real memcpy prototype. */ + +#if DEBUG +# include <stdio.h> +# include <stdlib.h> +/* Make it work even if the system's libc has its own mktime routine. */ +# undef mktime +# define mktime my_mktime +#endif /* DEBUG */ + +/* Some of the code in this file assumes that signed integer overflow + silently wraps around. This assumption can't easily be programmed + around, nor can it be checked for portably at compile-time or + easily eliminated at run-time. + + Define WRAPV to 1 if the assumption is valid and if + #pragma GCC optimize ("wrapv") + does not trigger GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51793>. + Otherwise, define it to 0; this forces the use of slower code that, + while not guaranteed by the C Standard, works on all production + platforms that we know about. */ +#ifndef WRAPV +# if ((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) && defined __GLIBC__ +# pragma GCC optimize ("wrapv") +# define WRAPV 1 +# else +# define WRAPV 0 +# endif +#endif + +/* Verify a requirement at compile-time (unlike assert, which is runtime). */ +#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } + +/* A signed type that is at least one bit wider than int. */ +#if INT_MAX <= LONG_MAX / 2 +typedef long int long_int; +#else +typedef long long int long_int; +#endif +verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2); + +/* Shift A right by B bits portably, by dividing A by 2**B and + truncating towards minus infinity. A and B should be free of side + effects, and B should be in the range 0 <= B <= INT_BITS - 2, where + INT_BITS is the number of useful bits in an int. GNU code can + assume that INT_BITS is at least 32. + + ISO C99 says that A >> B is implementation-defined if A < 0. Some + implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift + right in the usual way when A < 0, so SHR falls back on division if + ordinary A >> B doesn't seem to be the usual signed shift. */ +#define SHR(a, b) \ + ((-1 >> 1 == -1 \ + && (long_int) -1 >> 1 == -1 \ + && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t))) \ + ? (a) >> (b) \ + : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) + +/* The extra casts in the following macros work around compiler bugs, + e.g., in Cray C 5.0.3.0. */ + +/* True if the arithmetic type T is an integer type. bool counts as + an integer. */ +#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) + +/* True if negative values of the signed integer type T use two's + complement, or if T is an unsigned integer type. */ +#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) + +/* True if the arithmetic type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* The maximum and minimum values for the integer type T. These + macros have undefined behavior if T is signed and has padding bits. + If this is a problem for you, please let us know how to fix it for + your host. */ +#define TYPE_MINIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) 0 \ + : ~ TYPE_MAXIMUM (t))) +#define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) + +#ifndef TIME_T_MIN +# define TIME_T_MIN TYPE_MINIMUM (time_t) +#endif +#ifndef TIME_T_MAX +# define TIME_T_MAX TYPE_MAXIMUM (time_t) +#endif +#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1) + +verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); +verify (twos_complement_arithmetic, + (TYPE_TWOS_COMPLEMENT (int) + && TYPE_TWOS_COMPLEMENT (long_int) + && TYPE_TWOS_COMPLEMENT (time_t))); + +#define EPOCH_YEAR 1970 +#define TM_YEAR_BASE 1900 +verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0); + +/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ +static inline int +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 } + }; + + +#ifndef _LIBC +/* Portable standalone applications should supply a <time.h> that + declares a POSIX-compliant localtime_r, for the benefit of older + implementations that lack localtime_r or have a nonstandard one. + See the gnulib time_r module for one way to implement this. */ +# undef __localtime_r +# define __localtime_r localtime_r +# define __mktime_internal mktime_internal +# include "mktime-internal.h" +#endif + +/* Return 1 if the values A and B differ according to the rules for + tm_isdst: A and B differ if one is zero and the other positive. */ +static int +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 time stamps. + + The YEAR values uses the same numbering as TP->tm_year. Values + need not be in the usual range. However, YEAR1 must not be less + than 2 * INT_MIN or greater than 2 * INT_MAX. + + The result may overflow. It is the caller's responsibility to + detect overflow. */ + +static inline time_t +ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, + int year0, int yday0, int hour0, int min0, int sec0) +{ + verify (C99_integer_division, -1 / 2 == 0); + + /* Compute intervening leap days correctly even if year is negative. + Take care to avoid integer overflow here. */ + int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3); + int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3); + int a100 = a4 / 25 - (a4 % 25 < 0); + int b100 = b4 / 25 - (b4 % 25 < 0); + int a400 = SHR (a100, 2); + int b400 = SHR (b100, 2); + int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); + + /* Compute the desired time in time_t precision. Overflow might + occur here. */ + time_t tyear1 = year1; + time_t years = tyear1 - year0; + time_t days = 365 * years + yday1 - yday0 + intervening_leap_days; + time_t hours = 24 * days + hour1 - hour0; + time_t minutes = 60 * hours + min1 - min0; + time_t seconds = 60 * minutes + sec1 - sec0; + return seconds; +} + +/* Return the average of A and B, even if A + B would overflow. */ +static time_t +time_t_avg (time_t a, time_t b) +{ + return SHR (a, 1) + SHR (b, 1) + (a & b & 1); +} + +/* Return 1 if A + B does not overflow. If time_t is unsigned and if + B's top bit is set, assume that the sum represents A - -B, and + return 1 if the subtraction does not wrap around. */ +static int +time_t_add_ok (time_t a, time_t b) +{ + if (! TYPE_SIGNED (time_t)) + { + time_t sum = a + b; + return (sum < a) == (TIME_T_MIDPOINT <= b); + } + else if (WRAPV) + { + time_t sum = a + b; + return (sum < a) == (b < 0); + } + else + { + time_t avg = time_t_avg (a, b); + return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; + } +} + +/* Return 1 if A + B does not overflow. */ +static int +time_t_int_add_ok (time_t a, int b) +{ + verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX); + if (WRAPV) + { + time_t sum = a + b; + return (sum < a) == (b < 0); + } + else + { + int a_odd = a & 1; + time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b)); + return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; + } +} + +/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), + assuming that *T corresponds to *TP and that no clock adjustments + occurred between *TP and the desired time. + If TP is null, return a value not equal to *T; this avoids false matches. + If overflow occurs, yield the minimal or maximal value, except do not + yield a value equal to *T. */ +static time_t +guess_time_tm (long_int year, long_int yday, int hour, int min, int sec, + const time_t *t, const struct tm *tp) +{ + if (tp) + { + time_t d = ydhms_diff (year, yday, hour, min, sec, + tp->tm_year, tp->tm_yday, + tp->tm_hour, tp->tm_min, tp->tm_sec); + if (time_t_add_ok (*t, d)) + return *t + d; + } + + /* Overflow occurred one way or another. Return the nearest result + that is actually in range, except don't report a zero difference + if the actual difference is nonzero, as that would cause a false + match; and don't oscillate between two values, as that would + confuse the spring-forward gap detector. */ + return (*t < TIME_T_MIDPOINT + ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN) + : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX)); +} + +/* 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. */ +static struct tm * +ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), + time_t *t, struct tm *tp) +{ + struct tm *r = convert (t, tp); + + if (!r && *t) + { + time_t bad = *t; + time_t ok = 0; + + /* BAD is a known unconvertible time_t, and OK is a known good one. + Use binary search to narrow the range between BAD and OK until + they differ by 1. */ + while (bad != ok + (bad < 0 ? -1 : 1)) + { + time_t mid = *t = time_t_avg (ok, bad); + r = convert (t, tp); + if (r) + ok = mid; + else + bad = mid; + } + + if (!r && ok) + { + /* The last conversion attempt failed; + revert to the most recent successful attempt. */ + *t = ok; + r = convert (t, tp); + } + } + + return r; +} + + +/* Convert *TP to a time_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. + This function is external because it is used also by timegm.c. */ +time_t +__mktime_internal (struct tm *tp, + struct tm *(*convert) (const time_t *, struct tm *), + time_t *offset) +{ + time_t t, gt, t0, t1, t2; + 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; + + /* 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 minor overflows correctly, + assuming int and time_t arithmetic wraps around. + Major overflows are caught at the end. */ + + /* 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; + + time_t guessed_offset = *offset; + + int sec_requested = sec; + + if (LEAP_SECONDS_POSSIBLE) + { + /* Handle out-of-range seconds specially, + since ydhms_tm_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. */ + + t0 = ydhms_diff (year, yday, hour, min, sec, + EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset); + + if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3) + { + /* time_t isn't large enough to rule out overflows, so check + for major overflows. A gross check suffices, since if t0 + has overflowed, it is off by a multiple of TIME_T_MAX - + TIME_T_MIN + 1. So ignore any component of the difference + that is bounded by a small value. */ + + /* Approximate log base 2 of the number of time units per + biennium. A biennium is 2 years; use this unit instead of + years to avoid integer overflow. For example, 2 average + Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds, + which is 63113904 seconds, and rint (log2 (63113904)) is + 26. */ + int ALOG2_SECONDS_PER_BIENNIUM = 26; + int ALOG2_MINUTES_PER_BIENNIUM = 20; + int ALOG2_HOURS_PER_BIENNIUM = 14; + int ALOG2_DAYS_PER_BIENNIUM = 10; + int LOG2_YEARS_PER_BIENNIUM = 1; + + int approx_requested_biennia = + (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM) + - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM) + + SHR (mday, ALOG2_DAYS_PER_BIENNIUM) + + SHR (hour, ALOG2_HOURS_PER_BIENNIUM) + + SHR (min, ALOG2_MINUTES_PER_BIENNIUM) + + (LEAP_SECONDS_POSSIBLE + ? 0 + : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM))); + + int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM); + int diff = approx_biennia - approx_requested_biennia; + int abs_diff = diff < 0 ? -1 - diff : diff; + + /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously + gives a positive value of 715827882. Setting a variable + first then doing math on it seems to work. + (ghazi@caip.rutgers.edu) */ + time_t time_t_max = TIME_T_MAX; + time_t time_t_min = TIME_T_MIN; + time_t overflow_threshold = + (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM; + + if (overflow_threshold < abs_diff) + { + /* Overflow occurred. Try repairing it; this might work if + the time zone offset is enough to undo the overflow. */ + time_t repaired_t0 = -1 - t0; + approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM); + diff = approx_biennia - approx_requested_biennia; + abs_diff = diff < 0 ? -1 - diff : diff; + if (overflow_threshold < abs_diff) + return -1; + guessed_offset += repaired_t0 - t0; + t0 = repaired_t0; + } + } + + /* Repeatedly use the error to improve the guess. */ + + for (t = t1 = t2 = t0, dst2 = 0; + (gt = guess_time_tm (year, yday, hour, min, sec, &t, + ranged_convert (convert, &t, &tm)), + t != gt); + t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0) + if (t == t1 && t != t2 + && (tm.tm_isdst < 0 + || (isdst < 0 + ? dst2 <= (tm.tm_isdst != 0) + : (isdst != 0) != (tm.tm_isdst != 0)))) + /* We can't possibly find a match, as we are oscillating + between two values. The requested time probably falls + within a spring-forward gap of size GT - T. Follow the common + practice in this case, which is to return a time that is GT - T + away from the requested time, preferring a time whose + tm_isdst differs from the requested value. (If no tm_isdst + was requested and only one of the two values has a nonzero + tm_isdst, prefer that value.) In practice, this is more + useful than returning -1. */ + goto offset_found; + else if (--remaining_probes == 0) + return -1; + + /* 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. This should work for all real + time zone histories in the tz database. */ + + /* 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; + + /* The longest period of DST in tzdata2003a is 536454000 seconds + (e.g., America/Jujuy starting 1946-10-01 01:00). The longest + period of non-DST is much longer, but it makes no real sense + to search for more than a year of non-DST, so use the DST + max. */ + int duration_max = 536454000; + + /* 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) + if (time_t_int_add_ok (t, delta * direction)) + { + time_t ot = t + delta * direction; + struct tm otm; + ranged_convert (convert, &ot, &otm); + if (! isdst_differ (isdst, otm.tm_isdst)) + { + /* We found the desired tm_isdst. + Extrapolate back to the desired time. */ + t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); + ranged_convert (convert, &t, &tm); + goto offset_found; + } + } + } + + offset_found: + *offset = guessed_offset + t - t0; + + if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec) + { + /* Adjust time to reflect the tm_sec requested, not the normalized value. + Also, repair any damage from a false match due to a leap second. */ + int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec; + if (! time_t_int_add_ok (t, sec_requested)) + return -1; + t1 = t + sec_requested; + if (! time_t_int_add_ok (t1, sec_adjustment)) + return -1; + t2 = t1 + sec_adjustment; + if (! convert (&t2, &tm)) + return -1; + t = t2; + } + + *tp = tm; + return t; +} + + +/* FIXME: This should use a signed type wide enough to hold any UTC + offset in seconds. 'int' should be good enough for GNU code. We + can't fix this unilaterally though, as other modules invoke + __mktime_internal. */ +static time_t localtime_offset; + +/* Convert *TP to a time_t value. */ +time_t +mktime (struct tm *tp) +{ +#ifdef _LIBC + /* POSIX.1 8.1.1 requires that whenever mktime() is called, the + time zone names contained in the external variable 'tzname' shall + be set as if the tzset() function had been called. */ + __tzset (); +#endif + + return __mktime_internal (tp, __localtime_r, &localtime_offset); +} + +#ifdef weak_alias +weak_alias (mktime, timelocal) +#endif + +#ifdef _LIBC +libc_hidden_def (mktime) +libc_hidden_weak (timelocal) +#endif + +#if DEBUG + +static int +not_equal_tm (const struct tm *a, const struct tm *b) +{ + return ((a->tm_sec ^ b->tm_sec) + | (a->tm_min ^ b->tm_min) + | (a->tm_hour ^ b->tm_hour) + | (a->tm_mday ^ b->tm_mday) + | (a->tm_mon ^ b->tm_mon) + | (a->tm_year ^ b->tm_year) + | (a->tm_yday ^ b->tm_yday) + | isdst_differ (a->tm_isdst, b->tm_isdst)); +} + +static void +print_tm (const struct tm *tp) +{ + if (tp) + printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d", + tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec, + tp->tm_yday, tp->tm_wday, tp->tm_isdst); + else + printf ("0"); +} + +static int +check_result (time_t tk, struct tm tmk, time_t tl, const struct tm *lt) +{ + if (tk != tl || !lt || not_equal_tm (&tmk, lt)) + { + printf ("mktime ("); + print_tm (lt); + printf (")\nyields ("); + print_tm (&tmk); + printf (") == %ld, should be %ld\n", (long int) tk, (long int) tl); + return 1; + } + + return 0; +} + +int +main (int argc, char **argv) +{ + int status = 0; + struct tm tm, tmk, tml; + struct tm *lt; + time_t tk, tl, tl1; + char trailer; + + if ((argc == 3 || argc == 4) + && (sscanf (argv[1], "%d-%d-%d%c", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer) + == 3) + && (sscanf (argv[2], "%d:%d:%d%c", + &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer) + == 3)) + { + tm.tm_year -= TM_YEAR_BASE; + tm.tm_mon--; + tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]); + tmk = tm; + tl = mktime (&tmk); + lt = localtime (&tl); + if (lt) + { + tml = *lt; + lt = &tml; + } + printf ("mktime returns %ld == ", (long int) tl); + print_tm (&tmk); + printf ("\n"); + status = check_result (tl, tmk, tl, lt); + } + else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0)) + { + time_t from = atol (argv[1]); + time_t by = atol (argv[2]); + time_t to = atol (argv[3]); + + if (argc == 4) + for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) + { + lt = localtime (&tl); + if (lt) + { + tmk = tml = *lt; + tk = mktime (&tmk); + status |= check_result (tk, tmk, tl, &tml); + } + else + { + printf ("localtime (%ld) yields 0\n", (long int) tl); + status = 1; + } + tl1 = tl + by; + if ((tl1 < tl) != (by < 0)) + break; + } + else + for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) + { + /* Null benchmark. */ + lt = localtime (&tl); + if (lt) + { + tmk = tml = *lt; + tk = tl; + status |= check_result (tk, tmk, tl, &tml); + } + else + { + printf ("localtime (%ld) yields 0\n", (long int) tl); + status = 1; + } + tl1 = tl + by; + if ((tl1 < tl) != (by < 0)) + break; + } + } + else + printf ("Usage:\ +\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\ +\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\ +\t%s FROM BY TO - # Do not test those values (for benchmark).\n", + argv[0], argv[0], argv[0]); + + return status; +} + +#endif /* DEBUG */ + +/* +Local Variables: +compile-command: "gcc -DDEBUG -I. -Wall -W -O2 -g mktime.c -o mktime" +End: +*/ diff --git a/gnu/modechange.c b/gnu/modechange.c new file mode 100644 index 00000000..d82dbb35 --- /dev/null +++ b/gnu/modechange.c @@ -0,0 +1,387 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* modechange.c -- file mode manipulation + + Copyright (C) 1989-1990, 1997-1999, 2001, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by David MacKenzie <djm@ai.mit.edu> */ + +/* The ASCII mode string is compiled into an array of 'struct + modechange', which can then be applied to each file to be changed. + We do this instead of re-parsing the ASCII string for each file + because the compiled form requires less computation to use; when + changing the mode of many files, this probably results in a + performance gain. */ + +#include <config.h> + +#include "modechange.h" +#include <sys/stat.h> +#include "stat-macros.h" +#include "xalloc.h" +#include <stdlib.h> + +/* The traditional octal values corresponding to each mode bit. */ +#define SUID 04000 +#define SGID 02000 +#define SVTX 01000 +#define RUSR 00400 +#define WUSR 00200 +#define XUSR 00100 +#define RGRP 00040 +#define WGRP 00020 +#define XGRP 00010 +#define ROTH 00004 +#define WOTH 00002 +#define XOTH 00001 +#define ALLM 07777 /* all octal mode bits */ + +/* Convert OCTAL, which uses one of the traditional octal values, to + an internal mode_t value. */ +static mode_t +octal_to_mode (unsigned int octal) +{ + /* Help the compiler optimize the usual case where mode_t uses + the traditional octal representation. */ + return ((S_ISUID == SUID && S_ISGID == SGID && S_ISVTX == SVTX + && S_IRUSR == RUSR && S_IWUSR == WUSR && S_IXUSR == XUSR + && S_IRGRP == RGRP && S_IWGRP == WGRP && S_IXGRP == XGRP + && S_IROTH == ROTH && S_IWOTH == WOTH && S_IXOTH == XOTH) + ? octal + : (mode_t) ((octal & SUID ? S_ISUID : 0) + | (octal & SGID ? S_ISGID : 0) + | (octal & SVTX ? S_ISVTX : 0) + | (octal & RUSR ? S_IRUSR : 0) + | (octal & WUSR ? S_IWUSR : 0) + | (octal & XUSR ? S_IXUSR : 0) + | (octal & RGRP ? S_IRGRP : 0) + | (octal & WGRP ? S_IWGRP : 0) + | (octal & XGRP ? S_IXGRP : 0) + | (octal & ROTH ? S_IROTH : 0) + | (octal & WOTH ? S_IWOTH : 0) + | (octal & XOTH ? S_IXOTH : 0))); +} + +/* Special operations flags. */ +enum + { + /* For the sentinel at the end of the mode changes array. */ + MODE_DONE, + + /* The typical case. */ + MODE_ORDINARY_CHANGE, + + /* In addition to the typical case, affect the execute bits if at + least one execute bit is set already, or if the file is a + directory. */ + MODE_X_IF_ANY_X, + + /* Instead of the typical case, copy some existing permissions for + u, g, or o onto the other two. Which of u, g, or o is copied + is determined by which bits are set in the 'value' field. */ + MODE_COPY_EXISTING + }; + +/* Description of a mode change. */ +struct mode_change +{ + char op; /* One of "=+-". */ + char flag; /* Special operations flag. */ + mode_t affected; /* Set for u, g, o, or a. */ + mode_t value; /* Bits to add/remove. */ + mode_t mentioned; /* Bits explicitly mentioned. */ +}; + +/* Return a mode_change array with the specified "=ddd"-style + mode change operation, where NEW_MODE is "ddd" and MENTIONED + contains the bits explicitly mentioned in the mode are MENTIONED. */ + +static struct mode_change * +make_node_op_equals (mode_t new_mode, mode_t mentioned) +{ + struct mode_change *p = xmalloc (2 * sizeof *p); + p->op = '='; + p->flag = MODE_ORDINARY_CHANGE; + p->affected = CHMOD_MODE_BITS; + p->value = new_mode; + p->mentioned = mentioned; + p[1].flag = MODE_DONE; + return p; +} + +/* Return a pointer to an array of file mode change operations created from + MODE_STRING, an ASCII string that contains either an octal number + specifying an absolute mode, or symbolic mode change operations with + the form: + [ugoa...][[+-=][rwxXstugo...]...][,...] + + Return NULL if 'mode_string' does not contain a valid + representation of file mode change operations. */ + +struct mode_change * +mode_compile (char const *mode_string) +{ + /* The array of mode-change directives to be returned. */ + struct mode_change *mc; + size_t used = 0; + + if ('0' <= *mode_string && *mode_string < '8') + { + unsigned int octal_mode = 0; + mode_t mode; + mode_t mentioned; + + do + { + octal_mode = 8 * octal_mode + *mode_string++ - '0'; + if (ALLM < octal_mode) + return NULL; + } + while ('0' <= *mode_string && *mode_string < '8'); + + if (*mode_string) + return NULL; + + mode = octal_to_mode (octal_mode); + mentioned = (mode & (S_ISUID | S_ISGID)) | S_ISVTX | S_IRWXUGO; + return make_node_op_equals (mode, mentioned); + } + + /* Allocate enough space to hold the result. */ + { + size_t needed = 1; + char const *p; + for (p = mode_string; *p; p++) + needed += (*p == '=' || *p == '+' || *p == '-'); + mc = xnmalloc (needed, sizeof *mc); + } + + /* One loop iteration for each '[ugoa]*([-+=]([rwxXst]*|[ugo]))+'. */ + for (;; mode_string++) + { + /* Which bits in the mode are operated on. */ + mode_t affected = 0; + + /* Turn on all the bits in 'affected' for each group given. */ + for (;; mode_string++) + switch (*mode_string) + { + default: + goto invalid; + case 'u': + affected |= S_ISUID | S_IRWXU; + break; + case 'g': + affected |= S_ISGID | S_IRWXG; + break; + case 'o': + affected |= S_ISVTX | S_IRWXO; + break; + case 'a': + affected |= CHMOD_MODE_BITS; + break; + case '=': case '+': case '-': + goto no_more_affected; + } + no_more_affected:; + + do + { + char op = *mode_string++; + mode_t value; + char flag = MODE_COPY_EXISTING; + struct mode_change *change; + + switch (*mode_string++) + { + case 'u': + /* Set the affected bits to the value of the "u" bits + on the same file. */ + value = S_IRWXU; + break; + case 'g': + /* Set the affected bits to the value of the "g" bits + on the same file. */ + value = S_IRWXG; + break; + case 'o': + /* Set the affected bits to the value of the "o" bits + on the same file. */ + value = S_IRWXO; + break; + + default: + value = 0; + flag = MODE_ORDINARY_CHANGE; + + for (mode_string--;; mode_string++) + switch (*mode_string) + { + case 'r': + value |= S_IRUSR | S_IRGRP | S_IROTH; + break; + case 'w': + value |= S_IWUSR | S_IWGRP | S_IWOTH; + break; + case 'x': + value |= S_IXUSR | S_IXGRP | S_IXOTH; + break; + case 'X': + flag = MODE_X_IF_ANY_X; + break; + case 's': + /* Set the setuid/gid bits if 'u' or 'g' is selected. */ + value |= S_ISUID | S_ISGID; + break; + case 't': + /* Set the "save text image" bit if 'o' is selected. */ + value |= S_ISVTX; + break; + default: + goto no_more_values; + } + no_more_values:; + } + + change = &mc[used++]; + change->op = op; + change->flag = flag; + change->affected = affected; + change->value = value; + change->mentioned = (affected ? affected & value : value); + } + while (*mode_string == '=' || *mode_string == '+' + || *mode_string == '-'); + + if (*mode_string != ',') + break; + } + + if (*mode_string == 0) + { + mc[used].flag = MODE_DONE; + return mc; + } + +invalid: + free (mc); + return NULL; +} + +/* Return a file mode change operation that sets permissions to match those + of REF_FILE. Return NULL (setting errno) if REF_FILE can't be accessed. */ + +struct mode_change * +mode_create_from_ref (const char *ref_file) +{ + struct stat ref_stats; + + if (stat (ref_file, &ref_stats) != 0) + return NULL; + return make_node_op_equals (ref_stats.st_mode, CHMOD_MODE_BITS); +} + +/* Return the file mode bits of OLDMODE (which is the mode of a + directory if DIR), assuming the umask is UMASK_VALUE, adjusted as + indicated by the list of change operations CHANGES. If DIR, the + type 'X' change affects the returned value even if no execute bits + were set in OLDMODE, and set user and group ID bits are preserved + unless CHANGES mentioned them. If PMODE_BITS is not null, store into + *PMODE_BITS a mask denoting file mode bits that are affected by + CHANGES. + + The returned value and *PMODE_BITS contain only file mode bits. + For example, they have the S_IFMT bits cleared on a standard + Unix-like host. */ + +mode_t +mode_adjust (mode_t oldmode, bool dir, mode_t umask_value, + struct mode_change const *changes, mode_t *pmode_bits) +{ + /* The adjusted mode. */ + mode_t newmode = oldmode & CHMOD_MODE_BITS; + + /* File mode bits that CHANGES cares about. */ + mode_t mode_bits = 0; + + for (; changes->flag != MODE_DONE; changes++) + { + mode_t affected = changes->affected; + mode_t omit_change = + (dir ? S_ISUID | S_ISGID : 0) & ~ changes->mentioned; + mode_t value = changes->value; + + switch (changes->flag) + { + case MODE_ORDINARY_CHANGE: + break; + + case MODE_COPY_EXISTING: + /* Isolate in 'value' the bits in 'newmode' to copy. */ + value &= newmode; + + /* Copy the isolated bits to the other two parts. */ + value |= ((value & (S_IRUSR | S_IRGRP | S_IROTH) + ? S_IRUSR | S_IRGRP | S_IROTH : 0) + | (value & (S_IWUSR | S_IWGRP | S_IWOTH) + ? S_IWUSR | S_IWGRP | S_IWOTH : 0) + | (value & (S_IXUSR | S_IXGRP | S_IXOTH) + ? S_IXUSR | S_IXGRP | S_IXOTH : 0)); + break; + + case MODE_X_IF_ANY_X: + /* Affect the execute bits if execute bits are already set + or if the file is a directory. */ + if ((newmode & (S_IXUSR | S_IXGRP | S_IXOTH)) | dir) + value |= S_IXUSR | S_IXGRP | S_IXOTH; + break; + } + + /* If WHO was specified, limit the change to the affected bits. + Otherwise, apply the umask. Either way, omit changes as + requested. */ + value &= (affected ? affected : ~umask_value) & ~ omit_change; + + switch (changes->op) + { + case '=': + /* If WHO was specified, preserve the previous values of + bits that are not affected by this change operation. + Otherwise, clear all the bits. */ + { + mode_t preserved = (affected ? ~affected : 0) | omit_change; + mode_bits |= CHMOD_MODE_BITS & ~preserved; + newmode = (newmode & preserved) | value; + break; + } + + case '+': + mode_bits |= value; + newmode |= value; + break; + + case '-': + mode_bits |= value; + newmode &= ~value; + break; + } + } + + if (pmode_bits) + *pmode_bits = mode_bits; + return newmode; +} diff --git a/gnu/modechange.h b/gnu/modechange.h new file mode 100644 index 00000000..5f0c04e9 --- /dev/null +++ b/gnu/modechange.h @@ -0,0 +1,32 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* modechange.h -- definitions for file mode manipulation + + Copyright (C) 1989-1990, 1997, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#if ! defined MODECHANGE_H_ +# define MODECHANGE_H_ + +# include <stdbool.h> +# include <sys/types.h> + +struct mode_change *mode_compile (const char *); +struct mode_change *mode_create_from_ref (const char *); +mode_t mode_adjust (mode_t, bool, mode_t, struct mode_change const *, + mode_t *); + +#endif diff --git a/gnu/msvc-inval.c b/gnu/msvc-inval.c new file mode 100644 index 00000000..6dd1f995 --- /dev/null +++ b/gnu/msvc-inval.c @@ -0,0 +1,132 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Invalid parameter handler for MSVC runtime libraries. + Copyright (C) 2011-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* 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 <stdlib.h> + +# 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 <windows.h> + +# 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/gnu/msvc-inval.h b/gnu/msvc-inval.h new file mode 100644 index 00000000..70037196 --- /dev/null +++ b/gnu/msvc-inval.h @@ -0,0 +1,225 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Invalid parameter handler for MSVC runtime libraries. + Copyright (C) 2011-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#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 + { + <Code that can trigger an invalid parameter notification + but does not do 'return', 'break', 'continue', nor 'goto'.> + } + CATCH_MSVC_INVAL + { + <Code that handles an invalid parameter notification + but does not do 'return', 'break', 'continue', nor 'goto'.> + } + 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 <excpt.h> + +/* Gnulib can define its own status codes, as described in the page + "Raising Software Exceptions" on microsoft.com + <http://msdn.microsoft.com/en-us/library/het71c37.aspx>. + 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 + <http://msdn.microsoft.com/en-us/library/s58ftw19.aspx>. + 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 <setjmp.h> + +# 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/gnu/msvc-nothrow.c b/gnu/msvc-nothrow.c new file mode 100644 index 00000000..2a4fcc28 --- /dev/null +++ b/gnu/msvc-nothrow.c @@ -0,0 +1,52 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Wrappers that don't throw invalid parameter notifications + with MSVC runtime libraries. + Copyright (C) 2011-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include "msvc-nothrow.h" + +/* Get declarations of the native Windows API functions. */ +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include "msvc-inval.h" + +#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/gnu/msvc-nothrow.h b/gnu/msvc-nothrow.h new file mode 100644 index 00000000..55150d29 --- /dev/null +++ b/gnu/msvc-nothrow.h @@ -0,0 +1,46 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Wrappers that don't throw invalid parameter notifications + with MSVC runtime libraries. + Copyright (C) 2011-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#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 __WIN32__) && ! defined __CYGWIN__ + +/* Get original declaration of _get_osfhandle. */ +# include <io.h> + +# 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/gnu/nl_langinfo.c b/gnu/nl_langinfo.c new file mode 100644 index 00000000..7dd9a6d5 --- /dev/null +++ b/gnu/nl_langinfo.c @@ -0,0 +1,273 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* nl_langinfo() replacement: query locale dependent information. + + Copyright (C) 2007-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <langinfo.h> + +#if REPLACE_NL_LANGINFO + +/* Override nl_langinfo with support for added nl_item values. */ + +# include <locale.h> +# include <string.h> + +# undef nl_langinfo + +char * +rpl_nl_langinfo (nl_item item) +{ + switch (item) + { +# if GNULIB_defined_CODESET + case CODESET: + { + const char *locale; + static char buf[2 + 10 + 1]; + + locale = setlocale (LC_CTYPE, NULL); + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return + it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + } + return ""; + } +# endif +# if GNULIB_defined_T_FMT_AMPM + case T_FMT_AMPM: + return "%I:%M:%S %p"; +# 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 ""; + 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 "\0\0\0\0\0\0\0\0\0\0"; +# endif +# if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS + case YESEXPR: + return "^[yY]"; + case NOEXPR: + return "^[nN]"; +# endif + default: + break; + } + return nl_langinfo (item); +} + +#else + +/* Provide nl_langinfo from scratch. */ + +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +/* Native Windows platforms. */ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include <windows.h> + +# include <stdio.h> + +# else + +/* An old Unix platform without locales, such as Linux libc5 or BeOS. */ + +# endif + +# include <locale.h> + +char * +nl_langinfo (nl_item item) +{ + switch (item) + { + /* nl_langinfo items of the LC_CTYPE category */ + case CODESET: +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + { + static char buf[2 + 10 + 1]; + + /* The Windows API has a function returning the locale's codepage as + a number. */ + sprintf (buf, "CP%u", GetACP ()); + return buf; + } +# elif defined __BEOS__ + return "UTF-8"; +# else + return "ISO-8859-1"; +# endif + /* nl_langinfo items of the LC_NUMERIC category */ + case RADIXCHAR: + return localeconv () ->decimal_point; + case THOUSEP: + return localeconv () ->thousands_sep; + /* nl_langinfo items of the LC_TIME category. + TODO: Really use the locale. */ + case D_T_FMT: + case ERA_D_T_FMT: + return "%a %b %e %H:%M:%S %Y"; + case D_FMT: + case ERA_D_FMT: + return "%m/%d/%y"; + case T_FMT: + case ERA_T_FMT: + return "%H:%M:%S"; + case T_FMT_AMPM: + return "%I:%M:%S %p"; + case AM_STR: + return "AM"; + case PM_STR: + return "PM"; + case DAY_1: + return "Sunday"; + case DAY_2: + return "Monday"; + case DAY_3: + return "Tuesday"; + case DAY_4: + return "Wednesday"; + case DAY_5: + return "Thursday"; + case DAY_6: + return "Friday"; + case DAY_7: + return "Saturday"; + case ABDAY_1: + return "Sun"; + case ABDAY_2: + return "Mon"; + case ABDAY_3: + return "Tue"; + case ABDAY_4: + return "Wed"; + case ABDAY_5: + return "Thu"; + case ABDAY_6: + return "Fri"; + case ABDAY_7: + return "Sat"; + case MON_1: + return "January"; + case MON_2: + return "February"; + case MON_3: + return "March"; + case MON_4: + return "April"; + case MON_5: + return "May"; + case MON_6: + return "June"; + case MON_7: + return "July"; + case MON_8: + return "August"; + case MON_9: + return "September"; + case MON_10: + return "October"; + case MON_11: + return "November"; + case MON_12: + return "December"; + case ABMON_1: + return "Jan"; + case ABMON_2: + return "Feb"; + case ABMON_3: + return "Mar"; + case ABMON_4: + return "Apr"; + case ABMON_5: + return "May"; + case ABMON_6: + return "Jun"; + case ABMON_7: + return "Jul"; + case ABMON_8: + return "Aug"; + case ABMON_9: + return "Sep"; + case ABMON_10: + return "Oct"; + case ABMON_11: + return "Nov"; + case ABMON_12: + return "Dec"; + case ERA: + return ""; + case ALT_DIGITS: + return "\0\0\0\0\0\0\0\0\0\0"; + /* nl_langinfo items of the LC_MONETARY category + TODO: Really use the locale. */ + case CRNCYSTR: + return "-"; + /* nl_langinfo items of the LC_MESSAGES category + TODO: Really use the locale. */ + case YESEXPR: + return "^[yY]"; + case NOEXPR: + return "^[nN]"; + default: + return ""; + } +} + +#endif diff --git a/gnu/obstack.c b/gnu/obstack.c new file mode 100644 index 00000000..95d88fb4 --- /dev/null +++ b/gnu/obstack.c @@ -0,0 +1,422 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* obstack.c - subroutines used implicitly by object stack macros + + Copyright (C) 1988-1994, 1996-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifdef _LIBC +# include <obstack.h> +# include <shlib-compat.h> +#else +# include <config.h> +# include "obstack.h" +#endif + +/* NOTE BEFORE MODIFYING THIS FILE: This version number must be + incremented whenever callers compiled using an old obstack.h can no + longer properly call the functions in this obstack.c. */ +#define OBSTACK_INTERFACE_VERSION 1 + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself, and the installed library + supports the same library interface we do. This code is part of the GNU + C Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand 'configure --with-gnu-libc' and omit the object + files, it is simpler to just do this in the source for each such file. */ + +#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */ +#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 +# include <gnu-versions.h> +# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#include <stddef.h> + +#ifndef ELIDE_CODE + +# include <stdint.h> + +/* Determine default alignment. */ +union fooround +{ + uintmax_t i; + long double d; + void *p; +}; +struct fooalign +{ + char c; + union fooround u; +}; +/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. + But in fact it might be less smart and round addresses to as much as + DEFAULT_ROUNDING. So we prepare for it to do that. */ +enum + { + DEFAULT_ALIGNMENT = offsetof (struct fooalign, u), + DEFAULT_ROUNDING = sizeof (union fooround) + }; + +/* When we copy a long block of data, this is the unit to do it with. + On some machines, copying successive ints does not work; + in such a case, redefine COPYING_UNIT to 'long' (if that works) + or 'char' as a last resort. */ +# ifndef COPYING_UNIT +# define COPYING_UNIT int +# endif + + +/* The functions allocating more room by calling 'obstack_chunk_alloc' + jump to the handler pointed to by 'obstack_alloc_failed_handler'. + This can be set to a user defined function which should either + abort gracefully or use longjump - but shouldn't return. This + variable by default points to the internal function + 'print_and_abort'. */ +static _Noreturn void print_and_abort (void); +void (*obstack_alloc_failed_handler) (void) = print_and_abort; + +/* Exit value used when 'print_and_abort' is used. */ +# include <stdlib.h> +# ifdef _LIBC +int obstack_exit_failure = EXIT_FAILURE; +# else +# include "exitfail.h" +# define obstack_exit_failure exit_failure +# endif + +# ifdef _LIBC +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) +/* A looong time ago (before 1994, anyway; we're not sure) this global variable + was used by non-GNU-C macros to avoid multiple evaluation. The GNU C + library still exports it because somebody might use it. */ +struct obstack *_obstack_compat; +compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0); +# endif +# endif + +/* Define a macro that either calls functions with the traditional malloc/free + calling interface, or calls functions with the mmalloc/mfree interface + (that adds an extra first argument), based on the state of use_extra_arg. + For free, do not use ?:, since some compilers, like the MIPS compilers, + do not allow (expr) ? void : void. */ + +# define CALL_CHUNKFUN(h, size) \ + (((h) -> use_extra_arg) \ + ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ + : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size))) + +# define CALL_FREEFUN(h, old_chunk) \ + do { \ + if ((h) -> use_extra_arg) \ + (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ + else \ + (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \ + } while (0) + + +/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). + Objects start on multiples of ALIGNMENT (0 means use default). + CHUNKFUN is the function to use to allocate chunks, + and FREEFUN the function to free them. + + Return nonzero if successful, calls obstack_alloc_failed_handler if + allocation fails. */ + +int +_obstack_begin (struct obstack *h, + int size, int alignment, + void *(*chunkfun) (long), + void (*freefun) (void *)) +{ + register struct _obstack_chunk *chunk; /* points to new chunk */ + + if (alignment == 0) + alignment = DEFAULT_ALIGNMENT; + if (size == 0) + /* Default size is what GNU malloc can fit in a 4096-byte block. */ + { + /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. + Use the values for range checking, because if range checking is off, + the extra bytes won't be missed terribly, but if range checking is on + and we used a larger request, a whole extra 4096 bytes would be + allocated. + + These number are irrelevant to the new GNU malloc. I suspect it is + less sensitive to the size of the request. */ + int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) + + 4 + DEFAULT_ROUNDING - 1) + & ~(DEFAULT_ROUNDING - 1)); + size = 4096 - extra; + } + + h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun; + h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; + h->chunk_size = size; + h->alignment_mask = alignment - 1; + h->use_extra_arg = 0; + + chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); + if (!chunk) + (*obstack_alloc_failed_handler) (); + h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, + alignment - 1); + h->chunk_limit = chunk->limit + = (char *) chunk + h->chunk_size; + chunk->prev = 0; + /* The initial chunk now contains no empty object. */ + h->maybe_empty_object = 0; + h->alloc_failed = 0; + return 1; +} + +int +_obstack_begin_1 (struct obstack *h, int size, int alignment, + void *(*chunkfun) (void *, long), + void (*freefun) (void *, void *), + void *arg) +{ + register struct _obstack_chunk *chunk; /* points to new chunk */ + + if (alignment == 0) + alignment = DEFAULT_ALIGNMENT; + if (size == 0) + /* Default size is what GNU malloc can fit in a 4096-byte block. */ + { + /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. + Use the values for range checking, because if range checking is off, + the extra bytes won't be missed terribly, but if range checking is on + and we used a larger request, a whole extra 4096 bytes would be + allocated. + + These number are irrelevant to the new GNU malloc. I suspect it is + less sensitive to the size of the request. */ + int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) + + 4 + DEFAULT_ROUNDING - 1) + & ~(DEFAULT_ROUNDING - 1)); + size = 4096 - extra; + } + + h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun; + h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; + h->chunk_size = size; + h->alignment_mask = alignment - 1; + h->extra_arg = arg; + h->use_extra_arg = 1; + + chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); + if (!chunk) + (*obstack_alloc_failed_handler) (); + h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, + alignment - 1); + h->chunk_limit = chunk->limit + = (char *) chunk + h->chunk_size; + chunk->prev = 0; + /* The initial chunk now contains no empty object. */ + h->maybe_empty_object = 0; + h->alloc_failed = 0; + return 1; +} + +/* Allocate a new current chunk for the obstack *H + on the assumption that LENGTH bytes need to be added + to the current object, or a new object of length LENGTH allocated. + Copies any partial object from the end of the old chunk + to the beginning of the new one. */ + +void +_obstack_newchunk (struct obstack *h, int length) +{ + register struct _obstack_chunk *old_chunk = h->chunk; + register struct _obstack_chunk *new_chunk; + register long new_size; + register long obj_size = h->next_free - h->object_base; + register long i; + long already; + char *object_base; + + /* Compute size for new chunk. */ + new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100; + if (new_size < h->chunk_size) + new_size = h->chunk_size; + + /* Allocate and initialize the new chunk. */ + new_chunk = CALL_CHUNKFUN (h, new_size); + if (!new_chunk) + (*obstack_alloc_failed_handler) (); + h->chunk = new_chunk; + new_chunk->prev = old_chunk; + new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; + + /* Compute an aligned object_base in the new chunk */ + object_base = + __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask); + + /* Move the existing object to the new chunk. + Word at a time is fast and is safe if the object + is sufficiently aligned. */ + if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) + { + for (i = obj_size / sizeof (COPYING_UNIT) - 1; + i >= 0; i--) + ((COPYING_UNIT *)object_base)[i] + = ((COPYING_UNIT *)h->object_base)[i]; + /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, + but that can cross a page boundary on a machine + which does not do strict alignment for COPYING_UNITS. */ + already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT); + } + else + already = 0; + /* Copy remaining bytes one by one. */ + for (i = already; i < obj_size; i++) + object_base[i] = h->object_base[i]; + + /* If the object just copied was the only data in OLD_CHUNK, + free that chunk and remove it from the chain. + But not if that chunk might contain an empty object. */ + if (! h->maybe_empty_object + && (h->object_base + == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents, + h->alignment_mask))) + { + new_chunk->prev = old_chunk->prev; + CALL_FREEFUN (h, old_chunk); + } + + h->object_base = object_base; + h->next_free = h->object_base + obj_size; + /* The new chunk certainly contains no empty object yet. */ + h->maybe_empty_object = 0; +} +# ifdef _LIBC +libc_hidden_def (_obstack_newchunk) +# endif + +/* Return nonzero if object OBJ has been allocated from obstack H. + This is here for debugging. + If you use it in a program, you are probably losing. */ + +/* Suppress -Wmissing-prototypes warning. We don't want to declare this in + obstack.h because it is just for debugging. */ +int _obstack_allocated_p (struct obstack *h, void *obj); + +int +_obstack_allocated_p (struct obstack *h, void *obj) +{ + register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ + register struct _obstack_chunk *plp; /* point to previous chunk if any */ + + lp = (h)->chunk; + /* We use >= rather than > since the object cannot be exactly at + the beginning of the chunk but might be an empty object exactly + at the end of an adjacent chunk. */ + while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) + { + plp = lp->prev; + lp = plp; + } + return lp != 0; +} + +/* Free objects in obstack H, including OBJ and everything allocate + more recently than OBJ. If OBJ is zero, free everything in H. */ + +# undef obstack_free + +void +__obstack_free (struct obstack *h, void *obj) +{ + register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ + register struct _obstack_chunk *plp; /* point to previous chunk if any */ + + lp = h->chunk; + /* We use >= because there cannot be an object at the beginning of a chunk. + But there can be an empty object at that address + at the end of another chunk. */ + while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) + { + plp = lp->prev; + CALL_FREEFUN (h, lp); + lp = plp; + /* If we switch chunks, we can't tell whether the new current + chunk contains an empty object, so assume that it may. */ + h->maybe_empty_object = 1; + } + if (lp) + { + h->object_base = h->next_free = (char *) (obj); + h->chunk_limit = lp->limit; + h->chunk = lp; + } + else if (obj != 0) + /* obj is not in any of the chunks! */ + abort (); +} + +# ifdef _LIBC +/* Older versions of libc used a function _obstack_free intended to be + called by non-GCC compilers. */ +strong_alias (obstack_free, _obstack_free) +# endif + +int +_obstack_memory_used (struct obstack *h) +{ + register struct _obstack_chunk* lp; + register int nbytes = 0; + + for (lp = h->chunk; lp != 0; lp = lp->prev) + { + nbytes += lp->limit - (char *) lp; + } + return nbytes; +} + +/* Define the error handler. */ +# ifdef _LIBC +# include <libintl.h> +# else +# include "gettext.h" +# endif +# ifndef _ +# define _(msgid) gettext (msgid) +# endif + +# ifdef _LIBC +# include <libio/iolibio.h> +# endif + +static _Noreturn void +print_and_abort (void) +{ + /* Don't change any of these strings. Yes, it would be possible to add + the newline to the string and use fputs or so. But this must not + happen because the "memory exhausted" message appears in other places + like this and the translation should be reused instead of creating + a very similar string which requires a separate translation. */ +# ifdef _LIBC + (void) __fxprintf (NULL, "%s\n", _("memory exhausted")); +# else + fprintf (stderr, "%s\n", _("memory exhausted")); +# endif + exit (obstack_exit_failure); +} + +#endif /* !ELIDE_CODE */ diff --git a/gnu/obstack.h b/gnu/obstack.h new file mode 100644 index 00000000..40938857 --- /dev/null +++ b/gnu/obstack.h @@ -0,0 +1,514 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* obstack.h - object stack macros + Copyright (C) 1988-1994, 1996-1999, 2003-2006, 2009-2012 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +/* Summary: + +All the apparent functions defined here are macros. The idea +is that you would use these pre-tested macros to solve a +very specific set of problems, and they would run fast. +Caution: no side-effects in arguments please!! They may be +evaluated MANY times!! + +These macros operate a stack of objects. Each object starts life +small, and may grow to maturity. (Consider building a word syllable +by syllable.) An object can move while it is growing. Once it has +been "finished" it never changes address again. So the "top of the +stack" is typically an immature growing object, while the rest of the +stack is of mature, fixed size and fixed address objects. + +These routines grab large chunks of memory, using a function you +supply, called 'obstack_chunk_alloc'. On occasion, they free chunks, +by calling 'obstack_chunk_free'. You must define them and declare +them before using any obstack macros. + +Each independent stack is represented by a 'struct obstack'. +Each of the obstack macros expects a pointer to such a structure +as the first argument. + +One motivation for this package is the problem of growing char strings +in symbol tables. Unless you are "fascist pig with a read-only mind" +--Gosper's immortal quote from HAKMEM item 154, out of context--you +would not like to put any arbitrary upper limit on the length of your +symbols. + +In practice this often means you will build many short symbols and a +few long symbols. At the time you are reading a symbol you don't know +how long it is. One traditional method is to read a symbol into a +buffer, realloc()ating the buffer every time you try to read a symbol +that is longer than the buffer. This is beaut, but you still will +want to copy the symbol from the buffer to a more permanent +symbol-table entry say about half the time. + +With obstacks, you can work differently. Use one obstack for all symbol +names. As you read a symbol, grow the name in the obstack gradually. +When the name is complete, finalize it. Then, if the symbol exists already, +free the newly read name. + +The way we do this is to take a large chunk, allocating memory from +low addresses. When you want to build a symbol in the chunk you just +add chars above the current "high water mark" in the chunk. When you +have finished adding chars, because you got to the end of the symbol, +you know how long the chars are, and you can create a new object. +Mostly the chars will not burst over the highest address of the chunk, +because you would typically expect a chunk to be (say) 100 times as +long as an average object. + +In case that isn't clear, when we have enough chars to make up +the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) +so we just point to it where it lies. No moving of chars is +needed and this is the second win: potentially long strings need +never be explicitly shuffled. Once an object is formed, it does not +change its address during its lifetime. + +When the chars burst over a chunk boundary, we allocate a larger +chunk, and then copy the partly formed object from the end of the old +chunk to the beginning of the new larger chunk. We then carry on +accreting characters to the end of the object as we normally would. + +A special macro is provided to add a single char at a time to a +growing object. This allows the use of register variables, which +break the ordinary 'growth' macro. + +Summary: + We allocate large chunks. + We carve out one object at a time from the current chunk. + Once carved, an object never moves. + We are free to append data of any size to the currently + growing object. + Exactly one object is growing in an obstack at any one time. + You can run one obstack per control block. + You may have as many control blocks as you dare. + Because of the way we do it, you can "unwind" an obstack + back to a previous state. (You may remove objects much + as you would with a stack.) +*/ + + +/* Don't do the contents of this file more than once. */ + +#ifndef _OBSTACK_H +#define _OBSTACK_H 1 + +/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is + defined, as with GNU C, use that; that way we don't pollute the + namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h> + and use ptrdiff_t. */ + +#ifdef __PTRDIFF_TYPE__ +# define PTR_INT_TYPE __PTRDIFF_TYPE__ +#else +# include <stddef.h> +# define PTR_INT_TYPE ptrdiff_t +#endif + +/* If B is the base of an object addressed by P, return the result of + aligning P to the next multiple of A + 1. B and P must be of type + char *. A + 1 must be a power of 2. */ + +#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A))) + +/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case + where pointers can be converted to integers, aligned as integers, + and converted back again. If PTR_INT_TYPE is narrower than a + pointer (e.g., the AS/400), play it safe and compute the alignment + relative to B. Otherwise, use the faster strategy of computing the + alignment relative to 0. */ + +#define __PTR_ALIGN(B, P, A) \ + __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \ + P, A) + +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct _obstack_chunk /* Lives at front of each chunk. */ +{ + char *limit; /* 1 past end of this chunk */ + struct _obstack_chunk *prev; /* address of prior chunk or NULL */ + char contents[4]; /* objects begin here */ +}; + +struct obstack /* control current object in current chunk */ +{ + long chunk_size; /* preferred size to allocate chunks in */ + struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ + char *object_base; /* address of object we are building */ + char *next_free; /* where to add next char to current object */ + char *chunk_limit; /* address of char after current chunk */ + union + { + PTR_INT_TYPE tempint; + void *tempptr; + } temp; /* Temporary for some macros. */ + int alignment_mask; /* Mask of alignment for each object. */ + /* These prototypes vary based on 'use_extra_arg', and we use + casts to the prototypeless function type in all assignments, + but having prototypes here quiets -Wstrict-prototypes. */ + struct _obstack_chunk *(*chunkfun) (void *, long); + void (*freefun) (void *, struct _obstack_chunk *); + void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ + unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ + unsigned maybe_empty_object:1;/* There is a possibility that the current + chunk contains a zero-length object. This + prevents freeing the chunk if we allocate + a bigger chunk to replace it. */ + unsigned alloc_failed:1; /* No longer used, as we now call the failed + handler on error, but retained for binary + compatibility. */ +}; + +/* Declare the external functions we use; they are in obstack.c. */ + +extern void _obstack_newchunk (struct obstack *, int); +extern int _obstack_begin (struct obstack *, int, int, + void *(*) (long), void (*) (void *)); +extern int _obstack_begin_1 (struct obstack *, int, int, + void *(*) (void *, long), + void (*) (void *, void *), void *); +extern int _obstack_memory_used (struct obstack *); + +/* The default name of the function for freeing a chunk is 'obstack_free', + but gnulib users can override this by defining '__obstack_free'. */ +#ifndef __obstack_free +# define __obstack_free obstack_free +#endif +extern void __obstack_free (struct obstack *obstack, void *block); + + +/* Error handler called when 'obstack_chunk_alloc' failed to allocate + more memory. This can be set to a user defined function which + should either abort gracefully or use longjump - but shouldn't + return. The default action is to print a message and abort. */ +extern void (*obstack_alloc_failed_handler) (void); + +/* Exit value used when 'print_and_abort' is used. */ +extern int obstack_exit_failure; + +/* Pointer to beginning of object being allocated or to be allocated next. + Note that this might not be the final address of the object + because a new chunk might be needed to hold the final size. */ + +#define obstack_base(h) ((void *) (h)->object_base) + +/* Size for allocating ordinary chunks. */ + +#define obstack_chunk_size(h) ((h)->chunk_size) + +/* Pointer to next byte not yet allocated in current chunk. */ + +#define obstack_next_free(h) ((h)->next_free) + +/* Mask specifying low bits that should be clear in address of an object. */ + +#define obstack_alignment_mask(h) ((h)->alignment_mask) + +/* To prevent prototype warnings provide complete argument list. */ +#define obstack_init(h) \ + _obstack_begin ((h), 0, 0, \ + (void *(*) (long)) obstack_chunk_alloc, \ + (void (*) (void *)) obstack_chunk_free) + +#define obstack_begin(h, size) \ + _obstack_begin ((h), (size), 0, \ + (void *(*) (long)) obstack_chunk_alloc, \ + (void (*) (void *)) obstack_chunk_free) + +#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ + _obstack_begin ((h), (size), (alignment), \ + (void *(*) (long)) (chunkfun), \ + (void (*) (void *)) (freefun)) + +#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ + _obstack_begin_1 ((h), (size), (alignment), \ + (void *(*) (void *, long)) (chunkfun), \ + (void (*) (void *, void *)) (freefun), (arg)) + +#define obstack_chunkfun(h, newchunkfun) \ + ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) + +#define obstack_freefun(h, newfreefun) \ + ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) + +#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) + +#define obstack_blank_fast(h,n) ((h)->next_free += (n)) + +#define obstack_memory_used(h) _obstack_memory_used (h) + +#if defined __GNUC__ && defined __STDC__ && __STDC__ +/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and + does not implement __extension__. But that compiler doesn't define + __GNUC_MINOR__. */ +# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) +# define __extension__ +# endif + +/* For GNU C, if not -traditional, + we can define these macros to compute all args only once + without using a global variable. + Also, we can avoid using the 'temp' slot, to make faster code. */ + +# define obstack_object_size(OBSTACK) \ + __extension__ \ + ({ struct obstack const *__o = (OBSTACK); \ + (unsigned) (__o->next_free - __o->object_base); }) + +# define obstack_room(OBSTACK) \ + __extension__ \ + ({ struct obstack const *__o = (OBSTACK); \ + (unsigned) (__o->chunk_limit - __o->next_free); }) + +# define obstack_make_room(OBSTACK,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->chunk_limit - __o->next_free < __len) \ + _obstack_newchunk (__o, __len); \ + (void) 0; }) + +# define obstack_empty_p(OBSTACK) \ + __extension__ \ + ({ struct obstack const *__o = (OBSTACK); \ + (__o->chunk->prev == 0 \ + && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \ + __o->chunk->contents, \ + __o->alignment_mask)); }) + +# define obstack_grow(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->next_free + __len > __o->chunk_limit) \ + _obstack_newchunk (__o, __len); \ + memcpy (__o->next_free, where, __len); \ + __o->next_free += __len; \ + (void) 0; }) + +# define obstack_grow0(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->next_free + __len + 1 > __o->chunk_limit) \ + _obstack_newchunk (__o, __len + 1); \ + memcpy (__o->next_free, where, __len); \ + __o->next_free += __len; \ + *(__o->next_free)++ = 0; \ + (void) 0; }) + +# define obstack_1grow(OBSTACK,datum) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + 1 > __o->chunk_limit) \ + _obstack_newchunk (__o, 1); \ + obstack_1grow_fast (__o, datum); \ + (void) 0; }) + +/* These assume that the obstack alignment is good enough for pointers + or ints, and that the data added so far to the current object + shares that much alignment. */ + +# define obstack_ptr_grow(OBSTACK,datum) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ + _obstack_newchunk (__o, sizeof (void *)); \ + obstack_ptr_grow_fast (__o, datum); }) \ + +# define obstack_int_grow(OBSTACK,datum) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + sizeof (int) > __o->chunk_limit) \ + _obstack_newchunk (__o, sizeof (int)); \ + obstack_int_grow_fast (__o, datum); }) + +# define obstack_ptr_grow_fast(OBSTACK,aptr) \ +__extension__ \ +({ struct obstack *__o1 = (OBSTACK); \ + *(const void **) __o1->next_free = (aptr); \ + __o1->next_free += sizeof (const void *); \ + (void) 0; }) + +# define obstack_int_grow_fast(OBSTACK,aint) \ +__extension__ \ +({ struct obstack *__o1 = (OBSTACK); \ + *(int *) __o1->next_free = (aint); \ + __o1->next_free += sizeof (int); \ + (void) 0; }) + +# define obstack_blank(OBSTACK,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->chunk_limit - __o->next_free < __len) \ + _obstack_newchunk (__o, __len); \ + obstack_blank_fast (__o, __len); \ + (void) 0; }) + +# define obstack_alloc(OBSTACK,length) \ +__extension__ \ +({ struct obstack *__h = (OBSTACK); \ + obstack_blank (__h, (length)); \ + obstack_finish (__h); }) + +# define obstack_copy(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__h = (OBSTACK); \ + obstack_grow (__h, (where), (length)); \ + obstack_finish (__h); }) + +# define obstack_copy0(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__h = (OBSTACK); \ + obstack_grow0 (__h, (where), (length)); \ + obstack_finish (__h); }) + +/* The local variable is named __o1 to avoid a name conflict + when obstack_blank is called. */ +# define obstack_finish(OBSTACK) \ +__extension__ \ +({ struct obstack *__o1 = (OBSTACK); \ + void *__value = (void *) __o1->object_base; \ + if (__o1->next_free == __value) \ + __o1->maybe_empty_object = 1; \ + __o1->next_free \ + = __PTR_ALIGN (__o1->object_base, __o1->next_free, \ + __o1->alignment_mask); \ + if (__o1->next_free - (char *)__o1->chunk \ + > __o1->chunk_limit - (char *)__o1->chunk) \ + __o1->next_free = __o1->chunk_limit; \ + __o1->object_base = __o1->next_free; \ + __value; }) + +# define obstack_free(OBSTACK, OBJ) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + void *__obj = (OBJ); \ + if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ + __o->next_free = __o->object_base = (char *)__obj; \ + else (__obstack_free) (__o, __obj); }) + +#else /* not __GNUC__ or not __STDC__ */ + +# define obstack_object_size(h) \ + (unsigned) ((h)->next_free - (h)->object_base) + +# define obstack_room(h) \ + (unsigned) ((h)->chunk_limit - (h)->next_free) + +# define obstack_empty_p(h) \ + ((h)->chunk->prev == 0 \ + && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \ + (h)->chunk->contents, \ + (h)->alignment_mask)) + +/* Note that the call to _obstack_newchunk is enclosed in (..., 0) + so that we can avoid having void expressions + in the arms of the conditional expression. + Casting the third operand to void was tried before, + but some compilers won't accept it. */ + +# define obstack_make_room(h,length) \ +( (h)->temp.tempint = (length), \ + (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0)) + +# define obstack_grow(h,where,length) \ +( (h)->temp.tempint = (length), \ + (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ + memcpy ((h)->next_free, where, (h)->temp.tempint), \ + (h)->next_free += (h)->temp.tempint) + +# define obstack_grow0(h,where,length) \ +( (h)->temp.tempint = (length), \ + (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \ + memcpy ((h)->next_free, where, (h)->temp.tempint), \ + (h)->next_free += (h)->temp.tempint, \ + *((h)->next_free)++ = 0) + +# define obstack_1grow(h,datum) \ +( (((h)->next_free + 1 > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), 1), 0) : 0), \ + obstack_1grow_fast (h, datum)) + +# define obstack_ptr_grow(h,datum) \ +( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ + obstack_ptr_grow_fast (h, datum)) + +# define obstack_int_grow(h,datum) \ +( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ + obstack_int_grow_fast (h, datum)) + +# define obstack_ptr_grow_fast(h,aptr) \ + (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) + +# define obstack_int_grow_fast(h,aint) \ + (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint)) + +# define obstack_blank(h,length) \ +( (h)->temp.tempint = (length), \ + (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \ + ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ + obstack_blank_fast (h, (h)->temp.tempint)) + +# define obstack_alloc(h,length) \ + (obstack_blank ((h), (length)), obstack_finish ((h))) + +# define obstack_copy(h,where,length) \ + (obstack_grow ((h), (where), (length)), obstack_finish ((h))) + +# define obstack_copy0(h,where,length) \ + (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) + +# define obstack_finish(h) \ +( ((h)->next_free == (h)->object_base \ + ? (((h)->maybe_empty_object = 1), 0) \ + : 0), \ + (h)->temp.tempptr = (h)->object_base, \ + (h)->next_free \ + = __PTR_ALIGN ((h)->object_base, (h)->next_free, \ + (h)->alignment_mask), \ + (((h)->next_free - (char *) (h)->chunk \ + > (h)->chunk_limit - (char *) (h)->chunk) \ + ? ((h)->next_free = (h)->chunk_limit) : 0), \ + (h)->object_base = (h)->next_free, \ + (h)->temp.tempptr) + +# define obstack_free(h,obj) \ +( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \ + ((((h)->temp.tempint > 0 \ + && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \ + ? (int) ((h)->next_free = (h)->object_base \ + = (h)->temp.tempint + (char *) (h)->chunk) \ + : (((__obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0))) + +#endif /* not __GNUC__ or not __STDC__ */ + +#ifdef __cplusplus +} /* C++ */ +#endif + +#endif /* obstack.h */ diff --git a/gnu/offtostr.c b/gnu/offtostr.c new file mode 100644 index 00000000..8190d7a7 --- /dev/null +++ b/gnu/offtostr.c @@ -0,0 +1,5 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define anytostr offtostr +#define inttype off_t +#include "anytostr.c" diff --git a/gnu/open.c b/gnu/open.c new file mode 100644 index 00000000..387128bf --- /dev/null +++ b/gnu/open.c @@ -0,0 +1,183 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Open a descriptor to a file. + Copyright (C) 2007-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2007. */ + +/* If the user's config.h happens to include <fcntl.h>, let it include only + the system's <fcntl.h> here, so that orig_open doesn't recurse to + rpl_open. */ +#define __need_system_fcntl_h +#include <config.h> + +/* Get the original definition of open. It might be defined as a macro. */ +#include <fcntl.h> +#include <sys/types.h> +#undef __need_system_fcntl_h + +static inline int +orig_open (const char *filename, int flags, mode_t mode) +{ + return open (filename, flags, mode); +} + +/* Specification. */ +/* Write "fcntl.h" here, not <fcntl.h>, otherwise OSF/1 5.1 DTK cc eliminates + this include because of the preliminary #include <fcntl.h> above. */ +#include "fcntl.h" + +#include <errno.h> +#include <stdarg.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#ifndef REPLACE_OPEN_DIRECTORY +# define REPLACE_OPEN_DIRECTORY 0 +#endif + +int +open (const char *filename, int flags, ...) +{ + 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 __WIN32__) && ! defined __CYGWIN__ + if (strcmp (filename, "/dev/null") == 0) + filename = "NUL"; +#endif + +#if OPEN_TRAILING_SLASH_BUG + /* If the filename ends in a slash and one of O_CREAT, O_WRONLY, O_RDWR + is specified, then fail. + Rationale: POSIX <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html> + says that + "A pathname that contains at least one non-slash character and that + ends with one or more trailing slashes shall be resolved as if a + single dot character ( '.' ) were appended to the pathname." + and + "The special filename dot shall refer to the directory specified by + its predecessor." + 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 + <http://www.opengroup.org/susv3/functions/open.html> 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 | O_WRONLY | O_RDWR)) + { + size_t len = strlen (filename); + if (len > 0 && filename[len - 1] == '/') + { + errno = EISDIR; + return -1; + } + } +#endif + + fd = orig_open (filename, flags, mode); + +#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 <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html> + says that + "A pathname that contains at least one non-slash character and that + ends with one or more trailing slashes shall be resolved as if a + single dot character ( '.' ) were appended to the pathname." + and + "The special filename dot shall refer to the directory specified by + its predecessor." + 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/gnu/openat-die.c b/gnu/openat-die.c new file mode 100644 index 00000000..1be01493 --- /dev/null +++ b/gnu/openat-die.c @@ -0,0 +1,64 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Report a save- or restore-cwd failure in our openat replacement and then exit. + + Copyright (C) 2005-2006, 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "openat.h" + +#include <stdlib.h> + +#ifndef GNULIB_LIBPOSIX +# include "error.h" +#endif + +#include "exitfail.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) + +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. */ + +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/gnu/openat-priv.h b/gnu/openat-priv.h new file mode 100644 index 00000000..e7e2e8e8 --- /dev/null +++ b/gnu/openat-priv.h @@ -0,0 +1,66 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Internals for openat-like functions. + + Copyright (C) 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering */ + +#ifndef _GL_HEADER_OPENAT_PRIV +#define _GL_HEADER_OPENAT_PRIV + +#include <errno.h> +#include <limits.h> +#include <stdlib.h> + +/* 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/gnu/openat-proc.c b/gnu/openat-proc.c new file mode 100644 index 00000000..0c5a66a6 --- /dev/null +++ b/gnu/openat-proc.c @@ -0,0 +1,112 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Create /proc/self/fd-related names for subfiles of open directories. + + Copyright (C) 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +#include "openat-priv.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "intprops.h" + +/* The results of open() in this file are not used with fchdir, + and we do not leak fds to any single-threaded code that could use stdio, + therefore save some unnecessary work in fchdir.c. + FIXME - if the kernel ever adds support for multi-thread safety for + avoiding standard fds, then we should use open_safer. */ +#undef open +#undef close + +#define PROC_SELF_FD_FORMAT "/proc/self/fd/%d/%s" + +#define PROC_SELF_FD_NAME_SIZE_BOUND(len) \ + (sizeof PROC_SELF_FD_FORMAT - sizeof "%d%s" \ + + INT_STRLEN_BOUND (int) + (len) + 1) + + +/* Set BUF to the expansion of PROC_SELF_FD_FORMAT, using FD and FILE + respectively for %d and %s. If successful, return BUF if the + result fits in BUF, dynamically allocated memory otherwise. But + return NULL if /proc is not reliable, either because the operating + system support is lacking or because memory is low. */ +char * +openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file) +{ + static int proc_status = 0; + + /* Make sure the caller gets ENOENT when appropriate. */ + if (!*file) + { + buf[0] = '\0'; + return buf; + } + + 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); + 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_NAME_SIZE_BOUND (sizeof "../fd" - 1)]; + sprintf (dotdot_buf, PROC_SELF_FD_FORMAT, proc_self_fd, "../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_NAME_SIZE_BOUND (strlen (file)); + char *result = buf; + if (OPENAT_BUFFER_SIZE < bufsize) + { + result = malloc (bufsize); + if (! result) + return NULL; + } + sprintf (result, PROC_SELF_FD_FORMAT, fd, file); + return result; + } +} diff --git a/gnu/openat.c b/gnu/openat.c new file mode 100644 index 00000000..9f046df6 --- /dev/null +++ b/gnu/openat.c @@ -0,0 +1,288 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* provide a replacement openat function + Copyright (C) 2004-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering */ + +/* If the user's config.h happens to include <fcntl.h>, let it include only + the system's <fcntl.h> here, so that orig_openat doesn't recurse to + rpl_openat. */ +#define __need_system_fcntl_h +#include <config.h> + +/* Get the original definition of open. It might be defined as a macro. */ +#include <fcntl.h> +#include <sys/types.h> +#undef __need_system_fcntl_h + +#if HAVE_OPENAT +static inline 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 <fcntl.h>, otherwise OSF/1 5.1 DTK cc eliminates + this include because of the preliminary #include <fcntl.h> above. */ +#include "fcntl.h" + +#include "openat.h" + +#include <stdarg.h> +#include <stdbool.h> +#include <stddef.h> +#include <string.h> +#include <sys/stat.h> +#include <errno.h> + +#if HAVE_OPENAT + +/* Like openat, but work around Solaris 9 bugs with trailing slash. */ +int +rpl_openat (int dfd, char const *filename, int flags, ...) +{ + 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 + /* If the filename ends in a slash and one of O_CREAT, O_WRONLY, O_RDWR + is specified, then fail. + Rationale: POSIX <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html> + says that + "A pathname that contains at least one non-slash character and that + ends with one or more trailing slashes shall be resolved as if a + single dot character ( '.' ) were appended to the pathname." + and + "The special filename dot shall refer to the directory specified by + its predecessor." + 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 + <http://www.opengroup.org/susv3/functions/open.html> 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 | O_WRONLY | O_RDWR)) + { + size_t len = strlen (filename); + if (len > 0 && filename[len - 1] == '/') + { + errno = EISDIR; + return -1; + } + } +# endif + + fd = orig_openat (dfd, filename, flags, mode); + +# if OPEN_TRAILING_SLASH_BUG + /* If the filename ends in a slash and fd does not refer to a directory, + then fail. + Rationale: POSIX <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html> + says that + "A pathname that contains at least one non-slash character and that + ends with one or more trailing slashes shall be resolved as if a + single dot character ( '.' ) were appended to the pathname." + and + "The special filename dot shall refer to the directory specified by + its predecessor." + 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 "dosname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ +# include "openat-priv.h" +# include "save-cwd.h" + +/* Replacement for Solaris' openat function. + <http://www.google.com/search?q=openat+site:docs.sun.com> + 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); + + 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/gnu/openat.h b/gnu/openat.h new file mode 100644 index 00000000..99355bf6 --- /dev/null +++ b/gnu/openat.h @@ -0,0 +1,106 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* provide a replacement openat function + Copyright (C) 2004-2006, 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering */ + +#ifndef _GL_HEADER_OPENAT +#define _GL_HEADER_OPENAT + +#include <fcntl.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdbool.h> + +#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_FCHOWNAT + +static inline int +chownat (int fd, char const *file, uid_t owner, gid_t group) +{ + return fchownat (fd, file, owner, group, 0); +} + +static 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_FCHMODAT + +static inline int +chmodat (int fd, char const *file, mode_t mode) +{ + return fchmodat (fd, file, mode, 0); +} + +static inline int +lchmodat (int fd, char const *file, mode_t mode) +{ + return fchmodat (fd, file, mode, AT_SYMLINK_NOFOLLOW); +} + +#endif + +#if GNULIB_FSTATAT + +static inline int +statat (int fd, char const *name, struct stat *st) +{ + return fstatat (fd, name, st, 0); +} + +static 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. */ + +#endif /* _GL_HEADER_OPENAT */ diff --git a/gnu/opendir-safer.c b/gnu/opendir-safer.c new file mode 100644 index 00000000..e2590f57 --- /dev/null +++ b/gnu/opendir-safer.c @@ -0,0 +1,78 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Invoke opendir, but avoid some glitches. + + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Eric Blake. */ + +#include <config.h> + +#include "dirent-safer.h" + +#include <errno.h> +#include <unistd.h> +#include "unistd-safer.h" + +/* Like opendir, but do not clobber stdin, stdout, or stderr. */ + +DIR * +opendir_safer (char const *name) +{ + DIR *dp = opendir (name); + + if (dp) + { + int fd = dirfd (dp); + + if (0 <= fd && fd <= STDERR_FILENO) + { + /* If fdopendir is native (as on Linux), then it is safe to + assume dirfd(fdopendir(n))==n. If we are using the + gnulib module fdopendir, then this guarantee is not met, + but fdopendir recursively calls opendir_safer up to 3 + times to at least get a safe fd. If fdopendir is not + present but dirfd is accurate (as on cygwin 1.5.x), then + we recurse up to 3 times ourselves. Finally, if dirfd + always fails (as on mingw), then we are already safe. */ + DIR *newdp; + int e; +#if HAVE_FDOPENDIR || GNULIB_FDOPENDIR + int f = dup_safer (fd); + if (f < 0) + { + e = errno; + newdp = NULL; + } + else + { + newdp = fdopendir (f); + e = errno; + if (! newdp) + close (f); + } +#else /* !FDOPENDIR */ + newdp = opendir_safer (name); + e = errno; +#endif + closedir (dp); + errno = e; + dp = newdp; + } + } + + return dp; +} diff --git a/gnu/opendir.c b/gnu/opendir.c new file mode 100644 index 00000000..b86a5b2c --- /dev/null +++ b/gnu/opendir.c @@ -0,0 +1,150 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Start reading the entries of a directory. + Copyright (C) 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <dirent.h> + +#include <errno.h> +#include <stddef.h> + +#if HAVE_OPENDIR + +/* Override opendir(), to keep track of the open file descriptors. + Needed because there is a function dirfd(). */ + +#else + +# include <stdlib.h> + +# include "dirent-private.h" +# include "filename.h" + +#endif + +#if REPLACE_FCHDIR +# include <unistd.h> +#endif + +DIR * +opendir (const char *dir_name) +{ +#if HAVE_OPENDIR +# undef opendir + DIR *dirp; + + dirp = opendir (dir_name); + if (dirp == NULL) + return NULL; + +#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/gnu/parse-datetime.h b/gnu/parse-datetime.h new file mode 100644 index 00000000..cdf5721e --- /dev/null +++ b/gnu/parse-datetime.h @@ -0,0 +1,24 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Parse a string into an internal time stamp. + + Copyright (C) 1995, 1997-1998, 2003-2004, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <stdbool.h> +#include <time.h> + +bool parse_datetime (struct timespec *, char const *, struct timespec const *); diff --git a/gnu/parse-datetime.y b/gnu/parse-datetime.y new file mode 100644 index 00000000..01d71051 --- /dev/null +++ b/gnu/parse-datetime.y @@ -0,0 +1,1617 @@ +%{ +/* Parse a string into an internal time stamp. + + Copyright (C) 1999-2000, 2002-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Originally written by Steven M. Bellovin <smb@research.att.com> while + at the University of North Carolina at Chapel Hill. Later tweaked by + a couple of people on Usenet. Completely overhauled by Rich $alz + <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990. + + Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do + the right thing about local DST. Also modified by Paul Eggert + <eggert@cs.ucla.edu> in February 2004 to support + nanosecond-resolution time stamps, and in October 2004 to support + TZ strings in dates. */ + +/* FIXME: Check for arithmetic overflow in all cases, not just + some of them. */ + +#include <config.h> + +#include "parse-datetime.h" + +#include "intprops.h" +#include "timespec.h" +#include "verify.h" + +/* There's no need to extend the stack, so there's no need to involve + alloca. */ +#define YYSTACK_USE_ALLOCA 0 + +/* Tell Bison how much stack space is needed. 20 should be plenty for + this grammar, which is not right recursive. Beware setting it too + high, since that might cause problems on machines whose + implementations have lame stack-overflow checking. */ +#define YYMAXDEPTH 20 +#define YYINITDEPTH YYMAXDEPTH + +/* Since the code of parse-datetime.y is not included in the Emacs executable + itself, there is no need to #define static in this file. Even if + the code were included in the Emacs executable, it probably + wouldn't do any harm to #undef it here; this will only cause + problems if we try to write to a static variable, which I don't + think this code needs to do. */ +#ifdef emacs +# undef static +#endif + +#include <c-ctype.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xalloc.h" + +/* Bison's skeleton tests _STDLIB_H, while some stdlib.h headers + use _STDLIB_H_ as witness. Map the latter to the one bison uses. */ +/* FIXME: this is temporary. Remove when we have a mechanism to ensure + that the version we're using is fixed, too. */ +#ifdef _STDLIB_H_ +# undef _STDLIB_H +# define _STDLIB_H 1 +#endif + +/* ISDIGIT differs from isdigit, as follows: + - Its arg may be any int or unsigned int; it need not be an unsigned char + or EOF. + - It's typically faster. + POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to + isdigit unless it's important to use the locale's definition + of "digit" even when the host does not conform to POSIX. */ +#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) + +/* Shift A right by B bits portably, by dividing A by 2**B and + truncating towards minus infinity. A and B should be free of side + effects, and B should be in the range 0 <= B <= INT_BITS - 2, where + INT_BITS is the number of useful bits in an int. GNU code can + assume that INT_BITS is at least 32. + + ISO C99 says that A >> B is implementation-defined if A < 0. Some + implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift + right in the usual way when A < 0, so SHR falls back on division if + ordinary A >> B doesn't seem to be the usual signed shift. */ +#define SHR(a, b) \ + (-1 >> 1 == -1 \ + ? (a) >> (b) \ + : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) + +#define EPOCH_YEAR 1970 +#define TM_YEAR_BASE 1900 + +#define HOUR(x) ((x) * 60) + +/* long_time_t is a signed integer type that contains all time_t values. */ +verify (TYPE_IS_INTEGER (time_t)); +#if TIME_T_FITS_IN_LONG_INT +typedef long int long_time_t; +#else +typedef time_t long_time_t; +#endif + +/* Lots of this code assumes time_t and time_t-like values fit into + long_time_t. */ +verify (TYPE_MINIMUM (long_time_t) <= TYPE_MINIMUM (time_t) + && TYPE_MAXIMUM (time_t) <= TYPE_MAXIMUM (long_time_t)); + +/* FIXME: It also assumes that signed integer overflow silently wraps around, + but this is not true any more with recent versions of GCC 4. */ + +/* An integer value, and the number of digits in its textual + representation. */ +typedef struct +{ + bool negative; + long int value; + size_t digits; +} textint; + +/* An entry in the lexical lookup table. */ +typedef struct +{ + char const *name; + int type; + int value; +} table; + +/* Meridian: am, pm, or 24-hour style. */ +enum { MERam, MERpm, MER24 }; + +enum { BILLION = 1000000000, LOG10_BILLION = 9 }; + +/* Relative times. */ +typedef struct +{ + /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */ + long int year; + long int month; + long int day; + long int hour; + long int minutes; + long_time_t seconds; + long int ns; +} relative_time; + +#if HAVE_COMPOUND_LITERALS +# define RELATIVE_TIME_0 ((relative_time) { 0, 0, 0, 0, 0, 0, 0 }) +#else +static relative_time const RELATIVE_TIME_0; +#endif + +/* Information passed to and from the parser. */ +typedef struct +{ + /* The input string remaining to be parsed. */ + const char *input; + + /* N, if this is the Nth Tuesday. */ + long int day_ordinal; + + /* Day of week; Sunday is 0. */ + int day_number; + + /* tm_isdst flag for the local zone. */ + int local_isdst; + + /* Time zone, in minutes east of UTC. */ + long int time_zone; + + /* Style used for time. */ + int meridian; + + /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds. */ + textint year; + long int month; + long int day; + long int hour; + long int minutes; + struct timespec seconds; /* includes nanoseconds */ + + /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */ + relative_time rel; + + /* Presence or counts of nonterminals of various flavors parsed so far. */ + bool timespec_seen; + bool rels_seen; + size_t dates_seen; + size_t days_seen; + size_t local_zones_seen; + size_t dsts_seen; + size_t times_seen; + size_t zones_seen; + + /* Table of local time zone abbrevations, terminated by a null entry. */ + table local_time_zone_table[3]; +} parser_control; + +union YYSTYPE; +static int yylex (union YYSTYPE *, parser_control *); +static int yyerror (parser_control const *, char const *); +static long int time_zone_hhmm (parser_control *, textint, long int); + +/* Extract into *PC any date and time info from a string of digits + of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY, + YYYY, ...). */ +static void +digits_to_date_time (parser_control *pc, textint text_int) +{ + if (pc->dates_seen && ! pc->year.digits + && ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits)) + pc->year = text_int; + else + { + if (4 < text_int.digits) + { + pc->dates_seen++; + pc->day = text_int.value % 100; + pc->month = (text_int.value / 100) % 100; + pc->year.value = text_int.value / 10000; + pc->year.digits = text_int.digits - 4; + } + else + { + pc->times_seen++; + if (text_int.digits <= 2) + { + pc->hour = text_int.value; + pc->minutes = 0; + } + else + { + pc->hour = text_int.value / 100; + pc->minutes = text_int.value % 100; + } + pc->seconds.tv_sec = 0; + pc->seconds.tv_nsec = 0; + pc->meridian = MER24; + } + } +} + +/* Increment PC->rel by FACTOR * REL (FACTOR is 1 or -1). */ +static void +apply_relative_time (parser_control *pc, relative_time rel, int factor) +{ + pc->rel.ns += factor * rel.ns; + pc->rel.seconds += factor * rel.seconds; + pc->rel.minutes += factor * rel.minutes; + pc->rel.hour += factor * rel.hour; + pc->rel.day += factor * rel.day; + pc->rel.month += factor * rel.month; + pc->rel.year += factor * rel.year; + pc->rels_seen = true; +} + +/* Set PC-> hour, minutes, seconds and nanoseconds members from arguments. */ +static void +set_hhmmss (parser_control *pc, long int hour, long int minutes, + time_t sec, long int nsec) +{ + pc->hour = hour; + pc->minutes = minutes; + pc->seconds.tv_sec = sec; + pc->seconds.tv_nsec = nsec; +} + +%} + +/* We want a reentrant parser, even if the TZ manipulation and the calls to + localtime and gmtime are not reentrant. */ +%pure-parser +%parse-param { parser_control *pc } +%lex-param { parser_control *pc } + +/* This grammar has 31 shift/reduce conflicts. */ +%expect 31 + +%union +{ + long int intval; + textint textintval; + struct timespec timespec; + relative_time rel; +} + +%token <intval> tAGO +%token tDST + +%token tYEAR_UNIT tMONTH_UNIT tHOUR_UNIT tMINUTE_UNIT tSEC_UNIT +%token <intval> tDAY_UNIT tDAY_SHIFT + +%token <intval> tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN +%token <intval> tMONTH tORDINAL tZONE + +%token <textintval> tSNUMBER tUNUMBER +%token <timespec> tSDECIMAL_NUMBER tUDECIMAL_NUMBER + +%type <intval> o_colon_minutes +%type <timespec> seconds signed_seconds unsigned_seconds + +%type <rel> relunit relunit_snumber dayshift + +%% + +spec: + timespec + | items + ; + +timespec: + '@' seconds + { + pc->seconds = $2; + pc->timespec_seen = true; + } + ; + +items: + /* empty */ + | items item + ; + +item: + datetime + { pc->times_seen++; pc->dates_seen++; } + | time + { pc->times_seen++; } + | local_zone + { pc->local_zones_seen++; } + | zone + { pc->zones_seen++; } + | date + { pc->dates_seen++; } + | day + { pc->days_seen++; } + | rel + | number + | hybrid + ; + +datetime: + iso_8601_datetime + ; + +iso_8601_datetime: + iso_8601_date 'T' iso_8601_time + ; + +time: + tUNUMBER tMERIDIAN + { + set_hhmmss (pc, $1.value, 0, 0, 0); + pc->meridian = $2; + } + | tUNUMBER ':' tUNUMBER tMERIDIAN + { + set_hhmmss (pc, $1.value, $3.value, 0, 0); + pc->meridian = $4; + } + | tUNUMBER ':' tUNUMBER ':' unsigned_seconds tMERIDIAN + { + set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec); + pc->meridian = $6; + } + | iso_8601_time + ; + +iso_8601_time: + tUNUMBER zone_offset + { + set_hhmmss (pc, $1.value, 0, 0, 0); + pc->meridian = MER24; + } + | tUNUMBER ':' tUNUMBER o_zone_offset + { + set_hhmmss (pc, $1.value, $3.value, 0, 0); + pc->meridian = MER24; + } + | tUNUMBER ':' tUNUMBER ':' unsigned_seconds o_zone_offset + { + set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec); + pc->meridian = MER24; + } + ; + +o_zone_offset: + /* empty */ + | zone_offset + ; + +zone_offset: + tSNUMBER o_colon_minutes + { + pc->zones_seen++; + pc->time_zone = time_zone_hhmm (pc, $1, $2); + } + ; + +local_zone: + tLOCAL_ZONE + { + pc->local_isdst = $1; + pc->dsts_seen += (0 < $1); + } + | tLOCAL_ZONE tDST + { + pc->local_isdst = 1; + pc->dsts_seen += (0 < $1) + 1; + } + ; + +/* Note 'T' is a special case, as it is used as the separator in ISO + 8601 date and time of day representation. */ +zone: + tZONE + { pc->time_zone = $1; } + | 'T' + { pc->time_zone = HOUR(7); } + | tZONE relunit_snumber + { pc->time_zone = $1; + apply_relative_time (pc, $2, 1); } + | 'T' relunit_snumber + { pc->time_zone = HOUR(7); + apply_relative_time (pc, $2, 1); } + | tZONE tSNUMBER o_colon_minutes + { pc->time_zone = $1 + time_zone_hhmm (pc, $2, $3); } + | tDAYZONE + { pc->time_zone = $1 + 60; } + | tZONE tDST + { pc->time_zone = $1 + 60; } + ; + +day: + tDAY + { + pc->day_ordinal = 0; + pc->day_number = $1; + } + | tDAY ',' + { + pc->day_ordinal = 0; + pc->day_number = $1; + } + | tORDINAL tDAY + { + pc->day_ordinal = $1; + pc->day_number = $2; + } + | tUNUMBER tDAY + { + pc->day_ordinal = $1.value; + pc->day_number = $2; + } + ; + +date: + tUNUMBER '/' tUNUMBER + { + pc->month = $1.value; + pc->day = $3.value; + } + | tUNUMBER '/' tUNUMBER '/' tUNUMBER + { + /* Interpret as YYYY/MM/DD if the first value has 4 or more digits, + otherwise as MM/DD/YY. + The goal in recognizing YYYY/MM/DD is solely to support legacy + machine-generated dates like those in an RCS log listing. If + you want portability, use the ISO 8601 format. */ + if (4 <= $1.digits) + { + pc->year = $1; + pc->month = $3.value; + pc->day = $5.value; + } + else + { + pc->month = $1.value; + pc->day = $3.value; + pc->year = $5; + } + } + | tUNUMBER tMONTH tSNUMBER + { + /* e.g. 17-JUN-1992. */ + pc->day = $1.value; + pc->month = $2; + pc->year.value = -$3.value; + pc->year.digits = $3.digits; + } + | tMONTH tSNUMBER tSNUMBER + { + /* e.g. JUN-17-1992. */ + pc->month = $1; + pc->day = -$2.value; + pc->year.value = -$3.value; + pc->year.digits = $3.digits; + } + | tMONTH tUNUMBER + { + pc->month = $1; + pc->day = $2.value; + } + | tMONTH tUNUMBER ',' tUNUMBER + { + pc->month = $1; + pc->day = $2.value; + pc->year = $4; + } + | tUNUMBER tMONTH + { + pc->day = $1.value; + pc->month = $2; + } + | tUNUMBER tMONTH tUNUMBER + { + pc->day = $1.value; + pc->month = $2; + pc->year = $3; + } + | iso_8601_date + ; + +iso_8601_date: + tUNUMBER tSNUMBER tSNUMBER + { + /* ISO 8601 format. YYYY-MM-DD. */ + pc->year = $1; + pc->month = -$2.value; + pc->day = -$3.value; + } + ; + +rel: + relunit tAGO + { apply_relative_time (pc, $1, $2); } + | relunit + { apply_relative_time (pc, $1, 1); } + | dayshift + { apply_relative_time (pc, $1, 1); } + ; + +relunit: + tORDINAL tYEAR_UNIT + { $$ = RELATIVE_TIME_0; $$.year = $1; } + | tUNUMBER tYEAR_UNIT + { $$ = RELATIVE_TIME_0; $$.year = $1.value; } + | tYEAR_UNIT + { $$ = RELATIVE_TIME_0; $$.year = 1; } + | tORDINAL tMONTH_UNIT + { $$ = RELATIVE_TIME_0; $$.month = $1; } + | tUNUMBER tMONTH_UNIT + { $$ = RELATIVE_TIME_0; $$.month = $1.value; } + | tMONTH_UNIT + { $$ = RELATIVE_TIME_0; $$.month = 1; } + | tORDINAL tDAY_UNIT + { $$ = RELATIVE_TIME_0; $$.day = $1 * $2; } + | tUNUMBER tDAY_UNIT + { $$ = RELATIVE_TIME_0; $$.day = $1.value * $2; } + | tDAY_UNIT + { $$ = RELATIVE_TIME_0; $$.day = $1; } + | tORDINAL tHOUR_UNIT + { $$ = RELATIVE_TIME_0; $$.hour = $1; } + | tUNUMBER tHOUR_UNIT + { $$ = RELATIVE_TIME_0; $$.hour = $1.value; } + | tHOUR_UNIT + { $$ = RELATIVE_TIME_0; $$.hour = 1; } + | tORDINAL tMINUTE_UNIT + { $$ = RELATIVE_TIME_0; $$.minutes = $1; } + | tUNUMBER tMINUTE_UNIT + { $$ = RELATIVE_TIME_0; $$.minutes = $1.value; } + | tMINUTE_UNIT + { $$ = RELATIVE_TIME_0; $$.minutes = 1; } + | tORDINAL tSEC_UNIT + { $$ = RELATIVE_TIME_0; $$.seconds = $1; } + | tUNUMBER tSEC_UNIT + { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; } + | tSDECIMAL_NUMBER tSEC_UNIT + { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; } + | tUDECIMAL_NUMBER tSEC_UNIT + { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; } + | tSEC_UNIT + { $$ = RELATIVE_TIME_0; $$.seconds = 1; } + | relunit_snumber + ; + +relunit_snumber: + tSNUMBER tYEAR_UNIT + { $$ = RELATIVE_TIME_0; $$.year = $1.value; } + | tSNUMBER tMONTH_UNIT + { $$ = RELATIVE_TIME_0; $$.month = $1.value; } + | tSNUMBER tDAY_UNIT + { $$ = RELATIVE_TIME_0; $$.day = $1.value * $2; } + | tSNUMBER tHOUR_UNIT + { $$ = RELATIVE_TIME_0; $$.hour = $1.value; } + | tSNUMBER tMINUTE_UNIT + { $$ = RELATIVE_TIME_0; $$.minutes = $1.value; } + | tSNUMBER tSEC_UNIT + { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; } + ; + +dayshift: + tDAY_SHIFT + { $$ = RELATIVE_TIME_0; $$.day = $1; } + ; + +seconds: signed_seconds | unsigned_seconds; + +signed_seconds: + tSDECIMAL_NUMBER + | tSNUMBER + { $$.tv_sec = $1.value; $$.tv_nsec = 0; } + ; + +unsigned_seconds: + tUDECIMAL_NUMBER + | tUNUMBER + { $$.tv_sec = $1.value; $$.tv_nsec = 0; } + ; + +number: + tUNUMBER + { digits_to_date_time (pc, $1); } + ; + +hybrid: + tUNUMBER relunit_snumber + { + /* Hybrid all-digit and relative offset, so that we accept e.g., + "YYYYMMDD +N days" as well as "YYYYMMDD N days". */ + digits_to_date_time (pc, $1); + apply_relative_time (pc, $2, 1); + } + ; + +o_colon_minutes: + /* empty */ + { $$ = -1; } + | ':' tUNUMBER + { $$ = $2.value; } + ; + +%% + +static table const meridian_table[] = +{ + { "AM", tMERIDIAN, MERam }, + { "A.M.", tMERIDIAN, MERam }, + { "PM", tMERIDIAN, MERpm }, + { "P.M.", tMERIDIAN, MERpm }, + { NULL, 0, 0 } +}; + +static table const dst_table[] = +{ + { "DST", tDST, 0 } +}; + +static table const month_and_day_table[] = +{ + { "JANUARY", tMONTH, 1 }, + { "FEBRUARY", tMONTH, 2 }, + { "MARCH", tMONTH, 3 }, + { "APRIL", tMONTH, 4 }, + { "MAY", tMONTH, 5 }, + { "JUNE", tMONTH, 6 }, + { "JULY", tMONTH, 7 }, + { "AUGUST", tMONTH, 8 }, + { "SEPTEMBER",tMONTH, 9 }, + { "SEPT", tMONTH, 9 }, + { "OCTOBER", tMONTH, 10 }, + { "NOVEMBER", tMONTH, 11 }, + { "DECEMBER", tMONTH, 12 }, + { "SUNDAY", tDAY, 0 }, + { "MONDAY", tDAY, 1 }, + { "TUESDAY", tDAY, 2 }, + { "TUES", tDAY, 2 }, + { "WEDNESDAY",tDAY, 3 }, + { "WEDNES", tDAY, 3 }, + { "THURSDAY", tDAY, 4 }, + { "THUR", tDAY, 4 }, + { "THURS", tDAY, 4 }, + { "FRIDAY", tDAY, 5 }, + { "SATURDAY", tDAY, 6 }, + { NULL, 0, 0 } +}; + +static table const time_units_table[] = +{ + { "YEAR", tYEAR_UNIT, 1 }, + { "MONTH", tMONTH_UNIT, 1 }, + { "FORTNIGHT",tDAY_UNIT, 14 }, + { "WEEK", tDAY_UNIT, 7 }, + { "DAY", tDAY_UNIT, 1 }, + { "HOUR", tHOUR_UNIT, 1 }, + { "MINUTE", tMINUTE_UNIT, 1 }, + { "MIN", tMINUTE_UNIT, 1 }, + { "SECOND", tSEC_UNIT, 1 }, + { "SEC", tSEC_UNIT, 1 }, + { NULL, 0, 0 } +}; + +/* Assorted relative-time words. */ +static table const relative_time_table[] = +{ + { "TOMORROW", tDAY_SHIFT, 1 }, + { "YESTERDAY",tDAY_SHIFT, -1 }, + { "TODAY", tDAY_SHIFT, 0 }, + { "NOW", tDAY_SHIFT, 0 }, + { "LAST", tORDINAL, -1 }, + { "THIS", tORDINAL, 0 }, + { "NEXT", tORDINAL, 1 }, + { "FIRST", tORDINAL, 1 }, +/*{ "SECOND", tORDINAL, 2 }, */ + { "THIRD", tORDINAL, 3 }, + { "FOURTH", tORDINAL, 4 }, + { "FIFTH", tORDINAL, 5 }, + { "SIXTH", tORDINAL, 6 }, + { "SEVENTH", tORDINAL, 7 }, + { "EIGHTH", tORDINAL, 8 }, + { "NINTH", tORDINAL, 9 }, + { "TENTH", tORDINAL, 10 }, + { "ELEVENTH", tORDINAL, 11 }, + { "TWELFTH", tORDINAL, 12 }, + { "AGO", tAGO, -1 }, + { "HENCE", tAGO, 1 }, + { NULL, 0, 0 } +}; + +/* The universal time zone table. These labels can be used even for + time stamps that would not otherwise be valid, e.g., GMT time + stamps in London during summer. */ +static table const universal_time_zone_table[] = +{ + { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */ + { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */ + { "UTC", tZONE, HOUR ( 0) }, + { NULL, 0, 0 } +}; + +/* The time zone table. This table is necessarily incomplete, as time + zone abbreviations are ambiguous; e.g. Australians interpret "EST" + as Eastern time in Australia, not as US Eastern Standard Time. + You cannot rely on parse_datetime to handle arbitrary time zone + abbreviations; use numeric abbreviations like "-0500" instead. */ +static table const time_zone_table[] = +{ + { "WET", tZONE, HOUR ( 0) }, /* Western European */ + { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */ + { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */ + { "ART", tZONE, -HOUR ( 3) }, /* Argentina */ + { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */ + { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */ + { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */ + { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */ + { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */ + { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */ + { "CLT", tZONE, -HOUR ( 4) }, /* Chile */ + { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */ + { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */ + { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */ + { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */ + { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */ + { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */ + { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */ + { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */ + { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */ + { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */ + { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */ + { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */ + { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */ + { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */ + { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */ + { "WAT", tZONE, HOUR ( 1) }, /* West Africa */ + { "CET", tZONE, HOUR ( 1) }, /* Central European */ + { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */ + { "MET", tZONE, HOUR ( 1) }, /* Middle European */ + { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */ + { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ + { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ + { "EET", tZONE, HOUR ( 2) }, /* Eastern European */ + { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */ + { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */ + { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */ + { "EAT", tZONE, HOUR ( 3) }, /* East Africa */ + { "MSK", tZONE, HOUR ( 3) }, /* Moscow */ + { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */ + { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */ + { "SGT", tZONE, HOUR ( 8) }, /* Singapore */ + { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */ + { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */ + { "GST", tZONE, HOUR (10) }, /* Guam Standard */ + { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */ + { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */ + { NULL, 0, 0 } +}; + +/* Military time zone table. + + Note 'T' is a special case, as it is used as the separator in ISO + 8601 date and time of day representation. */ +static table const military_table[] = +{ + { "A", tZONE, -HOUR ( 1) }, + { "B", tZONE, -HOUR ( 2) }, + { "C", tZONE, -HOUR ( 3) }, + { "D", tZONE, -HOUR ( 4) }, + { "E", tZONE, -HOUR ( 5) }, + { "F", tZONE, -HOUR ( 6) }, + { "G", tZONE, -HOUR ( 7) }, + { "H", tZONE, -HOUR ( 8) }, + { "I", tZONE, -HOUR ( 9) }, + { "K", tZONE, -HOUR (10) }, + { "L", tZONE, -HOUR (11) }, + { "M", tZONE, -HOUR (12) }, + { "N", tZONE, HOUR ( 1) }, + { "O", tZONE, HOUR ( 2) }, + { "P", tZONE, HOUR ( 3) }, + { "Q", tZONE, HOUR ( 4) }, + { "R", tZONE, HOUR ( 5) }, + { "S", tZONE, HOUR ( 6) }, + { "T", 'T', 0 }, + { "U", tZONE, HOUR ( 8) }, + { "V", tZONE, HOUR ( 9) }, + { "W", tZONE, HOUR (10) }, + { "X", tZONE, HOUR (11) }, + { "Y", tZONE, HOUR (12) }, + { "Z", tZONE, HOUR ( 0) }, + { NULL, 0, 0 } +}; + + + +/* Convert a time zone expressed as HH:MM into an integer count of + minutes. If MM is negative, then S is of the form HHMM and needs + to be picked apart; otherwise, S is of the form HH. As specified in + http://www.opengroup.org/susv3xbd/xbd_chap08.html#tag_08_03, allow + only valid TZ range, and consider first two digits as hours, if no + minutes specified. */ + +static long int +time_zone_hhmm (parser_control *pc, textint s, long int mm) +{ + long int n_minutes; + + /* If the length of S is 1 or 2 and no minutes are specified, + interpret it as a number of hours. */ + if (s.digits <= 2 && mm < 0) + s.value *= 100; + + if (mm < 0) + n_minutes = (s.value / 100) * 60 + s.value % 100; + else + n_minutes = s.value * 60 + (s.negative ? -mm : mm); + + /* If the absolute number of minutes is larger than 24 hours, + arrange to reject it by incrementing pc->zones_seen. Thus, + we allow only values in the range UTC-24:00 to UTC+24:00. */ + if (24 * 60 < abs (n_minutes)) + pc->zones_seen++; + + return n_minutes; +} + +static int +to_hour (long int hours, int meridian) +{ + switch (meridian) + { + default: /* Pacify GCC. */ + case MER24: + return 0 <= hours && hours < 24 ? hours : -1; + case MERam: + return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1; + case MERpm: + return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1; + } +} + +static long int +to_year (textint textyear) +{ + long int year = textyear.value; + + if (year < 0) + year = -year; + + /* XPG4 suggests that years 00-68 map to 2000-2068, and + years 69-99 map to 1969-1999. */ + else if (textyear.digits == 2) + year += year < 69 ? 2000 : 1900; + + return year; +} + +static table const * _GL_ATTRIBUTE_PURE +lookup_zone (parser_control const *pc, char const *name) +{ + table const *tp; + + for (tp = universal_time_zone_table; tp->name; tp++) + if (strcmp (name, tp->name) == 0) + return tp; + + /* Try local zone abbreviations before those in time_zone_table, as + the local ones are more likely to be right. */ + for (tp = pc->local_time_zone_table; tp->name; tp++) + if (strcmp (name, tp->name) == 0) + return tp; + + for (tp = time_zone_table; tp->name; tp++) + if (strcmp (name, tp->name) == 0) + return tp; + + return NULL; +} + +#if ! HAVE_TM_GMTOFF +/* Yield the difference between *A and *B, + measured in seconds, ignoring leap seconds. + The body of this function is taken directly from the GNU C Library; + see src/strftime.c. */ +static long int +tm_diff (struct tm const *a, struct tm const *b) +{ + /* Compute intervening leap days correctly even if year is negative. + Take care to avoid int overflow in leap day calculations. */ + int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3); + int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3); + int a100 = a4 / 25 - (a4 % 25 < 0); + int b100 = b4 / 25 - (b4 % 25 < 0); + int a400 = SHR (a100, 2); + int b400 = SHR (b100, 2); + int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); + long int ayear = a->tm_year; + long int years = ayear - b->tm_year; + long int days = (365 * years + intervening_leap_days + + (a->tm_yday - b->tm_yday)); + return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) + + (a->tm_min - b->tm_min)) + + (a->tm_sec - b->tm_sec)); +} +#endif /* ! HAVE_TM_GMTOFF */ + +static table const * +lookup_word (parser_control const *pc, char *word) +{ + char *p; + char *q; + size_t wordlen; + table const *tp; + bool period_found; + bool abbrev; + + /* Make it uppercase. */ + for (p = word; *p; p++) + { + unsigned char ch = *p; + *p = c_toupper (ch); + } + + for (tp = meridian_table; tp->name; tp++) + if (strcmp (word, tp->name) == 0) + return tp; + + /* See if we have an abbreviation for a month. */ + wordlen = strlen (word); + abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.'); + + for (tp = month_and_day_table; tp->name; tp++) + if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0) + return tp; + + if ((tp = lookup_zone (pc, word))) + return tp; + + if (strcmp (word, dst_table[0].name) == 0) + return dst_table; + + for (tp = time_units_table; tp->name; tp++) + if (strcmp (word, tp->name) == 0) + return tp; + + /* Strip off any plural and try the units table again. */ + if (word[wordlen - 1] == 'S') + { + word[wordlen - 1] = '\0'; + for (tp = time_units_table; tp->name; tp++) + if (strcmp (word, tp->name) == 0) + return tp; + word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */ + } + + for (tp = relative_time_table; tp->name; tp++) + if (strcmp (word, tp->name) == 0) + return tp; + + /* Military time zones. */ + if (wordlen == 1) + for (tp = military_table; tp->name; tp++) + if (word[0] == tp->name[0]) + return tp; + + /* Drop out any periods and try the time zone table again. */ + for (period_found = false, p = q = word; (*p = *q); q++) + if (*q == '.') + period_found = true; + else + p++; + if (period_found && (tp = lookup_zone (pc, word))) + return tp; + + return NULL; +} + +static int +yylex (YYSTYPE *lvalp, parser_control *pc) +{ + unsigned char c; + size_t count; + + for (;;) + { + while (c = *pc->input, c_isspace (c)) + pc->input++; + + if (ISDIGIT (c) || c == '-' || c == '+') + { + char const *p; + int sign; + unsigned long int value; + if (c == '-' || c == '+') + { + sign = c == '-' ? -1 : 1; + while (c = *++pc->input, c_isspace (c)) + continue; + if (! ISDIGIT (c)) + /* skip the '-' sign */ + continue; + } + else + sign = 0; + p = pc->input; + for (value = 0; ; value *= 10) + { + unsigned long int value1 = value + (c - '0'); + if (value1 < value) + return '?'; + value = value1; + c = *++p; + if (! ISDIGIT (c)) + break; + if (ULONG_MAX / 10 < value) + return '?'; + } + if ((c == '.' || c == ',') && ISDIGIT (p[1])) + { + time_t s; + int ns; + int digits; + unsigned long int value1; + + /* Check for overflow when converting value to time_t. */ + if (sign < 0) + { + s = - value; + if (0 < s) + return '?'; + value1 = -s; + } + else + { + s = value; + if (s < 0) + return '?'; + value1 = s; + } + if (value != value1) + return '?'; + + /* Accumulate fraction, to ns precision. */ + p++; + ns = *p++ - '0'; + for (digits = 2; digits <= LOG10_BILLION; digits++) + { + ns *= 10; + if (ISDIGIT (*p)) + ns += *p++ - '0'; + } + + /* Skip excess digits, truncating toward -Infinity. */ + if (sign < 0) + for (; ISDIGIT (*p); p++) + if (*p != '0') + { + ns++; + break; + } + while (ISDIGIT (*p)) + p++; + + /* Adjust to the timespec convention, which is that + tv_nsec is always a positive offset even if tv_sec is + negative. */ + if (sign < 0 && ns) + { + s--; + if (! (s < 0)) + return '?'; + ns = BILLION - ns; + } + + lvalp->timespec.tv_sec = s; + lvalp->timespec.tv_nsec = ns; + pc->input = p; + return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER; + } + else + { + lvalp->textintval.negative = sign < 0; + if (sign < 0) + { + lvalp->textintval.value = - value; + if (0 < lvalp->textintval.value) + return '?'; + } + else + { + lvalp->textintval.value = value; + if (lvalp->textintval.value < 0) + return '?'; + } + lvalp->textintval.digits = p - pc->input; + pc->input = p; + return sign ? tSNUMBER : tUNUMBER; + } + } + + if (c_isalpha (c)) + { + char buff[20]; + char *p = buff; + table const *tp; + + do + { + if (p - buff < sizeof buff - 1) + *p++ = c; + c = *++pc->input; + } + while (c_isalpha (c) || c == '.'); + + *p = '\0'; + tp = lookup_word (pc, buff); + if (! tp) + return '?'; + lvalp->intval = tp->value; + return tp->type; + } + + if (c != '(') + return *pc->input++; + count = 0; + do + { + c = *pc->input++; + if (c == '\0') + return c; + if (c == '(') + count++; + else if (c == ')') + count--; + } + while (count != 0); + } +} + +/* Do nothing if the parser reports an error. */ +static int +yyerror (parser_control const *pc _GL_UNUSED, + char const *s _GL_UNUSED) +{ + return 0; +} + +/* If *TM0 is the old and *TM1 is the new value of a struct tm after + passing it to mktime, return true if it's OK that mktime returned T. + It's not OK if *TM0 has out-of-range members. */ + +static bool +mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t) +{ + if (t == (time_t) -1) + { + /* Guard against falsely reporting an error when parsing a time + stamp that happens to equal (time_t) -1, on a host that + supports such a time stamp. */ + tm1 = localtime (&t); + if (!tm1) + return false; + } + + return ! ((tm0->tm_sec ^ tm1->tm_sec) + | (tm0->tm_min ^ tm1->tm_min) + | (tm0->tm_hour ^ tm1->tm_hour) + | (tm0->tm_mday ^ tm1->tm_mday) + | (tm0->tm_mon ^ tm1->tm_mon) + | (tm0->tm_year ^ tm1->tm_year)); +} + +/* A reasonable upper bound for the size of ordinary TZ strings. + Use heap allocation if TZ's length exceeds this. */ +enum { TZBUFSIZE = 100 }; + +/* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated + otherwise. */ +static char * +get_tz (char tzbuf[TZBUFSIZE]) +{ + char *tz = getenv ("TZ"); + if (tz) + { + size_t tzsize = strlen (tz) + 1; + tz = (tzsize <= TZBUFSIZE + ? memcpy (tzbuf, tz, tzsize) + : xmemdup (tz, tzsize)); + } + return tz; +} + +/* Parse a date/time string, storing the resulting time value into *RESULT. + The string itself is pointed to by P. Return true if successful. + P can be an incomplete or relative time specification; if so, use + *NOW as the basis for the returned time. */ +bool +parse_datetime (struct timespec *result, char const *p, + struct timespec const *now) +{ + time_t Start; + long int Start_ns; + struct tm const *tmp; + struct tm tm; + struct tm tm0; + parser_control pc; + struct timespec gettime_buffer; + unsigned char c; + bool tz_was_altered = false; + char *tz0 = NULL; + char tz0buf[TZBUFSIZE]; + bool ok = true; + + if (! now) + { + gettime (&gettime_buffer); + now = &gettime_buffer; + } + + Start = now->tv_sec; + Start_ns = now->tv_nsec; + + tmp = localtime (&now->tv_sec); + if (! tmp) + return false; + + while (c = *p, c_isspace (c)) + p++; + + if (strncmp (p, "TZ=\"", 4) == 0) + { + char const *tzbase = p + 4; + size_t tzsize = 1; + char const *s; + + for (s = tzbase; *s; s++, tzsize++) + if (*s == '\\') + { + s++; + if (! (*s == '\\' || *s == '"')) + break; + } + else if (*s == '"') + { + char *z; + char *tz1; + char tz1buf[TZBUFSIZE]; + bool large_tz = TZBUFSIZE < tzsize; + bool setenv_ok; + /* Free tz0, in case this is the 2nd or subsequent time through. */ + free (tz0); + tz0 = get_tz (tz0buf); + z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf; + for (s = tzbase; *s != '"'; s++) + *z++ = *(s += *s == '\\'); + *z = '\0'; + setenv_ok = setenv ("TZ", tz1, 1) == 0; + if (large_tz) + free (tz1); + if (!setenv_ok) + goto fail; + tz_was_altered = true; + p = s + 1; + } + } + + /* As documented, be careful to treat the empty string just like + a date string of "0". Without this, an empty string would be + declared invalid when parsed during a DST transition. */ + if (*p == '\0') + p = "0"; + + pc.input = p; + pc.year.value = tmp->tm_year; + pc.year.value += TM_YEAR_BASE; + pc.year.digits = 0; + pc.month = tmp->tm_mon + 1; + pc.day = tmp->tm_mday; + pc.hour = tmp->tm_hour; + pc.minutes = tmp->tm_min; + pc.seconds.tv_sec = tmp->tm_sec; + pc.seconds.tv_nsec = Start_ns; + tm.tm_isdst = tmp->tm_isdst; + + pc.meridian = MER24; + pc.rel = RELATIVE_TIME_0; + pc.timespec_seen = false; + pc.rels_seen = false; + pc.dates_seen = 0; + pc.days_seen = 0; + pc.times_seen = 0; + pc.local_zones_seen = 0; + pc.dsts_seen = 0; + pc.zones_seen = 0; + +#if HAVE_STRUCT_TM_TM_ZONE + pc.local_time_zone_table[0].name = tmp->tm_zone; + pc.local_time_zone_table[0].type = tLOCAL_ZONE; + pc.local_time_zone_table[0].value = tmp->tm_isdst; + pc.local_time_zone_table[1].name = NULL; + + /* Probe the names used in the next three calendar quarters, looking + for a tm_isdst different from the one we already have. */ + { + int quarter; + for (quarter = 1; quarter <= 3; quarter++) + { + time_t probe = Start + quarter * (90 * 24 * 60 * 60); + struct tm const *probe_tm = localtime (&probe); + if (probe_tm && probe_tm->tm_zone + && probe_tm->tm_isdst != pc.local_time_zone_table[0].value) + { + { + pc.local_time_zone_table[1].name = probe_tm->tm_zone; + pc.local_time_zone_table[1].type = tLOCAL_ZONE; + pc.local_time_zone_table[1].value = probe_tm->tm_isdst; + pc.local_time_zone_table[2].name = NULL; + } + break; + } + } + } +#else +#if HAVE_TZNAME + { +# if !HAVE_DECL_TZNAME + extern char *tzname[]; +# endif + int i; + for (i = 0; i < 2; i++) + { + pc.local_time_zone_table[i].name = tzname[i]; + pc.local_time_zone_table[i].type = tLOCAL_ZONE; + pc.local_time_zone_table[i].value = i; + } + pc.local_time_zone_table[i].name = NULL; + } +#else + pc.local_time_zone_table[0].name = NULL; +#endif +#endif + + if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name + && ! strcmp (pc.local_time_zone_table[0].name, + pc.local_time_zone_table[1].name)) + { + /* This locale uses the same abbrevation for standard and + daylight times. So if we see that abbreviation, we don't + know whether it's daylight time. */ + pc.local_time_zone_table[0].value = -1; + pc.local_time_zone_table[1].name = NULL; + } + + if (yyparse (&pc) != 0) + goto fail; + + if (pc.timespec_seen) + *result = pc.seconds; + else + { + if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen + | (pc.local_zones_seen + pc.zones_seen))) + goto fail; + + tm.tm_year = to_year (pc.year) - TM_YEAR_BASE; + tm.tm_mon = pc.month - 1; + tm.tm_mday = pc.day; + if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen)) + { + tm.tm_hour = to_hour (pc.hour, pc.meridian); + if (tm.tm_hour < 0) + goto fail; + tm.tm_min = pc.minutes; + tm.tm_sec = pc.seconds.tv_sec; + } + else + { + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + pc.seconds.tv_nsec = 0; + } + + /* Let mktime deduce tm_isdst if we have an absolute time stamp. */ + if (pc.dates_seen | pc.days_seen | pc.times_seen) + tm.tm_isdst = -1; + + /* But if the input explicitly specifies local time with or without + DST, give mktime that information. */ + if (pc.local_zones_seen) + tm.tm_isdst = pc.local_isdst; + + tm0 = tm; + + Start = mktime (&tm); + + if (! mktime_ok (&tm0, &tm, Start)) + { + if (! pc.zones_seen) + goto fail; + else + { + /* Guard against falsely reporting errors near the time_t + boundaries when parsing times in other time zones. For + example, suppose the input string "1969-12-31 23:00:00 -0100", + the current time zone is 8 hours ahead of UTC, and the min + time_t value is 1970-01-01 00:00:00 UTC. Then the min + localtime value is 1970-01-01 08:00:00, and mktime will + therefore fail on 1969-12-31 23:00:00. To work around the + problem, set the time zone to 1 hour behind UTC temporarily + by setting TZ="XXX1:00" and try mktime again. */ + + long int time_zone = pc.time_zone; + long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone; + long int abs_time_zone_hour = abs_time_zone / 60; + int abs_time_zone_min = abs_time_zone % 60; + char tz1buf[sizeof "XXX+0:00" + + sizeof pc.time_zone * CHAR_BIT / 3]; + if (!tz_was_altered) + tz0 = get_tz (tz0buf); + sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0), + abs_time_zone_hour, abs_time_zone_min); + if (setenv ("TZ", tz1buf, 1) != 0) + goto fail; + tz_was_altered = true; + tm = tm0; + Start = mktime (&tm); + if (! mktime_ok (&tm0, &tm, Start)) + goto fail; + } + } + + if (pc.days_seen && ! pc.dates_seen) + { + tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7 + + 7 * (pc.day_ordinal + - (0 < pc.day_ordinal + && tm.tm_wday != pc.day_number))); + tm.tm_isdst = -1; + Start = mktime (&tm); + if (Start == (time_t) -1) + goto fail; + } + + /* Add relative date. */ + if (pc.rel.year | pc.rel.month | pc.rel.day) + { + int year = tm.tm_year + pc.rel.year; + int month = tm.tm_mon + pc.rel.month; + int day = tm.tm_mday + pc.rel.day; + if (((year < tm.tm_year) ^ (pc.rel.year < 0)) + | ((month < tm.tm_mon) ^ (pc.rel.month < 0)) + | ((day < tm.tm_mday) ^ (pc.rel.day < 0))) + goto fail; + tm.tm_year = year; + tm.tm_mon = month; + tm.tm_mday = day; + tm.tm_hour = tm0.tm_hour; + tm.tm_min = tm0.tm_min; + tm.tm_sec = tm0.tm_sec; + tm.tm_isdst = tm0.tm_isdst; + Start = mktime (&tm); + if (Start == (time_t) -1) + goto fail; + } + + /* The only "output" of this if-block is an updated Start value, + so this block must follow others that clobber Start. */ + if (pc.zones_seen) + { + long int delta = pc.time_zone * 60; + time_t t1; +#ifdef HAVE_TM_GMTOFF + delta -= tm.tm_gmtoff; +#else + time_t t = Start; + struct tm const *gmt = gmtime (&t); + if (! gmt) + goto fail; + delta -= tm_diff (&tm, gmt); +#endif + t1 = Start - delta; + if ((Start < t1) != (delta < 0)) + goto fail; /* time_t overflow */ + Start = t1; + } + + /* Add relative hours, minutes, and seconds. On hosts that support + leap seconds, ignore the possibility of leap seconds; e.g., + "+ 10 minutes" adds 600 seconds, even if one of them is a + leap second. Typically this is not what the user wants, but it's + too hard to do it the other way, because the time zone indicator + must be applied before relative times, and if mktime is applied + again the time zone will be lost. */ + { + long int sum_ns = pc.seconds.tv_nsec + pc.rel.ns; + long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION; + time_t t0 = Start; + long int d1 = 60 * 60 * pc.rel.hour; + time_t t1 = t0 + d1; + long int d2 = 60 * pc.rel.minutes; + time_t t2 = t1 + d2; + long_time_t d3 = pc.rel.seconds; + long_time_t t3 = t2 + d3; + long int d4 = (sum_ns - normalized_ns) / BILLION; + long_time_t t4 = t3 + d4; + time_t t5 = t4; + + if ((d1 / (60 * 60) ^ pc.rel.hour) + | (d2 / 60 ^ pc.rel.minutes) + | ((t1 < t0) ^ (d1 < 0)) + | ((t2 < t1) ^ (d2 < 0)) + | ((t3 < t2) ^ (d3 < 0)) + | ((t4 < t3) ^ (d4 < 0)) + | (t5 != t4)) + goto fail; + + result->tv_sec = t5; + result->tv_nsec = normalized_ns; + } + } + + goto done; + + fail: + ok = false; + done: + if (tz_was_altered) + ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0; + if (tz0 != tz0buf) + free (tz0); + return ok; +} + +#if TEST + +int +main (int ac, char **av) +{ + char buff[BUFSIZ]; + + printf ("Enter date, or blank line to exit.\n\t> "); + fflush (stdout); + + buff[BUFSIZ - 1] = '\0'; + while (fgets (buff, BUFSIZ - 1, stdin) && buff[0]) + { + struct timespec d; + struct tm const *tm; + if (! parse_datetime (&d, buff, NULL)) + printf ("Bad format - couldn't convert.\n"); + else if (! (tm = localtime (&d.tv_sec))) + { + long int sec = d.tv_sec; + printf ("localtime (%ld) failed\n", sec); + } + else + { + int ns = d.tv_nsec; + printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n", + tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, ns); + } + printf ("\t> "); + fflush (stdout); + } + return 0; +} +#endif /* TEST */ diff --git a/gnu/pathmax.h b/gnu/pathmax.h new file mode 100644 index 00000000..6ecab59c --- /dev/null +++ b/gnu/pathmax.h @@ -0,0 +1,86 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Define PATH_MAX somehow. Requires sys/types.h. + Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009-2012 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#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. + <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html> + 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 <unistd.h> + +# include <limits.h> + +# 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 <sys/param.h> +# 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 __WIN32__) && ! defined __CYGWIN__ +/* The page "Naming Files, Paths, and Namespaces" on msdn.microsoft.com, + section "Maximum Path Length Limitation", + <http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx#maxpath> + 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 <stdio.h>, + - _MAX_PATH in <stdlib.h>, + - MAX_PATH in <windef.h>. + Undefine the original value, because mingw's <limits.h> gets it wrong. */ +# undef PATH_MAX +# define PATH_MAX 260 +# endif + +#endif /* _PATHMAX_H */ diff --git a/gnu/pipe-safer.c b/gnu/pipe-safer.c new file mode 100644 index 00000000..269af717 --- /dev/null +++ b/gnu/pipe-safer.c @@ -0,0 +1,58 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Invoke pipe, but avoid some glitches. + Copyright (C) 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#include <config.h> + +#include "unistd-safer.h" + +#include <unistd.h> +#include <errno.h> + +/* 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 HAVE_PIPE + if (pipe (fd) == 0) + { + int i; + for (i = 0; i < 2; i++) + { + fd[i] = fd_safer (fd[i]); + if (fd[i] < 0) + { + int e = errno; + close (fd[1 - i]); + errno = e; + return -1; + } + } + + return 0; + } +#else + errno = ENOSYS; +#endif + + return -1; +} diff --git a/gnu/printf-args.c b/gnu/printf-args.c new file mode 100644 index 00000000..6a66de78 --- /dev/null +++ b/gnu/printf-args.c @@ -0,0 +1,190 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Decomposed printf argument list. + Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2012 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* 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 <config.h> +#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; +#if HAVE_LONG_LONG_INT + case TYPE_LONGLONGINT: + ap->a.a_longlongint = va_arg (args, long long int); + break; + case TYPE_ULONGLONGINT: + ap->a.a_ulonglongint = va_arg (args, unsigned long long int); + break; +#endif + case TYPE_DOUBLE: + ap->a.a_double = va_arg (args, double); + break; + 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; +#if HAVE_LONG_LONG_INT + case TYPE_COUNT_LONGLONGINT_POINTER: + ap->a.a_count_longlongint_pointer = va_arg (args, long long int *); + break; +#endif +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + case TYPE_U8_STRING: + 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/gnu/printf-args.h b/gnu/printf-args.h new file mode 100644 index 00000000..b8b4fbd3 --- /dev/null +++ b/gnu/printf-args.h @@ -0,0 +1,161 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Decomposed printf argument list. + Copyright (C) 1999, 2002-2003, 2006-2007, 2011-2012 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#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 <stddef.h> + +/* Get wchar_t. */ +#if HAVE_WCHAR_T +# include <stddef.h> +#endif + +/* Get wint_t. */ +#if HAVE_WINT_T +# include <wchar.h> +#endif + +/* Get va_list. */ +#include <stdarg.h> + + +/* Argument types */ +typedef enum +{ + TYPE_NONE, + TYPE_SCHAR, + TYPE_UCHAR, + TYPE_SHORT, + TYPE_USHORT, + TYPE_INT, + TYPE_UINT, + TYPE_LONGINT, + TYPE_ULONGINT, +#if HAVE_LONG_LONG_INT + TYPE_LONGLONGINT, + TYPE_ULONGLONGINT, +#endif + 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 +#if HAVE_LONG_LONG_INT +, TYPE_COUNT_LONGLONGINT_POINTER +#endif +#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; +#if HAVE_LONG_LONG_INT + long long int a_longlongint; + unsigned long long int a_ulonglongint; +#endif + float a_float; + double a_double; + long double a_longdouble; + 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; +#if HAVE_LONG_LONG_INT + long long int * a_count_longlongint_pointer; +#endif +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + const uint8_t * a_u8_string; + 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/gnu/printf-parse.c b/gnu/printf-parse.c new file mode 100644 index 00000000..eef96e04 --- /dev/null +++ b/gnu/printf-parse.c @@ -0,0 +1,641 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Formatted output to strings. + Copyright (C) 1999-2000, 2002-2003, 2006-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* 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 <config.h> +#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 <stddef.h> + +/* Get intmax_t. */ +#if defined IN_LIBINTL || defined IN_LIBASPRINTF +# if HAVE_STDINT_H_WITH_UINTMAX +# include <stdint.h> +# endif +# if HAVE_INTTYPES_H_WITH_UINTMAX +# include <inttypes.h> +# endif +#else +# include <stdint.h> +#endif + +/* malloc(), realloc(), free(). */ +#include <stdlib.h> + +/* memcpy(). */ +#include <string.h> + +/* errno. */ +#include <errno.h> + +/* 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 MacOS 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 __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 HAVE_LONG_LONG_INT + /* If 'long long' exists and is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_LONGLONGINT; + else +#endif + /* If 'long long' exists and is the same as 'long', we parse + "lld" into TYPE_LONGINT. */ + if (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 HAVE_LONG_LONG_INT + /* If 'long long' exists and is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_ULONGLONGINT; + else +#endif + /* If 'unsigned long long' exists and is the same as + 'unsigned long', we parse "llu" into TYPE_ULONGINT. */ + if (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 HAVE_LONG_LONG_INT + /* If 'long long' exists and is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_COUNT_LONGLONGINT_POINTER; + else +#endif + /* If 'long long' exists and is the same as 'long', we parse + "lln" into TYPE_COUNT_LONGINT_POINTER. */ + if (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/gnu/printf-parse.h b/gnu/printf-parse.h new file mode 100644 index 00000000..5b9c2a9e --- /dev/null +++ b/gnu/printf-parse.h @@ -0,0 +1,196 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Parse printf format string. + Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2012 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#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 <features.h> /* 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/gnu/priv-set.c b/gnu/priv-set.c new file mode 100644 index 00000000..8ce9648c --- /dev/null +++ b/gnu/priv-set.c @@ -0,0 +1,144 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Query, remove, or restore a Solaris privilege. + + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. + + Written by David Bartley. */ + +#include <config.h> +#include "priv-set.h" + +#if HAVE_GETPPRIV && HAVE_PRIV_H + +# include <errno.h> +# include <stdbool.h> +# include <priv.h> + +/* Holds a (cached) copy of the effective set. */ +static priv_set_t *eff_set; + +/* Holds a set of privileges that we have removed. */ +static priv_set_t *rem_set; + +static bool initialized; + +static int +priv_set_initialize (void) +{ + if (! initialized) + { + eff_set = priv_allocset (); + if (!eff_set) + { + return -1; + } + rem_set = priv_allocset (); + if (!rem_set) + { + priv_freeset (eff_set); + return -1; + } + if (getppriv (PRIV_EFFECTIVE, eff_set) != 0) + { + priv_freeset (eff_set); + priv_freeset (rem_set); + return -1; + } + priv_emptyset (rem_set); + initialized = true; + } + + return 0; +} + + +/* Check if priv is in the effective set. + Returns 1 if priv is a member and 0 if not. + Returns -1 on error with errno set appropriately. */ +int +priv_set_ismember (const char *priv) +{ + if (! initialized && priv_set_initialize () != 0) + return -1; + + return priv_ismember (eff_set, priv); +} + + +/* Try to remove priv from the effective set. + Returns 0 if priv was removed. + Returns -1 on error with errno set appropriately. */ +int +priv_set_remove (const char *priv) +{ + if (! initialized && priv_set_initialize () != 0) + return -1; + + if (priv_ismember (eff_set, priv)) + { + /* priv_addset/priv_delset can only fail if priv is invalid, which is + checked above by the priv_ismember call. */ + priv_delset (eff_set, priv); + if (setppriv (PRIV_SET, PRIV_EFFECTIVE, eff_set) != 0) + { + priv_addset (eff_set, priv); + return -1; + } + priv_addset (rem_set, priv); + } + else + { + errno = EINVAL; + return -1; + } + + return 0; +} + + +/* Try to restore priv to the effective set. + Returns 0 if priv was re-added to the effective set (after being previously + removed by a call to priv_set_remove). + Returns -1 on error with errno set appropriately. */ +int +priv_set_restore (const char *priv) +{ + if (! initialized && priv_set_initialize () != 0) + return -1; + + if (priv_ismember (rem_set, priv)) + { + /* priv_addset/priv_delset can only fail if priv is invalid, which is + checked above by the priv_ismember call. */ + priv_addset (eff_set, priv); + if (setppriv (PRIV_SET, PRIV_EFFECTIVE, eff_set) != 0) + { + priv_delset (eff_set, priv); + return -1; + } + priv_delset (rem_set, priv); + } + else + { + errno = EINVAL; + return -1; + } + + return 0; +} + +#endif diff --git a/gnu/priv-set.h b/gnu/priv-set.h new file mode 100644 index 00000000..6f715a21 --- /dev/null +++ b/gnu/priv-set.h @@ -0,0 +1,52 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Query, remove, or restore a Solaris privilege. + + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. + + Written by David Bartley. */ + +#if HAVE_GETPPRIV && HAVE_PRIV_H + +# include <priv.h> + +int priv_set_ismember (const char *priv); +int priv_set_remove (const char *priv); +int priv_set_restore (const char *priv); + +static inline int priv_set_remove_linkdir (void) +{ + return priv_set_remove (PRIV_SYS_LINKDIR); +} + +static inline int priv_set_restore_linkdir (void) +{ + return priv_set_restore (PRIV_SYS_LINKDIR); +} + +#else + +static inline int priv_set_remove_linkdir (void) +{ + return -1; +} + +static inline int priv_set_restore_linkdir (void) +{ + return -1; +} + +#endif diff --git a/gnu/progname.c b/gnu/progname.c new file mode 100644 index 00000000..bc0691de --- /dev/null +++ b/gnu/progname.c @@ -0,0 +1,94 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Program name management. + Copyright (C) 2001-2003, 2005-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 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 <http://www.gnu.org/licenses/>. */ + + +#include <config.h> + +/* Specification. */ +#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */ +#include "progname.h" + +#include <errno.h> /* get program_invocation_name declaration */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +/* String containing name the program is called with. + To be initialized by main(). */ +const char *program_name = NULL; + +/* Set program_name, based on argv[0]. + argv0 must be a string allocated with indefinite extent, and must not be + modified after this call. */ +void +set_program_name (const char *argv0) +{ + /* libtool creates a temporary executable whose name is sometimes prefixed + with "lt-" (depends on the platform). It also makes argv[0] absolute. + But the name of the temporary executable is a detail that should not be + visible to the end user and to the test suite. + Remove this "<dirname>/.libs/" or "<dirname>/.libs/lt-" prefix here. */ + const char *slash; + const char *base; + + /* Sanity check. POSIX requires the invoking process to pass a non-NULL + argv[0]. */ + if (argv0 == NULL) + { + /* It's a bug in the invoking program. Help diagnosing it. */ + fputs ("A NULL argv[0] was passed through an exec system call.\n", + stderr); + abort (); + } + + slash = strrchr (argv0, '/'); + base = (slash != NULL ? slash + 1 : argv0); + if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0) + { + argv0 = base; + if (strncmp (base, "lt-", 3) == 0) + { + argv0 = base + 3; + /* On glibc systems, remove the "lt-" prefix from the variable + program_invocation_short_name. */ +#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME + program_invocation_short_name = (char *) argv0; +#endif + } + } + + /* But don't strip off a leading <dirname>/ in general, because when the user + runs + /some/hidden/place/bin/cp foo foo + he should get the error message + /some/hidden/place/bin/cp: `foo' and `foo' are the same file + not + cp: `foo' and `foo' are the same file + */ + + program_name = argv0; + + /* On glibc systems, the error() function comes from libc and uses the + variable program_invocation_name, not program_name. So set this variable + as well. */ +#if HAVE_DECL_PROGRAM_INVOCATION_NAME + program_invocation_name = (char *) argv0; +#endif +} diff --git a/gnu/progname.h b/gnu/progname.h new file mode 100644 index 00000000..a288ae38 --- /dev/null +++ b/gnu/progname.h @@ -0,0 +1,64 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Program name management. + Copyright (C) 2001-2004, 2006, 2009-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _PROGNAME_H +#define _PROGNAME_H + +/* Programs using this file should do the following in main(): + set_program_name (argv[0]); + */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* String containing name the program is called with. */ +extern const char *program_name; + +/* Set program_name, based on argv[0]. + argv0 must be a string allocated with indefinite extent, and must not be + modified after this call. */ +extern void set_program_name (const char *argv0); + +#if ENABLE_RELOCATABLE + +/* Set program_name, based on argv[0], and original installation prefix and + directory, for relocatability. */ +extern void set_program_name_and_installdir (const char *argv0, + const char *orig_installprefix, + const char *orig_installdir); +#undef set_program_name +#define set_program_name(ARG0) \ + set_program_name_and_installdir (ARG0, INSTALLPREFIX, INSTALLDIR) + +/* Return the full pathname of the current executable, based on the earlier + call to set_program_name_and_installdir. Return NULL if unknown. */ +extern char *get_full_program_name (void); + +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif /* _PROGNAME_H */ diff --git a/gnu/quote.c b/gnu/quote.c new file mode 100644 index 00000000..0d7d60f2 --- /dev/null +++ b/gnu/quote.c @@ -0,0 +1,42 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* quote.c - quote arguments for output + + Copyright (C) 1998-2001, 2003, 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert <eggert@twinsun.com> */ + +#include <config.h> + +#include "quotearg.h" +#include "quote.h" + +/* Return an unambiguous printable representation of NAME, + allocated in slot N, suitable for diagnostics. */ +char const * +quote_n (int n, char const *name) +{ + return quotearg_n_style (n, locale_quoting_style, name); +} + +/* Return an unambiguous printable representation of NAME, + suitable for diagnostics. */ +char const * +quote (char const *name) +{ + return quote_n (0, name); +} diff --git a/gnu/quote.h b/gnu/quote.h new file mode 100644 index 00000000..0bb5140e --- /dev/null +++ b/gnu/quote.h @@ -0,0 +1,22 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* quote.h - prototypes for quote.c + + Copyright (C) 1998-2001, 2003, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + + +char const *quote_n (int n, char const *name); +char const *quote (char const *name); diff --git a/gnu/quotearg.c b/gnu/quotearg.c new file mode 100644 index 00000000..2b91ec56 --- /dev/null +++ b/gnu/quotearg.c @@ -0,0 +1,930 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* quotearg.c - quote arguments for output + + Copyright (C) 1998-2002, 2004-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert <eggert@twinsun.com> */ + +/* 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 <config.h> + +#include "quotearg.h" + +#include "xalloc.h" +#include "c-strcaseeq.h" +#include "localcharset.h" + +#include <ctype.h> +#include <errno.h> +#include <limits.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> +#include <wctype.h> + +#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", + "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, + 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 *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 = { 0 }; + 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; + 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; + +#define STORE(c) \ + do \ + { \ + if (len < buffersize) \ + buffer[len] = (c); \ + len++; \ + } \ + while (0) + + switch (quoting_style) + { + case c_maybe_quoting_style: + quoting_style = c_quoting_style; + elide_outer_quotes = true; + /* Fall through. */ + 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 + <http://en.wikipedia.org/wiki/Quotation_marks_in_other_languages> + 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_quoting_style: + quoting_style = shell_always_quoting_style; + elide_outer_quotes = true; + /* Fall through. */ + case 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; + + if (backslash_escapes + && quote_string_len + && i + quote_string_len <= 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) + { + if (elide_outer_quotes) + goto force_outer_quoting_style; + STORE ('\\'); + /* 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. */ + if (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; + /* 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; + /* Fall through. */ + case '#': case '~': + if (i != 0) + break; + /* Fall through. */ + case ' ': + 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 '\'': + if (quoting_style == shell_always_quoting_style) + { + if (elide_outer_quotes) + goto force_outer_quoting_style; + STORE ('\''); + STORE ('\\'); + STORE ('\''); + } + 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. */ + 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)); + } + + 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) + { + if (elide_outer_quotes) + goto force_outer_quoting_style; + STORE ('\\'); + 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; + STORE (c); + c = arg[++i]; + } + + goto store_c; + } + } + } + + if (! ((backslash_escapes || elide_outer_quotes) + && quote_these_too + && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))) + && !is_right_quote) + goto store_c; + + store_escape: + if (elide_outer_quotes) + goto force_outer_quoting_style; + STORE ('\\'); + + store_c: + STORE (c); + } + + if (len == 0 && quoting_style == shell_always_quoting_style + && elide_outer_quotes) + goto force_outer_quoting_style; + + 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. */ + 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; +} + +/* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O). */ +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 unsigned int nslots = 1; +static struct slotvec slotvec0 = {sizeof slot0, slot0}; +static struct slotvec *slotvec = &slotvec0; + +void +quotearg_free (void) +{ + struct slotvec *sv = slotvec; + unsigned 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. N is deliberately declared with type "int" + 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; + + unsigned int n0 = n; + struct slotvec *sv = slotvec; + + if (n < 0) + abort (); + + if (nslots <= n0) + { + /* FIXME: technically, the type of n1 should be 'unsigned int', + but that evokes an unsuppressible warning from gcc-4.0.1 and + older. If gcc ever provides an option to suppress that warning, + revert to the original type, so that the test in xalloc_oversized + is once again performed only at compile time. */ + size_t n1 = n0 + 1; + bool preallocated = (sv == &slotvec0); + + if (xalloc_oversized (n1, sizeof *sv)) + xalloc_die (); + + slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv); + if (preallocated) + *sv = slotvec0; + memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv); + nslots = n1; + } + + { + 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_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); +} diff --git a/gnu/quotearg.h b/gnu/quotearg.h new file mode 100644 index 00000000..5f78cbb0 --- /dev/null +++ b/gnu/quotearg.h @@ -0,0 +1,393 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* quotearg.h - quote arguments for output + + Copyright (C) 1998-2002, 2004, 2006, 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert <eggert@twinsun.com> */ + +#ifndef QUOTEARG_H_ +# define QUOTEARG_H_ 1 + +# include <stddef.h> + +/* 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 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); + +/* Get the value of O's quoting style. If O is null, use the default. */ +enum quoting_style get_quoting_style (struct quoting_options *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 *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); + +/* 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); + +/* 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 (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/gnu/raise.c b/gnu/raise.c new file mode 100644 index 00000000..cc0e972e --- /dev/null +++ b/gnu/raise.c @@ -0,0 +1,81 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Provide a non-threads replacement for the POSIX raise function. + + Copyright (C) 2002-2003, 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering and Bruno Haible */ + +#include <config.h> + +/* Specification. */ +#include <signal.h> + +#if HAVE_RAISE +/* Native Windows platform. */ + +# include <errno.h> + +# include "msvc-inval.h" + +# undef raise + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static inline 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; +} +# else +# define raise_nothrow raise +# endif + +#else +/* An old Unix platform. */ + +# include <unistd.h> + +# define rpl_raise raise + +#endif + +int +rpl_raise (int sig) +{ +#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 +} diff --git a/gnu/rawmemchr.c b/gnu/rawmemchr.c new file mode 100644 index 00000000..000a3830 --- /dev/null +++ b/gnu/rawmemchr.c @@ -0,0 +1,138 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Searching in a string. + Copyright (C) 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <string.h> + +/* Find the first occurrence of C in S. */ +void * +rawmemchr (const void *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; + + /* 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 == 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 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 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. + + 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_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 == 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 != c) + char_ptr++; + return (void *) char_ptr; +} diff --git a/gnu/rawmemchr.valgrind b/gnu/rawmemchr.valgrind new file mode 100644 index 00000000..63639236 --- /dev/null +++ b/gnu/rawmemchr.valgrind @@ -0,0 +1,12 @@ +# Suppress a valgrind message about use of uninitialized memory in rawmemchr(). +# 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/gnu/read.c b/gnu/read.c new file mode 100644 index 00000000..eb2813cf --- /dev/null +++ b/gnu/read.c @@ -0,0 +1,87 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* POSIX compatible read() function. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2011. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# include <errno.h> +# include <io.h> + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include <windows.h> + +# include "msvc-inval.h" +# include "msvc-nothrow.h" + +# undef read + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static inline ssize_t +read_nothrow (int fd, void *buf, size_t count) +{ + ssize_t result; + + TRY_MSVC_INVAL + { + result = read (fd, buf, count); + } + CATCH_MSVC_INVAL + { + result = -1; + errno = EBADF; + } + DONE_MSVC_INVAL; + + return result; +} +# else +# define read_nothrow read +# endif + +ssize_t +rpl_read (int fd, void *buf, size_t count) +{ + ssize_t ret = read_nothrow (fd, buf, count); + +# if GNULIB_NONBLOCKING + if (ret < 0 + && GetLastError () == ERROR_NO_DATA) + { + HANDLE h = (HANDLE) _get_osfhandle (fd); + if (GetFileType (h) == FILE_TYPE_PIPE) + { + /* h is a pipe or socket. */ + DWORD state; + if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0) + && (state & PIPE_NOWAIT) != 0) + /* h is a pipe in non-blocking mode. + Change errno from EINVAL to EAGAIN. */ + errno = EAGAIN; + } + } +# endif + + return ret; +} + +#endif diff --git a/gnu/readdir.c b/gnu/readdir.c new file mode 100644 index 00000000..4d5f3106 --- /dev/null +++ b/gnu/readdir.c @@ -0,0 +1,100 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Read the next entry of a directory. + Copyright (C) 2011-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <dirent.h> + +#include <errno.h> +#include <stddef.h> + +#include "dirent-private.h" + +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" + <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html> + "." 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/gnu/readlink.c b/gnu/readlink.c new file mode 100644 index 00000000..4028fbce --- /dev/null +++ b/gnu/readlink.c @@ -0,0 +1,76 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Stub for readlink(). + Copyright (C) 2003-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#include <errno.h> +#include <string.h> +#include <sys/stat.h> + +#if !HAVE_READLINK + +/* readlink() substitute for systems that don't have a readlink() function, + such as DJGPP 2.03 and mingw32. */ + +ssize_t +readlink (const char *name, char *buf _GL_UNUSED, + size_t bufsize _GL_UNUSED) +{ + 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 (name, &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 (const char *name, char *buf, size_t bufsize) +{ +# if READLINK_TRAILING_SLASH_BUG + size_t len = strlen (name); + if (len && name[len - 1] == '/') + { + /* Even if name 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 (name, &st) == 0) + errno = EINVAL; + return -1; + } +# endif /* READLINK_TRAILING_SLASH_BUG */ + return readlink (name, buf, bufsize); +} + +#endif /* HAVE_READLINK */ diff --git a/gnu/readlinkat.c b/gnu/readlinkat.c new file mode 100644 index 00000000..bd4abe40 --- /dev/null +++ b/gnu/readlinkat.c @@ -0,0 +1,49 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Read a symlink relative to an open directory. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <unistd.h> + +/* Gnulib provides a readlink stub for mingw; use it for distinction + between EINVAL and ENOENT, rather than always failing with ENOSYS. */ + +/* POSIX 2008 says that unlike readlink, readlinkat returns 0 for + success instead of the buffer length. But this would render + readlinkat worthless since readlink does not guarantee a + NUL-terminated buffer. Assume this was a bug in POSIX. */ + +/* Read the contents of symlink FILE into buffer BUF of size LEN, in the + directory open on descriptor FD. If possible, do it without changing + the working directory. Otherwise, resort to using save_cwd/fchdir, + then readlink/restore_cwd. If either the save_cwd or the restore_cwd + fails, then give a diagnostic and exit nonzero. */ + +#define AT_FUNC_NAME readlinkat +#define AT_FUNC_F1 readlink +#define AT_FUNC_POST_FILE_PARAM_DECLS , char *buf, size_t len +#define AT_FUNC_POST_FILE_ARGS , buf, len +#define AT_FUNC_RESULT ssize_t +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS +#undef AT_FUNC_RESULT diff --git a/gnu/realloc.c b/gnu/realloc.c new file mode 100644 index 00000000..4df2e5d4 --- /dev/null +++ b/gnu/realloc.c @@ -0,0 +1,81 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* realloc() function that is glibc compatible. + + Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering and Bruno Haible */ + +#define _GL_USE_STDLIB_ALLOC 1 +#include <config.h> + +/* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h. */ +#ifdef realloc +# define NEED_REALLOC_GNU 1 +/* Whereas the gnulib module 'realloc-gnu' defines HAVE_REALLOC_GNU. */ +#elif GNULIB_REALLOC_GNU && !HAVE_REALLOC_GNU +# define NEED_REALLOC_GNU 1 +#endif + +/* Infer the properties of the system's malloc function. + The gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */ +#if GNULIB_MALLOC_GNU && HAVE_MALLOC_GNU +# define SYSTEM_MALLOC_GLIBC_COMPATIBLE 1 +#endif + +#include <stdlib.h> + +#include <errno.h> + +/* Change the size of an allocated block of memory P to N bytes, + with error checking. If N is zero, change it to 1. If P is NULL, + use malloc. */ + +void * +rpl_realloc (void *p, size_t n) +{ + void *result; + +#if NEED_REALLOC_GNU + if (n == 0) + { + n = 1; + + /* In theory realloc might fail, so don't rely on it to free. */ + free (p); + p = NULL; + } +#endif + + if (p == NULL) + { +#if GNULIB_REALLOC_GNU && !NEED_REALLOC_GNU && !SYSTEM_MALLOC_GLIBC_COMPATIBLE + if (n == 0) + n = 1; +#endif + result = malloc (n); + } + else + result = realloc (p, n); + +#if !HAVE_REALLOC_POSIX + if (result == NULL) + errno = ENOMEM; +#endif + + return result; +} diff --git a/gnu/ref-add.sin b/gnu/ref-add.sin new file mode 100644 index 00000000..d51d3bb2 --- /dev/null +++ b/gnu/ref-add.sin @@ -0,0 +1,30 @@ +# Add this package to a list of references stored in a text file. +# +# Copyright (C) 2000, 2009-2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Written by Bruno Haible <haible@clisp.cons.org>. +# +/^# Packages using this file: / { + s/# Packages using this file:// + ta + :a + s/ @PACKAGE@ / @PACKAGE@ / + tb + s/ $/ @PACKAGE@ / + :b + s/^/# Packages using this file:/ +} diff --git a/gnu/ref-del.sin b/gnu/ref-del.sin new file mode 100644 index 00000000..29543c31 --- /dev/null +++ b/gnu/ref-del.sin @@ -0,0 +1,25 @@ +# Remove this package from a list of references stored in a text file. +# +# Copyright (C) 2000, 2009-2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Written by Bruno Haible <haible@clisp.cons.org>. +# +/^# Packages using this file: / { + s/# Packages using this file:// + s/ @PACKAGE@ / / + s/^/# Packages using this file:/ +} diff --git a/gnu/regcomp.c b/gnu/regcomp.c new file mode 100644 index 00000000..174afc0b --- /dev/null +++ b/gnu/regcomp.c @@ -0,0 +1,3878 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Extended regular expression matching and search library. + Copyright (C) 2002-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +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); +#ifdef RE_ENABLE_I18N +static void free_charset (re_charset_t *cset); +#endif /* RE_ENABLE_I18N */ +static void free_workarea_compile (regex_t *preg); +static reg_errcode_t create_initial_state (re_dfa_t *dfa); +#ifdef RE_ENABLE_I18N +static void optimize_utf8 (re_dfa_t *dfa); +#endif +static reg_errcode_t analyze (regex_t *preg); +static reg_errcode_t preorder (bin_tree_t *root, + reg_errcode_t (fn (void *, bin_tree_t *)), + 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) internal_function; +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); +#ifdef RE_ENABLE_I18N +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 unsigned char *class_name, + reg_syntax_t syntax); +#else /* not RE_ENABLE_I18N */ +static reg_errcode_t build_equiv_class (bitset_t sbcset, + const unsigned char *name); +static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, + bitset_t sbcset, + const unsigned char *class_name, + reg_syntax_t syntax); +#endif /* not RE_ENABLE_I18N */ +static bin_tree_t *build_charclass_op (re_dfa_t *dfa, + RE_TRANSLATE_TYPE trans, + const unsigned char *class_name, + const unsigned 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. */ + +#ifdef _LIBC +const char * +re_compile_pattern (pattern, length, bufp) + const char *pattern; + size_t length; + struct re_pattern_buffer *bufp; +#else /* size_t might promote */ +const char * +re_compile_pattern (const char *pattern, size_t length, + struct re_pattern_buffer *bufp) +#endif +{ + reg_errcode_t ret; + + /* 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]); +} +#ifdef _LIBC +weak_alias (__re_compile_pattern, re_compile_pattern) +#endif + +/* Set by 're_set_syntax' to the current regexp syntax to recognize. Can + also be assigned to arbitrarily: each pattern buffer stores its own + 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 (syntax) + reg_syntax_t syntax; +{ + reg_syntax_t ret = re_syntax_options; + + re_syntax_options = syntax; + return ret; +} +#ifdef _LIBC +weak_alias (__re_set_syntax, re_set_syntax) +#endif + +int +re_compile_fastmap (bufp) + struct re_pattern_buffer *bufp; +{ + re_dfa_t *dfa = (re_dfa_t *) 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; +} +#ifdef _LIBC +weak_alias (__re_compile_fastmap, re_compile_fastmap) +#endif + +static inline void +__attribute ((always_inline)) +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 = (re_dfa_t *) 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); +#ifdef RE_ENABLE_I18N + 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]); + } +#endif + } + 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); + } + } +#ifdef RE_ENABLE_I18N + 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); + } + } + } + } +#endif /* RE_ENABLE_I18N */ + else if (type == OP_PERIOD +#ifdef RE_ENABLE_I18N + || type == OP_UTF8_PERIOD +#endif /* RE_ENABLE_I18N */ + || type == END_OF_RE) + { + 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 (preg, pattern, cflags) + 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 (BE (preg->fastmap == NULL, 0)) + 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 (BE (ret == REG_NOERROR, 1)) + /* 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; +} +#ifdef _LIBC +weak_alias (__regcomp, regcomp) +#endif + +/* Returns a message corresponding to an error code, ERRCODE, returned + from either regcomp or regexec. We don't use PREG here. */ + +#ifdef _LIBC +size_t +regerror (errcode, preg, errbuf, errbuf_size) + int errcode; + const regex_t *_Restrict_ preg; + char *_Restrict_ errbuf; + size_t errbuf_size; +#else /* size_t might promote */ +size_t +regerror (int errcode, const regex_t *_Restrict_ preg, + char *_Restrict_ errbuf, size_t errbuf_size) +#endif +{ + const char *msg; + size_t msg_size; + + if (BE (errcode < 0 + || errcode >= (int) (sizeof (__re_error_msgid_idx) + / sizeof (__re_error_msgid_idx[0])), 0)) + /* 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 (BE (errbuf_size != 0, 1)) + { + size_t cpy_size = msg_size; + if (BE (msg_size > errbuf_size, 0)) + { + cpy_size = errbuf_size - 1; + errbuf[cpy_size] = '\0'; + } + memcpy (errbuf, msg, cpy_size); + } + + return msg_size; +} +#ifdef _LIBC +weak_alias (__regerror, regerror) +#endif + + +#ifdef RE_ENABLE_I18N +/* This static array is used for the map to single-byte characters when + UTF-8 is used. Otherwise we would allocate memory just to initialize + it the same all the time. UTF-8 is the preferred encoding so this is + a worthwhile optimization. */ +static const bitset_t utf8_sb_map = +{ + /* Set the first 128 bits. */ +# 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); +#ifdef RE_ENABLE_I18N + if (dfa->sb_char != utf8_sb_map) + re_free (dfa->sb_char); +#endif + re_free (dfa->subexp_map); +#ifdef DEBUG + re_free (dfa->re_str); +#endif + + re_free (dfa); +} + + +/* Free dynamically allocated space used by PREG. */ + +void +regfree (preg) + regex_t *preg; +{ + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + if (BE (dfa != NULL, 1)) + free_dfa_content (dfa); + preg->buffer = NULL; + preg->allocated = 0; + + re_free (preg->fastmap); + preg->fastmap = NULL; + + re_free (preg->translate); + preg->translate = NULL; +} +#ifdef _LIBC +weak_alias (__regfree, regfree) +#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 + +/* 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 (s) + 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 = (char *) malloc (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 = (re_dfa_t *) preg->buffer; + if (BE (preg->allocated < sizeof (re_dfa_t), 0)) + { + /* 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 = (unsigned char *) dfa; + } + preg->used = sizeof (re_dfa_t); + + err = init_dfa (dfa, length); + if (BE (err != REG_NOERROR, 0)) + { + 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 + + __libc_lock_init (dfa->lock); + + err = re_string_construct (®exp, pattern, length, preg->translate, + (syntax & RE_ICASE) != 0, dfa); + if (BE (err != REG_NOERROR, 0)) + { + re_compile_internal_free_return: + free_workarea_compile (preg); + re_string_destruct (®exp); + 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 (BE (dfa->str_tree == NULL, 0)) + goto re_compile_internal_free_return; + + /* Analyze the tree and create the nfa. */ + err = analyze (preg); + if (BE (err != REG_NOERROR, 0)) + goto re_compile_internal_free_return; + +#ifdef RE_ENABLE_I18N + /* If possible, do searching in single byte encoding to speed things up. */ + if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL) + optimize_utf8 (dfa); +#endif + + /* Then create the initial state of the dfa. */ + err = create_initial_state (dfa); + + /* Release work areas. */ + free_workarea_compile (preg); + re_string_destruct (®exp); + + if (BE (err != REG_NOERROR, 0)) + { + 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 + char *codeset_name; +#endif +#ifdef RE_ENABLE_I18N + size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t)); +#else + size_t max_i18n_object_size = 0; +#endif + size_t max_object_size = + MAX (sizeof (struct re_state_table_entry), + MAX (sizeof (re_token_t), + 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 (BE (SIZE_MAX / max_object_size / 2 <= pat_len, 0)) + 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 (strcasecmp (codeset_name, "UTF-8") == 0 + || strcasecmp (codeset_name, "UTF8") == 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 + +#ifdef RE_ENABLE_I18N + 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 (BE (dfa->sb_char == NULL, 0)) + 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 + } + } + } +#endif + + if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0)) + 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 +internal_function +init_word_char (re_dfa_t *dfa) +{ + int i, j, ch; + dfa->word_ops_used = 1; + for (i = 0, ch = 0; 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 = (re_dfa_t *) 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 (BE (err != REG_NOERROR, 0)) + 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 (BE (dfa->init_state == NULL, 0)) + 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 (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL + || dfa->init_state_begbuf == NULL, 0)) + 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; +} + +#ifdef RE_ENABLE_I18N +/* If it is possible to do searching in single byte encoding instead of UTF-8 + to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change + DFA nodes where needed. */ + +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; +} +#endif + +/* Analyze the structure tree, and calculate "first", "next", "edest", + "eclosure", and "inveclosure". */ + +static reg_errcode_t +analyze (regex_t *preg) +{ + re_dfa_t *dfa = (re_dfa_t *) 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 (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL + || dfa->eclosures == NULL, 0)) + 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) + { + free (dfa->subexp_map); + dfa->subexp_map = NULL; + } + } + + ret = postorder (dfa->str_tree, lower_subexps, preg); + if (BE (ret != REG_NOERROR, 0)) + return ret; + ret = postorder (dfa->str_tree, calc_first, dfa); + if (BE (ret != REG_NOERROR, 0)) + return ret; + preorder (dfa->str_tree, calc_next, dfa); + ret = preorder (dfa->str_tree, link_nfa_nodes, dfa); + if (BE (ret != REG_NOERROR, 0)) + return ret; + ret = calc_eclosure (dfa); + if (BE (ret != REG_NOERROR, 0)) + 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 (BE (dfa->inveclosures == NULL, 0)) + 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 (BE (err != REG_NOERROR, 0)) + 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 (BE (err != REG_NOERROR, 0)) + 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 = (re_dfa_t *) 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 (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0)) + { + *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 (BE (node->node_idx == REG_MISSING, 0)) + 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: + 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; + assert (REG_VALID_INDEX (left)); + assert (REG_VALID_INDEX (right)); + 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: + 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 +internal_function +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 (BE (clone_dest == REG_MISSING, 0)) + return REG_ESPACE; + dfa->nexts[clone_node] = dfa->nexts[org_node]; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (BE (! ok, 0)) + 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 (BE (! ok, 0)) + return REG_ESPACE; + break; + } + /* In case the node has another constraint, append it. */ + constraint |= dfa->nodes[org_node].constraint; + clone_dest = duplicate_node (dfa, org_dest, constraint); + if (BE (clone_dest == REG_MISSING, 0)) + return REG_ESPACE; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (BE (! ok, 0)) + 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 == REG_MISSING) + { + /* There is no such duplicated node, create a new one. */ + reg_errcode_t err; + clone_dest = duplicate_node (dfa, org_dest, constraint); + if (BE (clone_dest == REG_MISSING, 0)) + return REG_ESPACE; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (BE (! ok, 0)) + return REG_ESPACE; + err = duplicate_node_closure (dfa, org_dest, clone_dest, + root_node, constraint); + if (BE (err != REG_NOERROR, 0)) + 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 (BE (! ok, 0)) + return REG_ESPACE; + } + + org_dest = dfa->edests[org_node].elems[1]; + clone_dest = duplicate_node (dfa, org_dest, constraint); + if (BE (clone_dest == REG_MISSING, 0)) + return REG_ESPACE; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (BE (! ok, 0)) + 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 REG_MISSING; /* Not found. */ +} + +/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT. + Return the index of the new node, or REG_MISSING if insufficient storage is + available. */ + +static Idx +duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint) +{ + Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]); + if (BE (dup_idx != REG_MISSING, 1)) + { + 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 (BE (! ok, 0)) + 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; +#ifdef DEBUG + assert (dfa->nodes_len > 0); +#endif + 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; + } + +#ifdef DEBUG + assert (dfa->eclosures[node_idx].nelem != REG_MISSING); +#endif + + /* If we have already calculated, skip it. */ + if (dfa->eclosures[node_idx].nelem != 0) + continue; + /* Calculate epsilon closure of 'node_idx'. */ + err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true); + if (BE (err != REG_NOERROR, 0)) + 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 ok; + bool incomplete = false; + err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); + if (BE (err != REG_NOERROR, 0)) + return err; + + /* This indicates that we are calculating this node now. + We reference this value to avoid infinite loop. */ + dfa->eclosures[node].nelem = REG_MISSING; + + /* 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 (BE (err != REG_NOERROR, 0)) + 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 == REG_MISSING) + { + 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 (BE (err != REG_NOERROR, 0)) + return err; + } + else + eclosure_elem = dfa->eclosures[edest]; + /* Merge the epsilon closure of 'edest'. */ + err = re_node_set_merge (&eclosure, &eclosure_elem); + if (BE (err != REG_NOERROR, 0)) + 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); + } + } + + /* An epsilon closure includes itself. */ + ok = re_node_set_insert (&eclosure, node); + if (BE (! ok, 0)) + return REG_ESPACE; + if (incomplete && !root) + dfa->eclosures[node].nelem = 0; + else + 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 +internal_function +fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax) +{ + re_string_skip_bytes (input, peek_token (result, input, syntax)); +} + +/* Peek a token from INPUT, and return the length of the token. + We must not use this function inside bracket expressions. */ + +static int +internal_function +peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) +{ + unsigned char c; + + 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; +#ifdef RE_ENABLE_I18N + 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; + } +#endif + 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; +#ifdef RE_ENABLE_I18N + 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 +#endif + 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; +#ifdef RE_ENABLE_I18N + if (input->mb_cur_max > 1) + { + wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input)); + token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; + } + else +#endif + token->word_char = IS_WORD_CHAR (token->opr.c); + + switch (c) + { + 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 +internal_function +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; + +#ifdef RE_ENABLE_I18N + if (input->mb_cur_max > 1 && + !re_string_first_byte (input, re_string_cur_idx (input))) + { + token->type = CHARACTER; + return 1; + } +#endif /* RE_ENABLE_I18N */ + + if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) + && re_string_cur_idx (input) + 1 < re_string_length (input)) + { + /* 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; + } + /* else fall through. */ + 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 is occured, ERR is set by error code, and return NULL. + This function build the following tree, from regular expression <reg_exp>: + CAT + / \ + / \ + <reg_exp> 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 = (re_dfa_t *) 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 (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + eor = create_tree (dfa, NULL, NULL, END_OF_RE); + if (tree != NULL) + root = create_tree (dfa, tree, eor, CONCAT); + else + root = eor; + if (BE (eor == NULL || root == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + return root; +} + +/* This function build the following tree, from regular expression + <branch1>|<branch2>: + ALT + / \ + / \ + <branch1> <branch2> + + 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 = (re_dfa_t *) preg->buffer; + bin_tree_t *tree, *branch = NULL; + tree = parse_branch (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + 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)) + { + branch = parse_branch (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && branch == NULL, 0)) + return NULL; + } + else + branch = NULL; + tree = create_tree (dfa, tree, branch, OP_ALT); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + } + return tree; +} + +/* This function build the following tree, from regular expression + <exp1><exp2>: + CAT + / \ + / \ + <exp1> <exp2> + + 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 = (re_dfa_t *) preg->buffer; + tree = parse_expression (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + + while (token->type != OP_ALT && token->type != END_OF_RE + && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) + { + expr = parse_expression (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && expr == NULL, 0)) + { + return NULL; + } + if (tree != NULL && expr != NULL) + { + tree = create_tree (dfa, tree, expr, CONCAT); + if (tree == NULL) + { + *err = REG_ESPACE; + return NULL; + } + } + 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 = (re_dfa_t *) preg->buffer; + bin_tree_t *tree; + switch (token->type) + { + case CHARACTER: + tree = create_token_tree (dfa, NULL, NULL, token); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } +#ifdef RE_ENABLE_I18N + 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 (BE (mbc_remain == NULL || tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + } + } +#endif + break; + case OP_OPEN_SUBEXP: + tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + break; + case OP_OPEN_BRACKET: + tree = parse_bracket_exp (regexp, dfa, token, syntax, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + break; + case OP_BACK_REF: + if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1)) + { + *err = REG_ESUBREG; + return NULL; + } + dfa->used_bkref_map |= 1 << token->opr.idx; + tree = create_token_tree (dfa, NULL, NULL, token); + if (BE (tree == NULL, 0)) + { + *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); + } + /* else fall through */ + case OP_CLOSE_SUBEXP: + if ((token->type == OP_CLOSE_SUBEXP) && + !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) + { + *err = REG_ERPAREN; + return NULL; + } + /* else fall through */ + 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 (BE (tree == NULL, 0)) + { + *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 (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + } + else + { + tree = create_token_tree (dfa, NULL, NULL, token); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + } + /* We must return here, since ANCHORs can't be followed + by repetition operators. + eg. RE"^*" is invalid or "<ANCHOR(^)><CHAR(*)>", + it must not be "<ANCHOR(^)><REPEAT(*)>". */ + fetch_token (token, regexp, syntax); + return tree; + case OP_PERIOD: + tree = create_token_tree (dfa, NULL, NULL, token); + if (BE (tree == NULL, 0)) + { + *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, + (const unsigned char *) "alnum", + (const unsigned char *) "_", + token->type == OP_NOTWORD, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + break; + case OP_SPACE: + case OP_NOTSPACE: + tree = build_charclass_op (dfa, regexp->trans, + (const unsigned char *) "space", + (const unsigned char *) "", + token->type == OP_NOTSPACE, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + break; + case OP_ALT: + case END_OF_RE: + return NULL; + case BACK_SLASH: + *err = REG_EESCAPE; + return NULL; + default: + /* Must not happen? */ +#ifdef DEBUG + assert (0); +#endif + 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) + { + tree = parse_dup_op (tree, regexp, dfa, token, syntax, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + /* In BRE consecutive duplications are not allowed. */ + if ((syntax & RE_CONTEXT_INVALID_DUP) + && (token->type == OP_DUP_ASTERISK + || token->type == OP_OPEN_DUP_NUM)) + { + *err = REG_BADRPT; + return NULL; + } + } + + return tree; +} + +/* This function build the following tree, from regular expression + (<reg_exp>): + SUBEXP + | + <reg_exp> +*/ + +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 = (re_dfa_t *) 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 (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0)) + *err = REG_EPAREN; + if (BE (*err != REG_NOERROR, 0)) + return NULL; + } + + if (cur_nsub <= '9' - '1') + dfa->completed_bkref_map |= 1 << cur_nsub; + + tree = create_tree (dfa, tree, NULL, SUBEXP); + if (BE (tree == NULL, 0)) + { + *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 == REG_MISSING) + { + if (token->type == CHARACTER && token->opr.c == ',') + start = 0; /* We treat "{,m}" as "{0,m}". */ + else + { + *err = REG_BADBR; /* <re>{} is invalid. */ + return NULL; + } + } + if (BE (start != REG_ERROR, 1)) + { + /* We treat "{n}" as "{n,n}". */ + end = ((token->type == OP_CLOSE_DUP_NUM) ? start + : ((token->type == CHARACTER && token->opr.c == ',') + ? fetch_number (regexp, token, syntax) : REG_ERROR)); + } + if (BE (start == REG_ERROR || end == REG_ERROR, 0)) + { + /* Invalid sequence. */ + if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0)) + { + 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 (BE ((end != REG_MISSING && start > end) + || token->type != OP_CLOSE_DUP_NUM, 0)) + { + /* First number greater than second. */ + *err = REG_BADBR; + return NULL; + } + } + else + { + start = (token->type == OP_DUP_PLUS) ? 1 : 0; + end = (token->type == OP_DUP_QUESTION) ? 1 : REG_MISSING; + } + + fetch_token (token, regexp, syntax); + + if (BE (elem == NULL, 0)) + return NULL; + if (BE (start == 0 && end == 0, 0)) + { + postorder (elem, free_tree, NULL); + return NULL; + } + + /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}". */ + if (BE (start > 0, 0)) + { + tree = elem; + for (i = 2; i <= start; ++i) + { + elem = duplicate_tree (elem, dfa); + tree = create_tree (dfa, tree, elem, CONCAT); + if (BE (elem == NULL || tree == NULL, 0)) + goto parse_dup_op_espace; + } + + if (start == end) + return tree; + + /* Duplicate ELEM before it is marked optional. */ + elem = duplicate_tree (elem, dfa); + old_tree = tree; + } + else + old_tree = NULL; + + if (elem->token.type == SUBEXP) + postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx); + + tree = create_tree (dfa, elem, NULL, + (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT)); + if (BE (tree == NULL, 0)) + goto parse_dup_op_espace; + +/* From gnulib's "intprops.h": + True if the arithmetic type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + + /* This loop is actually executed only when end != REG_MISSING, + to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?... We have + already created the start+1-th copy. */ + if (TYPE_SIGNED (Idx) || end != REG_MISSING) + for (i = start + 2; i <= end; ++i) + { + elem = duplicate_tree (elem, dfa); + tree = create_tree (dfa, tree, elem, CONCAT); + if (BE (elem == NULL || tree == NULL, 0)) + goto parse_dup_op_espace; + + tree = create_tree (dfa, tree, NULL, OP_ALT); + if (BE (tree == NULL, 0)) + 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 + /* Local function for parse_bracket_exp only used in case of NOT _LIBC. + Build the range expression which starts from START_ELEM, and ends + at END_ELEM. The result are written to MBCSET and SBCSET. + RANGE_ALLOC is the allocated size of mbcset->range_starts, and + mbcset->range_ends, is a pointer argument sinse we may + update it. */ + +static reg_errcode_t +internal_function +# ifdef RE_ENABLE_I18N +build_range_exp (const reg_syntax_t syntax, + bitset_t sbcset, + re_charset_t *mbcset, + Idx *range_alloc, + const bracket_elem_t *start_elem, + const bracket_elem_t *end_elem) +# else /* not RE_ENABLE_I18N */ +build_range_exp (const reg_syntax_t syntax, + bitset_t sbcset, + const bracket_elem_t *start_elem, + const bracket_elem_t *end_elem) +# endif /* not RE_ENABLE_I18N */ +{ + unsigned int start_ch, end_ch; + /* Equivalence Classes and Character Classes can't be a range start/end. */ + if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS + || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, + 0)) + return REG_ERANGE; + + /* We can handle no multi character collating elements without libc + support. */ + if (BE ((start_elem->type == COLL_SYM + && strlen ((char *) start_elem->opr.name) > 1) + || (end_elem->type == COLL_SYM + && strlen ((char *) end_elem->opr.name) > 1), 0)) + return REG_ECOLLATE; + +# ifdef RE_ENABLE_I18N + { + wchar_t wc; + wint_t start_wc; + wint_t end_wc; + wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'}; + + 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)); + start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM) + ? __btowc (start_ch) : start_elem->opr.wch); + end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM) + ? __btowc (end_ch) : end_elem->opr.wch); + if (start_wc == WEOF || end_wc == WEOF) + return REG_ECOLLATE; + cmp_buf[0] = start_wc; + cmp_buf[4] = end_wc; + + if (BE ((syntax & RE_NO_EMPTY_RANGES) + && wcscoll (cmp_buf, cmp_buf + 4) > 0, 0)) + return REG_ERANGE; + + /* Got valid collation sequence values, add them as a new entry. + However, for !_LIBC we have no collation elements: if the + character set is single byte, the single byte character set + that we build below suffices. parse_bracket_exp passes + no MBCSET if dfa->mb_cur_max == 1. */ + if (mbcset) + { + /* Check the space of the arrays. */ + if (BE (*range_alloc == mbcset->nranges, 0)) + { + /* There is not enough space, need realloc. */ + wchar_t *new_array_start, *new_array_end; + Idx new_nranges; + + /* +1 in case of mbcset->nranges is 0. */ + new_nranges = 2 * mbcset->nranges + 1; + /* Use realloc since mbcset->range_starts and mbcset->range_ends + are NULL if *range_alloc == 0. */ + new_array_start = re_realloc (mbcset->range_starts, wchar_t, + new_nranges); + new_array_end = re_realloc (mbcset->range_ends, wchar_t, + new_nranges); + + if (BE (new_array_start == NULL || new_array_end == NULL, 0)) + 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 (wc = 0; wc < SBC_MAX; ++wc) + { + cmp_buf[2] = wc; + if (wcscoll (cmp_buf, cmp_buf + 2) <= 0 + && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0) + bitset_set (sbcset, wc); + } + } +# else /* not RE_ENABLE_I18N */ + { + unsigned int ch; + start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch + : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] + : 0)); + end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch + : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] + : 0)); + if (start_ch > end_ch) + return REG_ERANGE; + /* Build the table for single byte characters. */ + for (ch = 0; ch < SBC_MAX; ++ch) + if (start_ch <= ch && ch <= end_ch) + bitset_set (sbcset, ch); + } +# endif /* not RE_ENABLE_I18N */ + return REG_NOERROR; +} +#endif /* not _LIBC */ + +#ifndef _LIBC +/* Helper function for parse_bracket_exp only used in case of NOT _LIBC.. + Build the collating element which is represented by NAME. + The result are written to MBCSET and SBCSET. + COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a + pointer argument since we may update it. */ + +static reg_errcode_t +internal_function +build_collating_symbol (bitset_t sbcset, +# ifdef RE_ENABLE_I18N + re_charset_t *mbcset, Idx *coll_sym_alloc, +# endif + const unsigned char *name) +{ + size_t name_len = strlen ((const char *) name); + if (BE (name_len != 1, 0)) + return REG_ECOLLATE; + else + { + bitset_set (sbcset, name[0]); + return REG_NOERROR; + } +} +#endif /* not _LIBC */ + +/* This function parse bracket expression like "[abc]", "[a-c]", + "[[.a-a.]]" etc. */ + +static bin_tree_t * +parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + reg_syntax_t syntax, reg_errcode_t *err) +{ +#ifdef _LIBC + const unsigned char *collseqmb; + const char *collseqwc; + uint32_t nrules; + int32_t table_size; + const int32_t *symb_table; + const unsigned char *extra; + + /* Local function for parse_bracket_exp used in _LIBC environement. + Seek the collating symbol entry correspondings to NAME. + Return the index of the symbol in the SYMB_TABLE. */ + + auto inline int32_t + __attribute ((always_inline)) + seek_collating_symbol_entry (name, name_len) + const unsigned char *name; + size_t name_len; + { + int32_t hash = elem_hash ((const char *) name, name_len); + int32_t elem = hash % table_size; + if (symb_table[2 * elem] != 0) + { + int32_t second = hash % (table_size - 2) + 1; + + do + { + /* First compare the hashing value. */ + if (symb_table[2 * elem] == hash + /* Compare the length of the name. */ + && name_len == extra[symb_table[2 * elem + 1]] + /* Compare the name. */ + && memcmp (name, &extra[symb_table[2 * elem + 1] + 1], + name_len) == 0) + { + /* Yep, this is the entry. */ + break; + } + + /* Next entry. */ + elem += second; + } + while (symb_table[2 * elem] != 0); + } + return elem; + } + + /* Local function for parse_bracket_exp used in _LIBC environment. + Look up the collation sequence value of BR_ELEM. + Return the value if succeeded, UINT_MAX otherwise. */ + + auto inline unsigned int + __attribute ((always_inline)) + lookup_collation_sequence_value (br_elem) + bracket_elem_t *br_elem; + { + 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); + if (symb_table[2 * elem] != 0) + { + /* We found the entry. */ + idx = symb_table[2 * elem + 1]; + /* Skip the name of collating element name. */ + idx += 1 + extra[idx]; + /* Skip the byte sequence of the collating element. */ + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + /* Skip the multibyte collation sequence value. */ + idx += sizeof (unsigned int); + /* Skip the wide char sequence of the collating element. */ + idx += sizeof (unsigned int) * + (1 + *(unsigned int *) (extra + idx)); + /* Return the collation sequence value. */ + return *(unsigned int *) (extra + idx); + } + else if (symb_table[2 * elem] == 0 && 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 environement. + 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 sinse we may + update it. */ + + auto inline reg_errcode_t + __attribute ((always_inline)) + build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem) + re_charset_t *mbcset; + Idx *range_alloc; + bitset_t sbcset; + bracket_elem_t *start_elem, *end_elem; + { + unsigned int ch; + uint32_t start_collseq; + uint32_t end_collseq; + + /* Equivalence Classes and Character Classes can't be a range + start/end. */ + if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS + || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, + 0)) + return REG_ERANGE; + + start_collseq = lookup_collation_sequence_value (start_elem); + end_collseq = lookup_collation_sequence_value (end_elem); + /* Check start/end collation sequence values. */ + if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0)) + return REG_ECOLLATE; + if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0)) + return REG_ERANGE; + + /* 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 (BE (*range_alloc == mbcset->nranges, 0)) + { + /* There is not enough space, need realloc. */ + uint32_t *new_array_start; + uint32_t *new_array_end; + Idx new_nranges; + + /* +1 in case of mbcset->nranges is 0. */ + new_nranges = 2 * mbcset->nranges + 1; + new_array_start = re_realloc (mbcset->range_starts, uint32_t, + new_nranges); + new_array_end = re_realloc (mbcset->range_ends, uint32_t, + new_nranges); + + if (BE (new_array_start == NULL || new_array_end == NULL, 0)) + return REG_ESPACE; + + 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 environement. + 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 sinse we may update it. */ + + auto inline reg_errcode_t + __attribute ((always_inline)) + build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name) + re_charset_t *mbcset; + Idx *coll_sym_alloc; + bitset_t sbcset; + const unsigned char *name; + { + int32_t elem, idx; + size_t name_len = strlen ((const char *) name); + if (nrules != 0) + { + elem = seek_collating_symbol_entry (name, name_len); + if (symb_table[2 * elem] != 0) + { + /* We found the entry. */ + idx = symb_table[2 * elem + 1]; + /* Skip the name of collating element name. */ + idx += 1 + extra[idx]; + } + else if (symb_table[2 * elem] == 0 && name_len == 1) + { + /* No valid character, treat it as a normal + character. */ + bitset_set (sbcset, name[0]); + return REG_NOERROR; + } + else + return REG_ECOLLATE; + + /* Got valid collation sequence, add it as a new entry. */ + /* Check the space of the arrays. */ + if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0)) + { + /* Not enough, realloc it. */ + /* +1 in case of mbcset->ncoll_syms is 0. */ + Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1; + /* Use realloc since mbcset->coll_syms is NULL + if *alloc == 0. */ + int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t, + new_coll_sym_alloc); + if (BE (new_coll_syms == NULL, 0)) + return REG_ESPACE; + mbcset->coll_syms = new_coll_syms; + *coll_sym_alloc = new_coll_sym_alloc; + } + mbcset->coll_syms[mbcset->ncoll_syms++] = idx; + return REG_NOERROR; + } + else + { + if (BE (name_len != 1, 0)) + return REG_ECOLLATE; + else + { + bitset_set (sbcset, name[0]); + return REG_NOERROR; + } + } + } +#endif + + re_token_t br_token; + re_bitset_ptr_t sbcset; +#ifdef RE_ENABLE_I18N + re_charset_t *mbcset; + Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; + Idx equiv_class_alloc = 0, char_class_alloc = 0; +#endif /* not RE_ENABLE_I18N */ + bool non_match = false; + bin_tree_t *work_tree; + int token_len; + 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 = (const int32_t *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_TABLEMB); + extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_EXTRAMB); + } +#endif + sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); +#ifdef RE_ENABLE_I18N + mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); +#endif /* RE_ENABLE_I18N */ +#ifdef RE_ENABLE_I18N + if (BE (sbcset == NULL || mbcset == NULL, 0)) +#else + if (BE (sbcset == NULL, 0)) +#endif /* RE_ENABLE_I18N */ + { + *err = REG_ESPACE; + return NULL; + } + + token_len = peek_token_bracket (token, regexp, syntax); + if (BE (token->type == END_OF_RE, 0)) + { + *err = REG_BADPAT; + goto parse_bracket_exp_free_return; + } + if (token->type == OP_NON_MATCH_LIST) + { +#ifdef RE_ENABLE_I18N + mbcset->non_match = 1; +#endif /* not RE_ENABLE_I18N */ + non_match = true; + if (syntax & RE_HAT_LISTS_NOT_NEWLINE) + bitset_set (sbcset, '\n'); + re_string_skip_bytes (regexp, token_len); /* Skip a token. */ + token_len = peek_token_bracket (token, regexp, syntax); + if (BE (token->type == END_OF_RE, 0)) + { + *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; + ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa, + syntax, first_round); + if (BE (ret != REG_NOERROR, 0)) + { + *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 (BE (token->type == END_OF_RE, 0)) + { + *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 (BE (token2.type == END_OF_RE, 0)) + { + *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; + ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2, + dfa, syntax, true); + if (BE (ret != REG_NOERROR, 0)) + { + *err = ret; + goto parse_bracket_exp_free_return; + } + + token_len = peek_token_bracket (token, regexp, syntax); + +#ifdef _LIBC + *err = build_range_exp (sbcset, mbcset, &range_alloc, + &start_elem, &end_elem); +#else +# ifdef RE_ENABLE_I18N + *err = build_range_exp (syntax, sbcset, + dfa->mb_cur_max > 1 ? mbcset : NULL, + &range_alloc, &start_elem, &end_elem); +# else + *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem); +# endif +#endif /* RE_ENABLE_I18N */ + if (BE (*err != REG_NOERROR, 0)) + goto parse_bracket_exp_free_return; + } + else + { + switch (start_elem.type) + { + case SB_CHAR: + bitset_set (sbcset, start_elem.opr.ch); + break; +#ifdef RE_ENABLE_I18N + case MB_CHAR: + /* Check whether the array has enough space. */ + if (BE (mbchar_alloc == mbcset->nmbchars, 0)) + { + 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 (BE (new_mbchars == NULL, 0)) + goto parse_bracket_exp_espace; + mbcset->mbchars = new_mbchars; + } + mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch; + break; +#endif /* RE_ENABLE_I18N */ + case EQUIV_CLASS: + *err = build_equiv_class (sbcset, +#ifdef RE_ENABLE_I18N + mbcset, &equiv_class_alloc, +#endif /* RE_ENABLE_I18N */ + start_elem.opr.name); + if (BE (*err != REG_NOERROR, 0)) + goto parse_bracket_exp_free_return; + break; + case COLL_SYM: + *err = build_collating_symbol (sbcset, +#ifdef RE_ENABLE_I18N + mbcset, &coll_sym_alloc, +#endif /* RE_ENABLE_I18N */ + start_elem.opr.name); + if (BE (*err != REG_NOERROR, 0)) + goto parse_bracket_exp_free_return; + break; + case CHAR_CLASS: + *err = build_charclass (regexp->trans, sbcset, +#ifdef RE_ENABLE_I18N + mbcset, &char_class_alloc, +#endif /* RE_ENABLE_I18N */ + start_elem.opr.name, syntax); + if (BE (*err != REG_NOERROR, 0)) + goto parse_bracket_exp_free_return; + break; + default: + assert (0); + break; + } + } + if (BE (token->type == END_OF_RE, 0)) + { + *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); + +#ifdef RE_ENABLE_I18N + /* 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 (BE (mbc_tree == NULL, 0)) + 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 (BE (work_tree == NULL, 0)) + goto parse_bracket_exp_espace; + + /* Then join them by ALT node. */ + work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT); + if (BE (work_tree == NULL, 0)) + goto parse_bracket_exp_espace; + } + else + { + re_free (sbcset); + work_tree = mbc_tree; + } + } + else +#endif /* not RE_ENABLE_I18N */ + { +#ifdef RE_ENABLE_I18N + free_charset (mbcset); +#endif + /* Build a tree for simple bracket. */ + br_token.type = SIMPLE_BRACKET; + br_token.opr.sbcset = sbcset; + work_tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (BE (work_tree == NULL, 0)) + goto parse_bracket_exp_espace; + } + return work_tree; + + parse_bracket_exp_espace: + *err = REG_ESPACE; + parse_bracket_exp_free_return: + re_free (sbcset); +#ifdef RE_ENABLE_I18N + free_charset (mbcset); +#endif /* RE_ENABLE_I18N */ + 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) +{ +#ifdef RE_ENABLE_I18N + int cur_char_size; + cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp)); + if (cur_char_size > 1) + { + 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; + } +#endif /* RE_ENABLE_I18N */ + re_string_skip_bytes (regexp, token_len); /* Skip a token. */ + if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS + || token->type == OP_OPEN_EQUIV_CLASS) + return parse_bracket_symbol (elem, regexp, token); + if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen) + { + /* 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 [:<character_class>:], [.<collating_element>.], and + [=<equivalent_class>=]. */ + +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 sinse we may update it. */ + +static reg_errcode_t +#ifdef RE_ENABLE_I18N +build_equiv_class (bitset_t sbcset, re_charset_t *mbcset, + Idx *equiv_class_alloc, const unsigned char *name) +#else /* not RE_ENABLE_I18N */ +build_equiv_class (bitset_t sbcset, const unsigned char *name) +#endif /* not RE_ENABLE_I18N */ +{ +#ifdef _LIBC + uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + 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; + /* This #include defines a local function! */ +# include <locale/weight.h> + /* 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 (&cp); + if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0)) + /* This isn't a valid character. */ + return REG_ECOLLATE; + + /* Build single byte matcing table for this equivalence class. */ + char_buf[1] = (unsigned char) '\0'; + len = weights[idx1 & 0xffffff]; + for (ch = 0; ch < SBC_MAX; ++ch) + { + char_buf[0] = ch; + cp = char_buf; + idx2 = findidx (&cp); +/* + 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)) + { + int cnt = 0; + + while (cnt <= len && + weights[(idx1 & 0xffffff) + 1 + cnt] + == weights[(idx2 & 0xffffff) + 1 + cnt]) + ++cnt; + + if (cnt > len) + bitset_set (sbcset, ch); + } + } + /* Check whether the array has enough space. */ + if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0)) + { + /* 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 (BE (new_equiv_classes == NULL, 0)) + 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 (BE (strlen ((const char *) name) != 1, 0)) + 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 sinse we may update it. */ + +static reg_errcode_t +#ifdef RE_ENABLE_I18N +build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, + re_charset_t *mbcset, Idx *char_class_alloc, + const unsigned char *class_name, reg_syntax_t syntax) +#else /* not RE_ENABLE_I18N */ +build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, + const unsigned char *class_name, reg_syntax_t syntax) +#endif /* not RE_ENABLE_I18N */ +{ + int i; + const char *name = (const char *) 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"; + +#ifdef RE_ENABLE_I18N + /* Check the space of the arrays. */ + if (BE (*char_class_alloc == mbcset->nchar_classes, 0)) + { + /* 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 (BE (new_char_classes == NULL, 0)) + return REG_ESPACE; + mbcset->char_classes = new_char_classes; + *char_class_alloc = new_char_class_alloc; + } + mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name); +#endif /* RE_ENABLE_I18N */ + +#define BUILD_CHARCLASS_LOOP(ctype_func) \ + do { \ + if (BE (trans != NULL, 0)) \ + { \ + 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 unsigned char *class_name, + const unsigned char *extra, bool non_match, + reg_errcode_t *err) +{ + re_bitset_ptr_t sbcset; +#ifdef RE_ENABLE_I18N + re_charset_t *mbcset; + Idx alloc = 0; +#endif /* not RE_ENABLE_I18N */ + reg_errcode_t ret; + re_token_t br_token; + bin_tree_t *tree; + + sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); +#ifdef RE_ENABLE_I18N + mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); +#endif /* RE_ENABLE_I18N */ + +#ifdef RE_ENABLE_I18N + if (BE (sbcset == NULL || mbcset == NULL, 0)) +#else /* not RE_ENABLE_I18N */ + if (BE (sbcset == NULL, 0)) +#endif /* not RE_ENABLE_I18N */ + { + *err = REG_ESPACE; + return NULL; + } + + if (non_match) + { +#ifdef RE_ENABLE_I18N + mbcset->non_match = 1; +#endif /* not RE_ENABLE_I18N */ + } + + /* We don't care the syntax in this case. */ + ret = build_charclass (trans, sbcset, +#ifdef RE_ENABLE_I18N + mbcset, &alloc, +#endif /* RE_ENABLE_I18N */ + class_name, 0); + + if (BE (ret != REG_NOERROR, 0)) + { + re_free (sbcset); +#ifdef RE_ENABLE_I18N + free_charset (mbcset); +#endif /* RE_ENABLE_I18N */ + *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); + +#ifdef RE_ENABLE_I18N + /* Ensure only single byte characters are set. */ + if (dfa->mb_cur_max > 1) + bitset_mask (sbcset, dfa->sb_char); +#endif + + /* Build a tree for simple bracket. */ + br_token.type = SIMPLE_BRACKET; + br_token.opr.sbcset = sbcset; + tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (BE (tree == NULL, 0)) + goto build_word_op_espace; + +#ifdef RE_ENABLE_I18N + 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 (BE (mbc_tree == NULL, 0)) + goto build_word_op_espace; + /* Then join them by ALT node. */ + tree = create_tree (dfa, tree, mbc_tree, OP_ALT); + if (BE (mbc_tree != NULL, 1)) + return tree; + } + else + { + free_charset (mbcset); + return tree; + } +#else /* not RE_ENABLE_I18N */ + return tree; +#endif /* not RE_ENABLE_I18N */ + + build_word_op_espace: + re_free (sbcset); +#ifdef RE_ENABLE_I18N + free_charset (mbcset); +#endif /* RE_ENABLE_I18N */ + *err = REG_ESPACE; + return NULL; +} + +/* This is intended for the expressions like "a{1,3}". + Fetch a number from 'input', and return the number. + Return REG_MISSING if the number field is empty like "{,1}". + Return REG_ERROR if an error occurred. */ + +static Idx +fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) +{ + Idx num = REG_MISSING; + unsigned char c; + while (1) + { + fetch_token (token, input, syntax); + c = token->opr.c; + if (BE (token->type == END_OF_RE, 0)) + return REG_ERROR; + if (token->type == OP_CLOSE_DUP_NUM || c == ',') + break; + num = ((token->type != CHARACTER || c < '0' || '9' < c + || num == REG_ERROR) + ? REG_ERROR + : ((num == REG_MISSING) ? c - '0' : num * 10 + c - '0')); + num = (num > RE_DUP_MAX) ? REG_ERROR : num; + } + return num; +} + +#ifdef RE_ENABLE_I18N +static void +free_charset (re_charset_t *cset) +{ + re_free (cset->mbchars); +# ifdef _LIBC + re_free (cset->coll_syms); + re_free (cset->equiv_classes); + re_free (cset->range_starts); + re_free (cset->range_ends); +# endif + re_free (cset->char_classes); + re_free (cset); +} +#endif /* RE_ENABLE_I18N */ + +/* Functions for binary tree operation. */ + +/* 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; + 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 (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0)) + { + 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 = REG_MISSING; + + 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 = (Idx) (long) 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) +{ +#ifdef RE_ENABLE_I18N + if (node->type == COMPLEX_BRACKET && node->duplicated == 0) + free_charset (node->opr.mbcset); + else +#endif /* RE_ENABLE_I18N */ + if (node->type == SIMPLE_BRACKET && node->duplicated == 0) + re_free (node->opr.sbcset); +} + +/* 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/gnu/regex.c b/gnu/regex.c new file mode 100644 index 00000000..eec515d7 --- /dev/null +++ b/gnu/regex.c @@ -0,0 +1,74 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Extended regular expression matching and search library. + Copyright (C) 2002-2003, 2005-2006, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Make sure noone 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 <regex.h>, which correctly + #undefs RE_DUP_MAX and sets it to the right value. */ +#include <limits.h> +#include <strings.h> + +#include <regex.h> +#include "regex_internal.h" + +#include "regex_internal.c" +#include "regcomp.c" +#include "regexec.c" + +/* Binary backward compatibility. */ +#if _LIBC +# include <shlib-compat.h> +# 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/gnu/regex.h b/gnu/regex.h new file mode 100644 index 00000000..a5ed2817 --- /dev/null +++ b/gnu/regex.h @@ -0,0 +1,677 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Definitions for data structures and routines for the regular + expression library. + Copyright (C) 1985, 1989-1993, 1995-1998, 2000-2003, 2005-2006, 2009-2012 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _REGEX_H +#define _REGEX_H 1 + +#include <sys/types.h> + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Define __USE_GNU_REGEX to declare GNU extensions that violate the + POSIX name space rules. */ +#undef __USE_GNU_REGEX +#if (defined _GNU_SOURCE \ + || (!defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE \ + && !defined _XOPEN_SOURCE)) +# define __USE_GNU_REGEX 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 the offset of a byte within a string. + For historical reasons POSIX 1003.1-2004 requires that regoff_t be + at least as wide as off_t. However, many common POSIX platforms set + regoff_t to the more-sensible ssize_t and the Open Group has + signalled its intention to change the requirement to be that + regoff_t be at least as wide as ptrdiff_t and ssize_t; see XBD ERN + 60 (2005-08-25). We don't know of any hosts where ssize_t or + ptrdiff_t is wider than ssize_t, so ssize_t is safe. */ +typedef ssize_t regoff_t; + +/* The type of nonnegative object indexes. Traditionally, GNU regex + uses 'int' for these. Code that uses __re_idx_t should work + regardless of whether the type is signed. */ +typedef size_t __re_idx_t; + +/* The type of object sizes. */ +typedef size_t __re_size_t; + +/* The type of object sizes, in places where the traditional code + uses unsigned long int. */ +typedef size_t __re_long_size_t; + +#else + +/* Use types that are binary-compatible with the traditional GNU regex + implementation, which mishandles strings longer than INT_MAX. */ + +typedef int regoff_t; +typedef int __re_idx_t; +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_REGEX + +/* 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 \<digit> matches <digit>. + If not set, then \<digit> 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 /* defined __USE_GNU_REGEX */ + +/* 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_REGEX +/* 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_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) + +# define RE_SYNTAX_GNU_AWK \ + ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ + & ~(RE_DOT_NOT_NULL | RE_INTERVALS | 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) + +# define RE_SYNTAX_GREP \ + (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ + | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ + | RE_NEWLINE_ALT) + +# define RE_SYNTAX_EGREP \ + (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ + | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ + | RE_NO_BK_VBAR) + +# define RE_SYNTAX_POSIX_EGREP \ + (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \ + | RE_INVALID_INTERVAL_ORD) + +/* 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]]] */ + +#endif /* defined __USE_GNU_REGEX */ + +#ifdef __USE_GNU_REGEX + +/* Maximum number of duplicates an interval can allow. POSIX-conforming + systems might define this in <limits.h>, but we want our + value, so remove any previous define. */ +# 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 - 2) / 10 - 1) 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 /* defined __USE_GNU_REGEX */ + + +/* 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, /* Compiled pattern bigger than 2^16 bytes. */ + _REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ +} reg_errcode_t; + +#ifdef _XOPEN_SOURCE +# 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 + +/* struct re_pattern_buffer normally uses member names like 'buffer' + that POSIX does not allow. In POSIX mode these members have names + with leading 're_' (e.g., 're_buffer'). */ +#ifdef __USE_GNU_REGEX +# define _REG_RE_NAME(id) id +# define _REG_RM_NAME(id) id +#else +# define _REG_RE_NAME(id) re_##id +# define _REG_RM_NAME(id) rm_##id +#endif + +/* The user can specify the type of the re_translate member by + defining the macro RE_TRANSLATE_TYPE, which defaults to unsigned + char *. This pollutes the POSIX name space, so in POSIX mode just + use unsigned char *. */ +#ifdef __USE_GNU_REGEX +# ifndef RE_TRANSLATE_TYPE +# define RE_TRANSLATE_TYPE unsigned char * +# endif +# define REG_TRANSLATE_TYPE RE_TRANSLATE_TYPE +#else +# define REG_TRANSLATE_TYPE unsigned char * +#endif + +/* This data structure represents a compiled pattern. Before calling + the pattern compiler, the fields 'buffer', 'allocated', 'fastmap', + 'translate', and 'no_sub' can be set. After the pattern has been + compiled, the 're_nsub' field is available. All other fields are + private to the regex routines. */ + +struct re_pattern_buffer +{ + /* Space that holds the compiled pattern. It is declared as + 'unsigned char *' because its elements are sometimes used as + array indexes. */ + unsigned char *_REG_RE_NAME (buffer); + + /* Number of bytes to which 'buffer' points. */ + __re_long_size_t _REG_RE_NAME (allocated); + + /* Number of bytes actually used in 'buffer'. */ + __re_long_size_t _REG_RE_NAME (used); + + /* Syntax setting with which the pattern was compiled. */ + reg_syntax_t _REG_RE_NAME (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 *_REG_RE_NAME (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. */ + REG_TRANSLATE_TYPE _REG_RE_NAME (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 int _REG_RE_NAME (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_REGEX +# define REGS_UNALLOCATED 0 +# define REGS_REALLOCATE 1 +# define REGS_FIXED 2 +#endif + unsigned int _REG_RE_NAME (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 int _REG_RE_NAME (fastmap_accurate) : 1; + + /* If set, 're_match_2' does not return information about + subexpressions. */ + unsigned int _REG_RE_NAME (no_sub) : 1; + + /* If set, a beginning-of-line anchor doesn't match at the beginning + of the string. */ + unsigned int _REG_RE_NAME (not_bol) : 1; + + /* Similarly for an end-of-line anchor. */ + unsigned int _REG_RE_NAME (not_eol) : 1; + + /* If true, an anchor at a newline matches. */ + unsigned int _REG_RE_NAME (newline_anchor) : 1; + +/* [[[end pattern_buffer]]] */ +}; + +typedef struct re_pattern_buffer regex_t; + +/* 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 _REG_RM_NAME (num_regs); + regoff_t *_REG_RM_NAME (start); + regoff_t *_REG_RM_NAME (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. */ +#if !defined RE_NREGS && defined __USE_GNU_REGEX +# define RE_NREGS 30 +#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. */ + +/* 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. */ +extern const char *re_compile_pattern (const char *__pattern, size_t __length, + struct re_pattern_buffer *__buffer); + + +/* 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, __re_idx_t __length, + __re_idx_t __start, regoff_t __range, + struct re_registers *__regs); + + +/* Like 're_search', but search in the concatenation of STRING1 and + STRING2. Also, stop searching at index START + STOP. */ +extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, + const char *__string1, __re_idx_t __length1, + const char *__string2, __re_idx_t __length2, + __re_idx_t __start, regoff_t __range, + struct re_registers *__regs, + __re_idx_t __stop); + + +/* Like 're_search', but return how many characters in STRING the regexp + in BUFFER matched, starting at position START. */ +extern regoff_t re_match (struct re_pattern_buffer *__buffer, + const char *__string, __re_idx_t __length, + __re_idx_t __start, struct re_registers *__regs); + + +/* Relates to 're_match' as 're_search_2' relates to 're_search'. */ +extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, + const char *__string1, __re_idx_t __length1, + const char *__string2, __re_idx_t __length2, + __re_idx_t __start, struct re_registers *__regs, + __re_idx_t __stop); + + +/* 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); + +#if defined _REGEX_RE_COMP || defined _LIBC +# ifndef _CRAY +/* 4.2 bsd compatibility. */ +extern char *re_comp (const char *); +extern int re_exec (const char *); +# endif +#endif + +/* GCC 2.95 and later have "__restrict"; C99 compilers have + "restrict", and "configure" may have defined "restrict". + Other compilers use __restrict, __restrict__, and _Restrict, and + 'configure' might #define 'restrict' to those words, so pick a + different name. */ +#ifndef _Restrict_ +# if 199901L <= __STDC_VERSION__ +# define _Restrict_ restrict +# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__) +# define _Restrict_ __restrict +# else +# define _Restrict_ +# endif +#endif +/* gcc 3.1 and up support the [restrict] syntax. Don't trust + sys/cdefs.h's definition of __restrict_arr, though, as it + mishandles gcc -ansi -pedantic. */ +#ifndef _Restrict_arr_ +# if ((199901L <= __STDC_VERSION__ \ + || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) \ + && !defined __STRICT_ANSI__)) \ + && !defined __GNUG__) +# 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_], + int __eflags); + +extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, + char *_Restrict_ __errbuf, size_t __errbuf_size); + +extern void regfree (regex_t *__preg); + + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* regex.h */ diff --git a/gnu/regex_internal.c b/gnu/regex_internal.c new file mode 100644 index 00000000..76de230c --- /dev/null +++ b/gnu/regex_internal.c @@ -0,0 +1,1743 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Extended regular expression matching and search library. + Copyright (C) 2002-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +static void re_string_construct_common (const char *str, Idx len, + re_string_t *pstr, + RE_TRANSLATE_TYPE trans, bool icase, + const re_dfa_t *dfa) internal_function; +static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, + const re_node_set *nodes, + re_hashval_t hash) internal_function; +static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, + const re_node_set *nodes, + unsigned int context, + re_hashval_t hash) internal_function; + +/* 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 +internal_function __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 (BE (ret != REG_NOERROR, 0)) + 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 +internal_function __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 (BE (ret != REG_NOERROR, 0)) + return ret; + } + pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; + + if (icase) + { +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + { + while (1) + { + ret = build_wcs_upper_buffer (pstr); + if (BE (ret != REG_NOERROR, 0)) + return ret; + if (pstr->valid_raw_len >= len) + break; + if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max) + break; + ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); + if (BE (ret != REG_NOERROR, 0)) + return ret; + } + } + else +#endif /* RE_ENABLE_I18N */ + build_upper_buffer (pstr); + } + else + { +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + build_wcs_buffer (pstr); + else +#endif /* RE_ENABLE_I18N */ + { + if (trans != NULL) + re_string_translate_buffer (pstr); + 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 +internal_function __attribute_warn_unused_result__ +re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) +{ +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + { + wint_t *new_wcs; + + /* Avoid overflow. */ + size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx)); + if (BE (SIZE_MAX / max_object_size < new_buf_len, 0)) + return REG_ESPACE; + + new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len); + if (BE (new_wcs == NULL, 0)) + return REG_ESPACE; + pstr->wcs = new_wcs; + if (pstr->offsets != NULL) + { + Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len); + if (BE (new_offsets == NULL, 0)) + return REG_ESPACE; + pstr->offsets = new_offsets; + } + } +#endif /* RE_ENABLE_I18N */ + if (pstr->mbs_allocated) + { + unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, + new_buf_len); + if (BE (new_mbs == NULL, 0)) + return REG_ESPACE; + pstr->mbs = new_mbs; + } + pstr->bufs_len = new_buf_len; + return REG_NOERROR; +} + + +static void +internal_function +re_string_construct_common (const char *str, Idx len, re_string_t *pstr, + RE_TRANSLATE_TYPE trans, bool icase, + const re_dfa_t *dfa) +{ + 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; +} + +#ifdef RE_ENABLE_I18N + +/* Build wide character buffer PSTR->WCS. + If the byte sequence of the string are: + <mb1>(0), <mb1>(1), <mb2>(0), <mb2>(1), <sb3> + Then wide character buffer will be: + <wc1> , WEOF , <wc2> , WEOF , <wc3> + 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 +internal_function +build_wcs_buffer (re_string_t *pstr) +{ +#ifdef _LIBC + unsigned char buf[MB_LEN_MAX]; + assert (MB_LEN_MAX >= pstr->mb_cur_max); +#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 (BE (pstr->trans != NULL, 0)) + { + 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 (BE (mbclen == (size_t) -2, 0)) + { + /* The buffer doesn't have enough space, finish to build. */ + pstr->cur_state = prev_st; + break; + } + else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0)) + { + /* We treat these cases as a singlebyte character. */ + mbclen = 1; + wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; + if (BE (pstr->trans != NULL, 0)) + wc = pstr->trans[wc]; + pstr->cur_state = prev_st; + } + + /* 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 +internal_function __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]; + assert (MB_LEN_MAX >= pstr->mb_cur_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; + + if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]) + && mbsinit (&pstr->cur_state)) + { + /* In case of a singlebyte character. */ + pstr->mbs[byte_idx] + = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]); + /* The next step uses the assumption that wchar_t is encoded + ASCII-safe: all ASCII values can be converted like this. */ + pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx]; + ++byte_idx; + continue; + } + + 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 (BE (mbclen < (size_t) -2, 1)) + { + wchar_t wcu = wc; + if (iswlower (wc)) + { + size_t mbcdlen; + + wcu = towupper (wc); + mbcdlen = wcrtomb (buf, wcu, &prev_st); + if (BE (mbclen == mbcdlen, 1)) + 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) + { + /* It is an invalid character or '\0'. Just use the byte. */ + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; + pstr->mbs[byte_idx] = ch; + /* And also cast it to wide char. */ + pstr->wcs[byte_idx++] = (wchar_t) ch; + if (BE (mbclen == (size_t) -1, 0)) + 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 (BE (pstr->trans != NULL, 0)) + { + 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 (BE (mbclen < (size_t) -2, 1)) + { + wchar_t wcu = wc; + if (iswlower (wc)) + { + size_t mbcdlen; + + wcu = towupper (wc); + mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st); + if (BE (mbclen == mbcdlen, 1)) + 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 (BE (pstr->offsets_needed != 0, 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) + { + /* It is an invalid character or '\0'. Just use the byte. */ + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; + + if (BE (pstr->trans != NULL, 0)) + ch = pstr->trans [ch]; + pstr->mbs[byte_idx] = ch; + + if (BE (pstr->offsets_needed != 0, 0)) + pstr->offsets[byte_idx] = src_idx; + ++src_idx; + + /* And also cast it to wide char. */ + pstr->wcs[byte_idx++] = (wchar_t) ch; + if (BE (mbclen == (size_t) -1, 0)) + 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 +internal_function +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; + remain_len = pstr->len - rawbuf_idx; + prev_st = pstr->cur_state; + mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, + remain_len, &pstr->cur_state); + if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0)) + { + /* 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; +} +#endif /* RE_ENABLE_I18N */ + +/* Build the buffer PSTR->MBS, and apply the translation if we need. + This function is used in case of REG_ICASE. */ + +static void +internal_function +build_upper_buffer (re_string_t *pstr) +{ + Idx char_idx, end_idx; + 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 (BE (pstr->trans != NULL, 0)) + ch = pstr->trans[ch]; + if (islower (ch)) + pstr->mbs[char_idx] = toupper (ch); + else + pstr->mbs[char_idx] = ch; + } + pstr->valid_len = char_idx; + pstr->valid_raw_len = char_idx; +} + +/* Apply TRANS to the buffer in PSTR. */ + +static void +internal_function +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 +internal_function __attribute_warn_unused_result__ +re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) +{ + Idx offset; + + if (BE (pstr->raw_mbs_idx <= idx, 0)) + offset = idx - pstr->raw_mbs_idx; + else + { + /* Reset buffer. */ +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); +#endif /* RE_ENABLE_I18N */ + pstr->len = pstr->raw_len; + pstr->stop = pstr->raw_stop; + pstr->valid_len = 0; + 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 (BE (offset != 0, 1)) + { + /* Should the already checked characters be kept? */ + if (BE (offset < pstr->valid_raw_len, 1)) + { + /* Yes, move them to the front of the buffer. */ +#ifdef RE_ENABLE_I18N + if (BE (pstr->offsets_needed, 0)) + { + 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 +#endif + { + pstr->tip_context = re_string_context_at (pstr, offset - 1, + eflags); +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + memmove (pstr->wcs, pstr->wcs + offset, + (pstr->valid_len - offset) * sizeof (wint_t)); +#endif /* RE_ENABLE_I18N */ + if (BE (pstr->mbs_allocated, 0)) + memmove (pstr->mbs, pstr->mbs + offset, + pstr->valid_len - offset); + pstr->valid_len -= offset; + pstr->valid_raw_len -= offset; +#if DEBUG + assert (pstr->valid_len > 0); +#endif + } + } + else + { +#ifdef RE_ENABLE_I18N + /* No, skip all characters until IDX. */ + Idx prev_valid_len = pstr->valid_len; + + if (BE (pstr->offsets_needed, 0)) + { + pstr->len = pstr->raw_len - idx + offset; + pstr->stop = pstr->raw_stop - idx + offset; + pstr->offsets_needed = 0; + } +#endif + pstr->valid_len = 0; +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + { + Idx wcs_idx; + 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) && BE (pstr->trans == NULL, 1)) + { + 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; + size_t mbclen; + +#if 0 /* dead code: buf is set but never used */ + unsigned char buf[6]; + if (BE (pstr->trans != NULL, 0)) + { + int i = mlen < 6 ? mlen : 6; + while (--i >= 0) + buf[i] = pstr->trans[p[i]]; + } +#endif + /* 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 *) p, 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 = ((BE (pstr->word_ops_used != 0, 0) + && IS_WIDE_WORD_CHAR (wc)) + ? CONTEXT_WORD + : ((IS_WIDE_NEWLINE (wc) + && pstr->newline_anchor) + ? CONTEXT_NEWLINE : 0)); + if (BE (pstr->valid_len, 0)) + { + 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 +#endif /* RE_ENABLE_I18N */ + { + 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 (!BE (pstr->mbs_allocated, 0)) + pstr->mbs += offset; + } + pstr->raw_mbs_idx = idx; + pstr->len -= offset; + pstr->stop -= offset; + + /* Then build the buffers. */ +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + { + if (pstr->icase) + { + reg_errcode_t ret = build_wcs_upper_buffer (pstr); + if (BE (ret != REG_NOERROR, 0)) + return ret; + } + else + build_wcs_buffer (pstr); + } + else +#endif /* RE_ENABLE_I18N */ + if (BE (pstr->mbs_allocated, 0)) + { + 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 +internal_function __attribute ((pure)) +re_string_peek_byte_case (const re_string_t *pstr, Idx idx) +{ + int ch; + Idx off; + + /* Handle the common (easiest) cases first. */ + if (BE (!pstr->mbs_allocated, 1)) + return re_string_peek_byte (pstr, idx); + +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1 + && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx)) + return re_string_peek_byte (pstr, idx); +#endif + + off = pstr->cur_idx + idx; +#ifdef RE_ENABLE_I18N + if (pstr->offsets_needed) + off = pstr->offsets[off]; +#endif + + ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; + +#ifdef RE_ENABLE_I18N + /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I + this function returns CAPITAL LETTER I instead of first byte of + DOTLESS SMALL LETTER I. The latter would confuse the parser, + since peek_byte_case doesn't advance cur_idx in any way. */ + if (pstr->offsets_needed && !isascii (ch)) + return re_string_peek_byte (pstr, idx); +#endif + + return ch; +} + +static unsigned char +internal_function __attribute ((pure)) +re_string_fetch_byte_case (re_string_t *pstr) +{ + if (BE (!pstr->mbs_allocated, 1)) + return re_string_fetch_byte (pstr); + +#ifdef RE_ENABLE_I18N + 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; + } +#endif + + return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++]; +} + +static void +internal_function +re_string_destruct (re_string_t *pstr) +{ +#ifdef RE_ENABLE_I18N + re_free (pstr->wcs); + re_free (pstr->offsets); +#endif /* RE_ENABLE_I18N */ + if (pstr->mbs_allocated) + re_free (pstr->mbs); +} + +/* Return the context at IDX in INPUT. */ + +static unsigned int +internal_function +re_string_context_at (const re_string_t *input, Idx idx, int eflags) +{ + int c; + if (BE (! REG_VALID_INDEX (idx), 0)) + /* In this case, we use the value stored in input->tip_context, + since we can't know the character in input->mbs[-1] here. */ + return input->tip_context; + if (BE (idx == input->len, 0)) + return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF + : CONTEXT_NEWLINE | CONTEXT_ENDBUF); +#ifdef RE_ENABLE_I18N + if (input->mb_cur_max > 1) + { + wint_t wc; + Idx wc_idx = idx; + while(input->wcs[wc_idx] == WEOF) + { +#ifdef DEBUG + /* It must not happen. */ + assert (REG_VALID_INDEX (wc_idx)); +#endif + --wc_idx; + if (! REG_VALID_INDEX (wc_idx)) + return input->tip_context; + } + wc = input->wcs[wc_idx]; + if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc)) + return CONTEXT_WORD; + return (IS_WIDE_NEWLINE (wc) && input->newline_anchor + ? CONTEXT_NEWLINE : 0); + } + else +#endif + { + c = re_string_byte_at (input, idx); + if (bitset_contain (input->word_char, c)) + return CONTEXT_WORD; + return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0; + } +} + +/* Functions for set operation. */ + +static reg_errcode_t +internal_function __attribute_warn_unused_result__ +re_node_set_alloc (re_node_set *set, Idx size) +{ + set->alloc = size; + set->nelem = 0; + set->elems = re_malloc (Idx, size); + if (BE (set->elems == NULL, 0)) + return REG_ESPACE; + return REG_NOERROR; +} + +static reg_errcode_t +internal_function __attribute_warn_unused_result__ +re_node_set_init_1 (re_node_set *set, Idx elem) +{ + set->alloc = 1; + set->nelem = 1; + set->elems = re_malloc (Idx, 1); + if (BE (set->elems == NULL, 0)) + { + set->alloc = set->nelem = 0; + return REG_ESPACE; + } + set->elems[0] = elem; + return REG_NOERROR; +} + +static reg_errcode_t +internal_function __attribute_warn_unused_result__ +re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) +{ + set->alloc = 2; + set->elems = re_malloc (Idx, 2); + if (BE (set->elems == NULL, 0)) + 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 +internal_function __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 (BE (dest->elems == NULL, 0)) + { + 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 +internal_function __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 (BE (new_elems == NULL, 0)) + 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 (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1]) + --id; + + if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1]) + dest->elems[--sbase] = src1->elems[i1]; + + if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2)) + break; + } + + /* Lower the highest of the two items. */ + else if (src1->elems[i1] < src2->elems[i2]) + { + if (! REG_VALID_INDEX (--i2)) + break; + } + else + { + if (! REG_VALID_INDEX (--i1)) + 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 && REG_VALID_INDEX (id)) + 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 (! REG_VALID_INDEX (--id)) + 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 +internal_function __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 (BE (dest->elems == NULL, 0)) + 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 +internal_function __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 (BE (new_buffer == NULL, 0)) + return REG_ESPACE; + dest->elems = new_buffer; + dest->alloc = new_alloc; + } + + if (BE (dest->nelem == 0, 0)) + { + 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; + REG_VALID_INDEX (is) && REG_VALID_INDEX (id); ) + { + 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 (REG_VALID_INDEX (is)) + { + /* 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 (! REG_VALID_INDEX (--id)) + { + /* 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 +internal_function __attribute_warn_unused_result__ +re_node_set_insert (re_node_set *set, Idx elem) +{ + Idx idx; + /* In case the set is empty. */ + if (set->alloc == 0) + return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1); + + if (BE (set->nelem, 0) == 0) + { + /* We already guaranteed above that set->alloc != 0. */ + 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 (BE (new_elems == NULL, 0)) + 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]) + { + idx = 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]; + } + + /* 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 +internal_function __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 (BE (new_elems == NULL, 0)) + 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 +internal_function __attribute ((pure)) +re_node_set_compare (const re_node_set *set1, const re_node_set *set2) +{ + Idx i; + if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) + return false; + for (i = set1->nelem ; REG_VALID_INDEX (--i) ; ) + 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 +internal_function __attribute ((pure)) +re_node_set_contains (const re_node_set *set, Idx elem) +{ + __re_size_t idx, right, mid; + if (! REG_VALID_NONZERO_INDEX (set->nelem)) + 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 +internal_function +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 REG_MISSING if an error occurred. */ + +static Idx +internal_function +re_dfa_add_node (re_dfa_t *dfa, re_token_t token) +{ + if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) + { + 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; + size_t max_object_size = + MAX (sizeof (re_token_t), + MAX (sizeof (re_node_set), + sizeof (Idx))); + + /* Avoid overflows. */ + if (BE (SIZE_MAX / 2 / max_object_size < dfa->nodes_alloc, 0)) + return REG_MISSING; + + new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc); + if (BE (new_nodes == NULL, 0)) + return REG_MISSING; + 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 (BE (new_nexts == NULL || new_indices == NULL + || new_edests == NULL || new_eclosures == NULL, 0)) + return REG_MISSING; + dfa->nexts = new_nexts; + dfa->org_indices = new_indices; + dfa->edests = new_edests; + dfa->eclosures = new_eclosures; + dfa->nodes_alloc = new_nodes_alloc; + } + dfa->nodes[dfa->nodes_len] = token; + dfa->nodes[dfa->nodes_len].constraint = 0; +#ifdef RE_ENABLE_I18N + { + int type = token.type; + dfa->nodes[dfa->nodes_len].accept_mb = + (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET; + } +#endif + dfa->nexts[dfa->nodes_len] = REG_MISSING; + 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 inline re_hashval_t +internal_function +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 * +internal_function __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; +#ifdef lint + /* Suppress bogus uninitialized-variable warnings. */ + *err = REG_NOERROR; +#endif + if (BE (nodes->nelem == 0, 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 (BE (new_state == NULL, 0)) + *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 * +internal_function __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; +#ifdef 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 (BE (new_state == NULL, 0)) + *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 (BE (err != REG_NOERROR, 0)) + 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 (BE (! re_node_set_insert_last (&newstate->non_eps_nodes, elem), 0)) + return REG_ESPACE; + } + + spot = dfa->state_table + (hash & dfa->state_hash_mask); + if (BE (spot->alloc <= spot->num, 0)) + { + Idx new_alloc = 2 * spot->num + 2; + re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *, + new_alloc); + if (BE (new_array == NULL, 0)) + 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 independ of contexts. + Return the new state if succeeded, otherwise return NULL. */ + +static re_dfastate_t * +internal_function __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 (BE (newstate == NULL, 0)) + return NULL; + err = re_node_set_init_copy (&newstate->nodes, nodes); + if (BE (err != REG_NOERROR, 0)) + { + 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; +#ifdef RE_ENABLE_I18N + newstate->accept_mb |= node->accept_mb; +#endif /* RE_ENABLE_I18N */ + + /* If the state has the halt node, the state is a halt state. */ + if (type == END_OF_RE) + 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 (BE (err != REG_NOERROR, 0)) + { + 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 * +internal_function __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 (BE (newstate == NULL, 0)) + return NULL; + err = re_node_set_init_copy (&newstate->nodes, nodes); + if (BE (err != REG_NOERROR, 0)) + { + 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; +#ifdef RE_ENABLE_I18N + newstate->accept_mb |= node->accept_mb; +#endif /* RE_ENABLE_I18N */ + + /* If the state has the halt node, the state is a halt state. */ + if (type == END_OF_RE) + newstate->halt = 1; + else if (type == OP_BACK_REF) + newstate->has_backref = 1; + + if (constraint) + { + if (newstate->entrance_nodes == &newstate->nodes) + { + newstate->entrance_nodes = re_malloc (re_node_set, 1); + if (BE (newstate->entrance_nodes == NULL, 0)) + { + free_state (newstate); + return NULL; + } + if (re_node_set_init_copy (newstate->entrance_nodes, nodes) + != REG_NOERROR) + 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 (BE (err != REG_NOERROR, 0)) + { + free_state (newstate); + newstate = NULL; + } + return newstate; +} diff --git a/gnu/regex_internal.h b/gnu/regex_internal.h new file mode 100644 index 00000000..1d7b5e50 --- /dev/null +++ b/gnu/regex_internal.h @@ -0,0 +1,868 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Extended regular expression matching and search library. + Copyright (C) 2002-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _REGEX_INTERNAL_H +#define _REGEX_INTERNAL_H 1 + +#include <assert.h> +#include <ctype.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <langinfo.h> +#ifndef _LIBC +# include "localcharset.h" +#endif +#include <locale.h> + +#include <wchar.h> +#include <wctype.h> +#include <stdint.h> +#if defined _LIBC +# include <bits/libc-lock.h> +#else +# define __libc_lock_init(NAME) do { } while (0) +# define __libc_lock_lock(NAME) do { } while (0) +# define __libc_lock_unlock(NAME) do { } while (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 + +#ifdef _LIBC +# ifndef _RE_DEFINE_LOCALE_FUNCTIONS +# define _RE_DEFINE_LOCALE_FUNCTIONS 1 +# include <locale/localeinfo.h> +# include <locale/elem-hash.h> +# include <locale/coll-lookup.h> +# endif +#endif + +/* This is for other GNU distributions with internationalized messages. */ +#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include <libintl.h> +# ifdef _LIBC +# undef gettext +# define gettext(msgid) \ + INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES) +# endif +#else +# define gettext(msgid) (msgid) +#endif + +#ifndef gettext_noop +/* This define is so xgettext can find the internationalizable + strings. */ +# define gettext_noop(String) String +#endif + +/* For loser systems without the definition. */ +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + +#if (defined MB_CUR_MAX && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC +# define RE_ENABLE_I18N +#endif + +#if __GNUC__ >= 3 +# define BE(expr, val) __builtin_expect (expr, val) +#else +# define BE(expr, val) (expr) +# ifdef _LIBC +# define inline +# endif +#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 +# define __wctype wctype +# define __iswctype iswctype +# define __btowc btowc +# define __wcrtomb wcrtomb +# define __mbrtowc mbrtowc +# define __regfree regfree +# define attribute_hidden +#endif /* not _LIBC */ + +#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +# define __attribute(arg) __attribute__ (arg) +#else +# define __attribute(arg) +#endif + +typedef __re_idx_t Idx; + +/* Special return value for failure to match. */ +#define REG_MISSING ((Idx) -1) + +/* Special return value for internal error. */ +#define REG_ERROR ((Idx) -2) + +/* Test whether N is a valid index, and is not one of the above. */ +#ifdef _REGEX_LARGE_OFFSETS +# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR) +#else +# define REG_VALID_INDEX(n) (0 <= (n)) +#endif + +/* Test whether N is a valid nonzero index. */ +#ifdef _REGEX_LARGE_OFFSETS +# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1)) +#else +# define REG_VALID_NONZERO_INDEX(n) (0 < (n)) +#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. For portability to hosts with + padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)'; + instead, deduce it directly from BITSET_WORD_MAX. Avoid + greater-than-32-bit integers and unconditional shifts by more than + 31 bits, as they're not portable. */ +#if BITSET_WORD_MAX == 0xffffffffUL +# define BITSET_WORD_BITS 32 +#elif BITSET_WORD_MAX >> 31 >> 4 == 1 +# define BITSET_WORD_BITS 36 +#elif BITSET_WORD_MAX >> 31 >> 16 == 1 +# define BITSET_WORD_BITS 48 +#elif BITSET_WORD_MAX >> 31 >> 28 == 1 +# define BITSET_WORD_BITS 60 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1 +# define BITSET_WORD_BITS 64 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1 +# define BITSET_WORD_BITS 72 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1 +# define BITSET_WORD_BITS 128 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1 +# define BITSET_WORD_BITS 256 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1 +# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */ +# if BITSET_WORD_BITS <= SBC_MAX +# error "Invalid SBC_MAX" +# endif +#else +# error "Add case for new bitset_word_t size" +#endif + +/* Number of 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, +#ifdef RE_ENABLE_I18N + COMPLEX_BRACKET = 6, + OP_UTF8_PERIOD = 7, +#endif /* RE_ENABLE_I18N */ + + /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used + when the debugger shows values of this enum type. */ +#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; + +#ifdef RE_ENABLE_I18N +typedef struct +{ + /* Multibyte characters. */ + wchar_t *mbchars; + + /* Collating symbols. */ +# ifdef _LIBC + int32_t *coll_syms; +# endif + + /* Equivalence classes. */ +# ifdef _LIBC + int32_t *equiv_classes; +# endif + + /* Range expressions. */ +# ifdef _LIBC + uint32_t *range_starts; + uint32_t *range_ends; +# else /* not _LIBC */ + wchar_t *range_starts; + wchar_t *range_ends; +# endif /* not _LIBC */ + + /* 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; +#endif /* RE_ENABLE_I18N */ + +typedef struct +{ + union + { + unsigned char c; /* for CHARACTER */ + re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */ +#ifdef RE_ENABLE_I18N + re_charset_t *mbcset; /* for COMPLEX_BRACKET */ +#endif /* RE_ENABLE_I18N */ + Idx idx; /* for BACK_REF */ + re_context_type ctx_type; /* for ANCHOR */ + } opr; +#if __GNUC__ >= 2 && !defined __STRICT_ANSI__ + 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; +#ifdef RE_ENABLE_I18N + unsigned int accept_mb : 1; + /* These 2 bits can be moved into the union if needed (e.g. if running out + of bits; move opr.c to opr.c.c and move the flags to opr.c.flags). */ + unsigned int mb_partial : 1; +#endif + unsigned int word_char : 1; +} re_token_t; + +#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; +#ifdef RE_ENABLE_I18N + /* Store the wide character string which is corresponding to MBS. */ + wint_t *wcs; + Idx *offsets; + mbstate_t cur_state; +#endif + /* Index in RAW_MBS. Each character mbs[i] corresponds to + raw_mbs[raw_mbs_idx + i]. */ + Idx raw_mbs_idx; + /* 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 internal_function +#endif + +static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, + Idx new_buf_len) + internal_function; +#ifdef RE_ENABLE_I18N +static void build_wcs_buffer (re_string_t *pstr) internal_function; +static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr) + internal_function; +#endif /* RE_ENABLE_I18N */ +static void build_upper_buffer (re_string_t *pstr) internal_function; +static void re_string_translate_buffer (re_string_t *pstr) internal_function; +static unsigned int re_string_context_at (const re_string_t *input, Idx idx, + int eflags) + internal_function __attribute ((pure)); +#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)) + +#include <alloca.h> + +#ifndef _LIBC +# if HAVE_ALLOCA +/* The OS usually guarantees only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + allocate anything larger than 4096 bytes. Also care for the possibility + of a few compiler-allocated temporary stack slots. */ +# define __libc_use_alloca(n) ((n) < 4032) +# else +/* alloca is implemented with malloc, so just use malloc. */ +# define __libc_use_alloca(n) 0 +# undef alloca +# define alloca(n) malloc (n) +# endif +#endif + +#ifndef MAX +# define MAX(a,b) ((a) < (b) ? (b) : (a)) +#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; + char more; + char unused; + unsigned short int eps_reachable_subexps_map; +}; + +typedef struct +{ + /* The string object corresponding to the input string. */ + re_string_t input; +#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) + const re_dfa_t *const dfa; +#else + const re_dfa_t *dfa; +#endif + /* EFLAGS of the argument of regexec. */ + int eflags; + /* Where the matching ends. */ + 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 +#ifdef _LIBC + __libc_lock_define (, lock) +#endif +}; + +#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; + + +/* Inline 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]; +} + +#ifdef RE_ENABLE_I18N +/* Inline functions for re_string. */ +static inline int +internal_function __attribute ((pure)) +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 inline wint_t +internal_function __attribute ((pure)) +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]; +} + +static int +internal_function __attribute ((pure)) +re_string_elem_size_at (const re_string_t *pstr, Idx idx) +{ +# ifdef _LIBC + const unsigned char *p, *extra; + const int32_t *table, *indirect; + int32_t tmp; +# include <locale/weight.h> + 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; + tmp = findidx (&p); + return p - pstr->mbs - idx; + } + else +# endif /* _LIBC */ + return 1; +} +#endif /* RE_ENABLE_I18N */ + +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_MINOR__ +# define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +# else +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + +#if __GNUC_PREREQ (3,4) +# undef __attribute_warn_unused_result__ +# define __attribute_warn_unused_result__ \ + __attribute__ ((__warn_unused_result__)) +#else +# define __attribute_warn_unused_result__ /* empty */ +#endif + +#endif /* _REGEX_INTERNAL_H */ diff --git a/gnu/regexec.c b/gnu/regexec.c new file mode 100644 index 00000000..fc6a6d66 --- /dev/null +++ b/gnu/regexec.c @@ -0,0 +1,4419 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Extended regular expression matching and search library. + Copyright (C) 2002-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, + Idx n) internal_function; +static void match_ctx_clean (re_match_context_t *mctx) internal_function; +static void match_ctx_free (re_match_context_t *cache) internal_function; +static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node, + Idx str_idx, Idx from, Idx to) + internal_function; +static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) + internal_function; +static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node, + Idx str_idx) internal_function; +static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop, + Idx node, Idx str_idx) + internal_function; +static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, + re_dfastate_t **limited_sts, Idx last_node, + Idx last_str_idx) + internal_function; +static reg_errcode_t re_search_internal (const regex_t *preg, + const char *string, Idx length, + Idx start, Idx last_start, Idx stop, + size_t nmatch, regmatch_t pmatch[], + int eflags) internal_function; +static regoff_t re_search_2_stub (struct re_pattern_buffer *bufp, + const char *string1, Idx length1, + const char *string2, Idx length2, + Idx start, regoff_t range, + struct re_registers *regs, + Idx stop, bool ret_len) internal_function; +static regoff_t re_search_stub (struct re_pattern_buffer *bufp, + const char *string, Idx length, Idx start, + regoff_t range, Idx stop, + struct re_registers *regs, + bool ret_len) internal_function; +static unsigned int re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, + Idx nregs, int regs_allocated) + internal_function; +static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx) + internal_function; +static Idx check_matching (re_match_context_t *mctx, bool fl_longest_match, + Idx *p_match_first) internal_function; +static Idx check_halt_state_context (const re_match_context_t *mctx, + const re_dfastate_t *state, Idx idx) + internal_function; +static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, + regmatch_t *prev_idx_match, Idx cur_node, + Idx cur_idx, Idx nmatch) internal_function; +static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs, + Idx str_idx, Idx dest_node, Idx nregs, + regmatch_t *regs, + re_node_set *eps_via_nodes) + internal_function; +static reg_errcode_t set_regs (const regex_t *preg, + const re_match_context_t *mctx, + size_t nmatch, regmatch_t *pmatch, + bool fl_backtrack) internal_function; +static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs) + internal_function; + +#ifdef RE_ENABLE_I18N +static int sift_states_iter_mb (const re_match_context_t *mctx, + re_sift_context_t *sctx, + Idx node_idx, Idx str_idx, Idx max_str_idx) + internal_function; +#endif /* RE_ENABLE_I18N */ +static reg_errcode_t sift_states_backward (const re_match_context_t *mctx, + re_sift_context_t *sctx) + internal_function; +static reg_errcode_t build_sifted_states (const re_match_context_t *mctx, + re_sift_context_t *sctx, Idx str_idx, + re_node_set *cur_dest) + internal_function; +static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx, + re_sift_context_t *sctx, + Idx str_idx, + re_node_set *dest_nodes) + internal_function; +static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa, + re_node_set *dest_nodes, + const re_node_set *candidates) + internal_function; +static bool check_dst_limits (const re_match_context_t *mctx, + const re_node_set *limits, + Idx dst_node, Idx dst_idx, Idx src_node, + Idx src_idx) internal_function; +static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, + int boundaries, Idx subexp_idx, + Idx from_node, Idx bkref_idx) + internal_function; +static int check_dst_limits_calc_pos (const re_match_context_t *mctx, + Idx limit, Idx subexp_idx, + Idx node, Idx str_idx, + Idx bkref_idx) internal_function; +static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa, + re_node_set *dest_nodes, + const re_node_set *candidates, + re_node_set *limits, + struct re_backref_cache_entry *bkref_ents, + Idx str_idx) internal_function; +static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx, + re_sift_context_t *sctx, + Idx str_idx, const re_node_set *candidates) + internal_function; +static reg_errcode_t merge_state_array (const re_dfa_t *dfa, + re_dfastate_t **dst, + re_dfastate_t **src, Idx num) + internal_function; +static re_dfastate_t *find_recover_state (reg_errcode_t *err, + re_match_context_t *mctx) internal_function; +static re_dfastate_t *transit_state (reg_errcode_t *err, + re_match_context_t *mctx, + re_dfastate_t *state) internal_function; +static re_dfastate_t *merge_state_with_log (reg_errcode_t *err, + re_match_context_t *mctx, + re_dfastate_t *next_state) + internal_function; +static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx, + re_node_set *cur_nodes, + Idx str_idx) internal_function; +#if 0 +static re_dfastate_t *transit_state_sb (reg_errcode_t *err, + re_match_context_t *mctx, + re_dfastate_t *pstate) + internal_function; +#endif +#ifdef RE_ENABLE_I18N +static reg_errcode_t transit_state_mb (re_match_context_t *mctx, + re_dfastate_t *pstate) + internal_function; +#endif /* RE_ENABLE_I18N */ +static reg_errcode_t transit_state_bkref (re_match_context_t *mctx, + const re_node_set *nodes) + internal_function; +static reg_errcode_t get_subexp (re_match_context_t *mctx, + Idx bkref_node, Idx bkref_str_idx) + internal_function; +static reg_errcode_t get_subexp_sub (re_match_context_t *mctx, + const re_sub_match_top_t *sub_top, + re_sub_match_last_t *sub_last, + Idx bkref_node, Idx bkref_str) + internal_function; +static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, + Idx subexp_idx, int type) internal_function; +static reg_errcode_t check_arrival (re_match_context_t *mctx, + state_array_t *path, Idx top_node, + Idx top_str, Idx last_node, Idx last_str, + int type) internal_function; +static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx, + Idx str_idx, + re_node_set *cur_nodes, + re_node_set *next_nodes) + internal_function; +static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa, + re_node_set *cur_nodes, + Idx ex_subexp, int type) + internal_function; +static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa, + re_node_set *dst_nodes, + Idx target, Idx ex_subexp, + int type) internal_function; +static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx, + re_node_set *cur_nodes, Idx cur_str, + Idx subexp_num, int type) + internal_function; +static bool build_trtable (const re_dfa_t *dfa, + re_dfastate_t *state) internal_function; +#ifdef RE_ENABLE_I18N +static int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, + const re_string_t *input, Idx idx) + internal_function; +# ifdef _LIBC +static unsigned int find_collation_sequence_value (const unsigned char *mbs, + size_t name_len) + internal_function; +# endif /* _LIBC */ +#endif /* RE_ENABLE_I18N */ +static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa, + const re_dfastate_t *state, + re_node_set *states_node, + bitset_t *states_ch) internal_function; +static bool check_node_accept (const re_match_context_t *mctx, + const re_token_t *node, Idx idx) + internal_function; +static reg_errcode_t extend_buffers (re_match_context_t *mctx) + internal_function; + +/* 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. + + We return 0 if we find a match and REG_NOMATCH if not. */ + +int +regexec (preg, string, nmatch, pmatch, eflags) + const regex_t *_Restrict_ preg; + const char *_Restrict_ string; + size_t nmatch; + regmatch_t pmatch[_Restrict_arr_]; + int eflags; +{ + reg_errcode_t err; + Idx start, length; +#ifdef _LIBC + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; +#endif + + 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); + } + + __libc_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); + __libc_lock_unlock (dfa->lock); + return err != REG_NOERROR; +} + +#ifdef _LIBC +# include <shlib-compat.h> +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[], 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. Return value -1 means no + match was found and -2 indicates an internal error. */ + +regoff_t +re_match (bufp, string, length, start, regs) + struct re_pattern_buffer *bufp; + const char *string; + Idx length, start; + struct re_registers *regs; +{ + 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 (bufp, string, length, start, range, regs) + struct re_pattern_buffer *bufp; + const char *string; + Idx length, 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 (bufp, string1, length1, string2, length2, start, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + Idx length1, length2, start, stop; + struct re_registers *regs; +{ + 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 (bufp, string1, length1, string2, length2, start, range, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + Idx length1, length2, start, stop; + regoff_t range; + struct re_registers *regs; +{ + 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 +internal_function +re_search_2_stub (struct re_pattern_buffer *bufp, + const char *string1, Idx length1, + const char *string2, Idx length2, + Idx start, regoff_t range, struct re_registers *regs, + Idx stop, bool ret_len) +{ + const char *str; + regoff_t rval; + Idx len = length1 + length2; + char *s = NULL; + + if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0)) + return -2; + + /* Concatenate the strings. */ + if (length2 > 0) + if (length1 > 0) + { + s = re_malloc (char, len); + + if (BE (s == NULL, 0)) + 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 +internal_function +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; +#ifdef _LIBC + re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; +#endif + Idx last_start = start + range; + + /* Check for out-of-range. */ + if (BE (start < 0 || start > length, 0)) + return -1; + if (BE (length < last_start || (0 <= range && last_start < start), 0)) + last_start = length; + else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0)) + last_start = 0; + + __libc_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 (BE (bufp->no_sub, 0)) + regs = NULL; + + /* We need at least 1 register. */ + if (regs == NULL) + nregs = 1; + else if (BE (bufp->regs_allocated == REGS_FIXED + && regs->num_regs <= bufp->re_nsub, 0)) + { + nregs = regs->num_regs; + if (BE (nregs < 1, 0)) + { + /* Nothing can be copied to regs. */ + regs = NULL; + nregs = 1; + } + } + else + nregs = bufp->re_nsub + 1; + pmatch = re_malloc (regmatch_t, nregs); + if (BE (pmatch == NULL, 0)) + { + 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 ther regs with -1's when no match was found. */ + if (result != REG_NOERROR) + rval = -1; + 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 (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0)) + rval = -2; + } + + if (BE (rval == 0, 1)) + { + if (ret_len) + { + assert (pmatch[0].rm_so == start); + rval = pmatch[0].rm_eo - start; + } + else + rval = pmatch[0].rm_so; + } + re_free (pmatch); + out: + __libc_lock_unlock (dfa->lock); + return rval; +} + +static unsigned int +internal_function +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 (BE (regs->start == NULL, 0)) + return REGS_UNALLOCATED; + regs->end = re_malloc (regoff_t, need_regs); + if (BE (regs->end == NULL, 0)) + { + 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 (BE (need_regs > regs->num_regs, 0)) + { + regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs); + regoff_t *new_end; + if (BE (new_start == NULL, 0)) + return REGS_UNALLOCATED; + new_end = re_realloc (regs->end, regoff_t, need_regs); + if (BE (new_end == NULL, 0)) + { + re_free (new_start); + return REGS_UNALLOCATED; + } + regs->start = new_start; + regs->end = new_end; + regs->num_regs = need_regs; + } + } + else + { + assert (regs_allocated == REGS_FIXED); + /* This function may not be called with REGS_FIXED and nregs too big. */ + assert (regs->num_regs >= nregs); + 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 (bufp, regs, num_regs, starts, ends) + struct re_pattern_buffer *bufp; + struct re_registers *regs; + __re_size_t num_regs; + regoff_t *starts, *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 (s) + 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 +internal_function __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 = (const re_dfa_t *) preg->buffer; + Idx left_lim, right_lim; + int incr; + bool fl_longest_match; + int match_kind; + Idx match_first; + Idx match_last = REG_MISSING; + Idx extra_nmatch; + bool sb; + int ch; +#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) + re_match_context_t mctx = { .dfa = dfa }; +#else + re_match_context_t mctx; +#endif + char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate + && start != last_start && !preg->can_be_null) + ? preg->fastmap : NULL); + RE_TRANSLATE_TYPE t = preg->translate; + +#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) + memset (&mctx, '\0', sizeof (re_match_context_t)); + mctx.dfa = dfa; +#endif + + extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0; + nmatch -= extra_nmatch; + + /* Check if the DFA haven't been compiled. */ + if (BE (preg->used == 0 || dfa->init_state == NULL + || dfa->init_state_word == NULL || dfa->init_state_nl == NULL + || dfa->init_state_begbuf == NULL, 0)) + return REG_NOMATCH; + +#ifdef DEBUG + /* We assume front-end functions already check them. */ + assert (0 <= last_start && last_start <= length); +#endif + + /* 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 (BE (err != REG_NOERROR, 0)) + goto free_return; + mctx.input.stop = stop; + mctx.input.raw_stop = stop; + mctx.input.newline_anchor = preg->newline_anchor; + + err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2); + if (BE (err != REG_NOERROR, 0)) + 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 (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0)) + { + err = REG_ESPACE; + goto free_return; + } + + mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1); + if (BE (mctx.state_log == NULL, 0)) + { + err = REG_ESPACE; + goto free_return; + } + } + else + mctx.state_log = NULL; + + match_first = start; + mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF + : CONTEXT_NEWLINE | CONTEXT_BEGBUF; + + /* Check incrementally whether of not the input string match. */ + 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 (BE (match_first < right_lim, 1) + && !fastmap[t[(unsigned char) string[match_first]]]) + ++match_first; + goto forward_match_found_start_or_reached_end; + + case 6: + /* Fastmap without translation, match forward. */ + while (BE (match_first < right_lim, 1) + && !fastmap[(unsigned char) string[match_first]]) + ++match_first; + + forward_match_found_start_or_reached_end: + if (BE (match_first == right_lim, 0)) + { + 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 (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0)) + { + err = re_string_reconstruct (&mctx.input, match_first, + eflags); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + + offset = match_first - mctx.input.raw_mbs_idx; + } + /* If MATCH_FIRST is out of the buffer, leave it as '\0'. + Note that MATCH_FIRST must not be smaller than 0. */ + ch = (match_first >= length + ? 0 : re_string_byte_at (&mctx.input, offset)); + 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 (BE (err != REG_NOERROR, 0)) + goto free_return; + +#ifdef RE_ENABLE_I18N + /* Don't consider this char as a possible match start if it part, + yet isn't the head, of a multibyte character. */ + if (!sb && !re_string_first_byte (&mctx.input, 0)) + continue; +#endif + + /* It seems to be appropriate one, then use the matcher. */ + /* We assume that the matching starts from 0. */ + mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0; + match_last = check_matching (&mctx, fl_longest_match, + start <= last_start ? &match_first : NULL); + if (match_last != REG_MISSING) + { + if (BE (match_last == REG_ERROR, 0)) + { + 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 (BE (err != REG_NOMATCH, 0)) + goto free_return; + match_last = REG_MISSING; + } + else + break; /* We found a match. */ + } + } + + match_ctx_clean (&mctx); + } + +#ifdef DEBUG + assert (match_last != REG_MISSING); + assert (err == REG_NOERROR); +#endif + + /* 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 (BE (err != REG_NOERROR, 0)) + goto free_return; + } + + /* At last, add the offset to the each registers, since we slided + 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) + { +#ifdef RE_ENABLE_I18N + if (BE (mctx.input.offsets_needed != 0, 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]); + } +#else + assert (mctx.input.offsets_needed == 0); +#endif + 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 +internal_function __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; +#ifdef DEBUG + assert (mctx->state_log != NULL); +#endif + match_last = mctx->match_last; + halt_node = mctx->last_node; + + /* Avoid overflow. */ + if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0)) + return REG_ESPACE; + + sifted_states = re_malloc (re_dfastate_t *, match_last + 1); + if (BE (sifted_states == NULL, 0)) + { + ret = REG_ESPACE; + goto free_return; + } + if (dfa->nbackref) + { + lim_states = re_malloc (re_dfastate_t *, match_last + 1); + if (BE (lim_states == NULL, 0)) + { + 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 (BE (ret != REG_NOERROR, 0)) + goto free_return; + if (sifted_states[0] != NULL || lim_states[0] != NULL) + break; + do + { + --match_last; + if (! REG_VALID_INDEX (match_last)) + { + 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 (BE (ret != REG_NOERROR, 0)) + 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 (BE (ret != REG_NOERROR, 0)) + 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 inline re_dfastate_t * +__attribute ((always_inline)) internal_function +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 REG_MISSING if + there is no match, and return REG_ERROR 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 assume that the maching starts from the current + index of the buffer. */ + +static Idx +internal_function __attribute_warn_unused_result__ +check_matching (re_match_context_t *mctx, bool fl_longest_match, + Idx *p_match_first) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx match = 0; + Idx match_last = REG_MISSING; + Idx 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 (BE (cur_state == NULL, 0)) + { + assert (err == REG_ESPACE); + return REG_ERROR; + } + + 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 (BE (dfa->nbackref, 0)) + { + at_init_state = false; + err = check_subexp_matching_top (mctx, &cur_state->nodes, 0); + if (BE (err != REG_NOERROR, 0)) + return err; + + if (cur_state->has_backref) + { + err = transit_state_bkref (mctx, &cur_state->nodes); + if (BE (err != REG_NOERROR, 0)) + return err; + } + } + } + + /* If the RE accepts NULL string. */ + if (BE (cur_state->halt, 0)) + { + 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 (BE (next_char_idx >= mctx->input.bufs_len, 0) + || (BE (next_char_idx >= mctx->input.valid_len, 0) + && mctx->input.valid_len < mctx->input.len)) + { + err = extend_buffers (mctx); + if (BE (err != REG_NOERROR, 0)) + { + assert (err == REG_ESPACE); + return REG_ERROR; + } + } + + 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 (BE (err != REG_NOERROR, 0)) + return REG_ERROR; + + if (mctx->state_log == NULL + || (match && !fl_longest_match) + || (cur_state = find_recover_state (&err, mctx)) == NULL) + break; + } + + if (BE (at_init_state, 0)) + { + 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 +internal_function +check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context) +{ + re_token_type_t type = dfa->nodes[node].type; + 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 +internal_function +check_halt_state_context (const re_match_context_t *mctx, + const re_dfastate_t *state, Idx idx) +{ + Idx i; + unsigned int context; +#ifdef DEBUG + assert (state->halt); +#endif + 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 REG_MISSING in case of errors. */ + +static Idx +internal_function +proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + Idx *pidx, Idx node, re_node_set *eps_via_nodes, + struct re_fail_stack_t *fs) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx i; + bool ok; + if (IS_EPSILON_NODE (dfa->nodes[node].type)) + { + re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes; + re_node_set *edests = &dfa->edests[node]; + Idx dest_node; + ok = re_node_set_insert (eps_via_nodes, node); + if (BE (! ok, 0)) + return REG_ERROR; + /* Pick up a valid destination, or return REG_MISSING if none + is found. */ + for (dest_node = REG_MISSING, i = 0; i < edests->nelem; ++i) + { + Idx candidate = edests->elems[i]; + if (!re_node_set_contains (cur_nodes, candidate)) + continue; + if (dest_node == REG_MISSING) + 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, + eps_via_nodes)) + return REG_ERROR; + + /* We know we are going to exit. */ + break; + } + } + return dest_node; + } + else + { + Idx naccepted = 0; + re_token_type_t type = dfa->nodes[node].type; + +#ifdef RE_ENABLE_I18N + if (dfa->nodes[node].accept_mb) + naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx); + else +#endif /* RE_ENABLE_I18N */ + if (type == OP_BACK_REF) + { + Idx subexp_idx = dfa->nodes[node].opr.idx + 1; + naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so; + if (fs != NULL) + { + if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1) + return REG_MISSING; + else if (naccepted) + { + char *buf = (char *) re_string_get_buffer (&mctx->input); + if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx, + naccepted) != 0) + return REG_MISSING; + } + } + + if (naccepted == 0) + { + Idx dest_node; + ok = re_node_set_insert (eps_via_nodes, node); + if (BE (! ok, 0)) + return REG_ERROR; + 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 REG_MISSING; + re_node_set_empty (eps_via_nodes); + return dest_node; + } + } + return REG_MISSING; +} + +static reg_errcode_t +internal_function __attribute_warn_unused_result__ +push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, + Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes) +{ + reg_errcode_t err; + Idx num = fs->num++; + if (fs->num == fs->alloc) + { + struct re_fail_stack_ent_t *new_array; + new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t) + * fs->alloc * 2)); + 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, nregs); + if (fs->stack[num].regs == NULL) + return REG_ESPACE; + memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs); + err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes); + return err; +} + +static Idx +internal_function +pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, + regmatch_t *regs, re_node_set *eps_via_nodes) +{ + Idx num = --fs->num; + assert (REG_VALID_INDEX (num)); + *pidx = fs->stack[num].idx; + memcpy (regs, fs->stack[num].regs, 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; + return fs->stack[num].node; +} + +/* Set the positions where the subexpressions are starts/ends to registers + PMATCH. + Note: We assume that pmatch[0] is already set, and + pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */ + +static reg_errcode_t +internal_function __attribute_warn_unused_result__ +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 = (const re_dfa_t *) 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 }; + regmatch_t *prev_idx_match; + bool prev_idx_match_malloced = false; + +#ifdef DEBUG + assert (nmatch > 1); + assert (mctx->state_log != NULL); +#endif + 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 (__libc_use_alloca (nmatch * sizeof (regmatch_t))) + prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t)); + else + { + prev_idx_match = re_malloc (regmatch_t, nmatch); + if (prev_idx_match == NULL) + { + free_fail_stack_return (fs); + return REG_ESPACE; + } + prev_idx_match_malloced = true; + } + 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) + { + Idx reg_idx; + if (fs) + { + for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) + if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1) + break; + if (reg_idx == nmatch) + { + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + return free_fail_stack_return (fs); + } + cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, + &eps_via_nodes); + } + else + { + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + return REG_NOERROR; + } + } + + /* Proceed to next node. */ + cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node, + &eps_via_nodes, fs); + + if (BE (! REG_VALID_INDEX (cur_node), 0)) + { + if (BE (cur_node == REG_ERROR, 0)) + { + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + free_fail_stack_return (fs); + return REG_ESPACE; + } + if (fs) + cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, + &eps_via_nodes); + else + { + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + return REG_NOMATCH; + } + } + } + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + return free_fail_stack_return (fs); +} + +static reg_errcode_t +internal_function +free_fail_stack_return (struct re_fail_stack_t *fs) +{ + if (fs) + { + 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 +internal_function +update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, + regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch) +{ + 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) + { + Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; + if (reg_num < nmatch) + { + /* We are at the last node of this sub expression. */ + if (pmatch[reg_num].rm_so < cur_idx) + { + pmatch[reg_num].rm_eo = cur_idx; + /* 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 +internal_function +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; + +#ifdef DEBUG + assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL); +#endif + + /* Build sifted state_log[str_idx]. It has the nodes which can epsilon + transit to the last_node and the last_node itself. */ + err = re_node_set_init_1 (&cur_dest, sctx->last_node); + if (BE (err != REG_NOERROR, 0)) + return err; + err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); + if (BE (err != REG_NOERROR, 0)) + 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 (BE (err != REG_NOERROR, 0)) + 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 (BE (err != REG_NOERROR, 0)) + goto free_return; + } + err = REG_NOERROR; + free_return: + re_node_set_free (&cur_dest); + return err; +} + +static reg_errcode_t +internal_function __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; + +#ifdef DEBUG + re_token_type_t type = dfa->nodes[prev_node].type; + assert (!IS_EPSILON_NODE (type)); +#endif +#ifdef RE_ENABLE_I18N + /* If the node may accept "multi byte". */ + if (dfa->nodes[prev_node].accept_mb) + naccepted = sift_states_iter_mb (mctx, sctx, prev_node, + str_idx, sctx->last_str_idx); +#endif /* RE_ENABLE_I18N */ + + /* We don't check backreferences here. + See update_cur_sifted_state(). */ + 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 (BE (! ok, 0)) + return REG_ESPACE; + } + + return REG_NOERROR; +} + +/* Helper functions. */ + +static reg_errcode_t +internal_function +clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) +{ + Idx top = mctx->state_log_top; + + if (next_state_log_idx >= mctx->input.bufs_len + || (next_state_log_idx >= mctx->input.valid_len + && mctx->input.valid_len < mctx->input.len)) + { + reg_errcode_t err; + err = extend_buffers (mctx); + if (BE (err != REG_NOERROR, 0)) + return err; + } + + if (top < next_state_log_idx) + { + 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 +internal_function +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 (BE (err != REG_NOERROR, 0)) + return err; + dst[st_idx] = re_acquire_state (&err, dfa, &merged_set); + re_node_set_free (&merged_set); + if (BE (err != REG_NOERROR, 0)) + return err; + } + } + return REG_NOERROR; +} + +static reg_errcode_t +internal_function +update_cur_sifted_state (const re_match_context_t *mctx, + re_sift_context_t *sctx, Idx str_idx, + re_node_set *dest_nodes) +{ + 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 (BE (err != REG_NOERROR, 0)) + 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 (BE (err != REG_NOERROR, 0)) + return err; + } + } + + sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes); + if (BE (err != REG_NOERROR, 0)) + return err; + } + + if (candidates && mctx->state_log[str_idx]->has_backref) + { + err = sift_states_bkref (mctx, sctx, str_idx, candidates); + if (BE (err != REG_NOERROR, 0)) + return err; + } + return REG_NOERROR; +} + +static reg_errcode_t +internal_function __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 (BE (err != REG_NOERROR, 0)) + return err; + + if (!state->inveclosure.alloc) + { + err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem); + if (BE (err != REG_NOERROR, 0)) + return REG_ESPACE; + for (i = 0; i < dest_nodes->nelem; i++) + { + err = re_node_set_merge (&state->inveclosure, + dfa->inveclosures + dest_nodes->elems[i]); + if (BE (err != REG_NOERROR, 0)) + return REG_ESPACE; + } + } + return re_node_set_add_intersect (dest_nodes, candidates, + &state->inveclosure); +} + +static reg_errcode_t +internal_function +sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes, + const re_node_set *candidates) +{ + 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] : REG_MISSING); + if ((!re_node_set_contains (inv_eclosure, edst1) + && re_node_set_contains (dest_nodes, edst1)) + || (REG_VALID_NONZERO_INDEX (edst2) + && !re_node_set_contains (inv_eclosure, edst2) + && re_node_set_contains (dest_nodes, edst2))) + { + err = re_node_set_add_intersect (&except_nodes, candidates, + dfa->inveclosures + cur_node); + if (BE (err != REG_NOERROR, 0)) + { + 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 +internal_function +check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits, + Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx) +{ + 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: + <src> <dst> ( <subexp> ) + ( <subexp> ) <src> <dst> + ( <subexp1> <src> <subexp2> <dst> <subexp3> ) */ + if (src_pos == dst_pos) + continue; /* This is unrelated limitation. */ + else + return true; + } + return false; +} + +static int +internal_function +check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, + Idx subexp_idx, Idx from_node, Idx bkref_idx) +{ + 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 != REG_MISSING) + { + 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 +internal_function +check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit, + Idx subexp_idx, Idx from_node, Idx str_idx, + Idx bkref_idx) +{ + 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 +internal_function +check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, + const re_node_set *candidates, re_node_set *limits, + struct re_backref_cache_entry *bkref_ents, Idx str_idx) +{ + 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 = REG_MISSING; + Idx cls_node = REG_MISSING; + 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 (REG_VALID_INDEX (ops_node)) + { + err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes, + candidates); + if (BE (err != REG_NOERROR, 0)) + return err; + } + + /* Check the limitation of the close subexpression. */ + if (REG_VALID_INDEX (cls_node)) + 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 (BE (err != REG_NOERROR, 0)) + 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 (BE (err != REG_NOERROR, 0)) + return err; + } + } + } + } + return REG_NOERROR; +} + +static reg_errcode_t +internal_function __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 == REG_MISSING) + 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 (BE (err != REG_NOERROR, 0)) + goto free_return; + } + local_sctx.last_node = node; + local_sctx.last_str_idx = str_idx; + ok = re_node_set_insert (&local_sctx.limits, enabled_idx); + if (BE (! ok, 0)) + { + err = REG_ESPACE; + goto free_return; + } + cur_state = local_sctx.sifted_states[str_idx]; + err = sift_states_backward (mctx, &local_sctx); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + if (sctx->limited_states != NULL) + { + err = merge_state_array (dfa, sctx->limited_states, + local_sctx.sifted_states, + str_idx + 1); + if (BE (err != REG_NOERROR, 0)) + 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; +} + + +#ifdef RE_ENABLE_I18N +static int +internal_function +sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, + Idx node_idx, Idx str_idx, Idx max_str_idx) +{ + 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 + could't accept the current input "multi byte". */ + naccepted = 0; + /* Otherwise, it is sure that the node could accept + 'naccepted' bytes input. */ + return naccepted; +} +#endif /* RE_ENABLE_I18N */ + + +/* Functions for state transition. */ + +/* Return the next state to which the current state STATE will transit by + accepting the current input byte, and update STATE_LOG if necessary. + If STATE can accept a multibyte char/collating element/back reference + update the destination of STATE_LOG. */ + +static re_dfastate_t * +internal_function __attribute_warn_unused_result__ +transit_state (reg_errcode_t *err, re_match_context_t *mctx, + re_dfastate_t *state) +{ + re_dfastate_t **trtable; + unsigned char ch; + +#ifdef RE_ENABLE_I18N + /* If the current state can accept multibyte. */ + if (BE (state->accept_mb, 0)) + { + *err = transit_state_mb (mctx, state); + if (BE (*err != REG_NOERROR, 0)) + return NULL; + } +#endif /* RE_ENABLE_I18N */ + + /* 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 (BE (trtable != NULL, 1)) + return trtable[ch]; + + trtable = state->word_trtable; + if (BE (trtable != NULL, 1)) + { + 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 * +internal_function +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 (BE (*err != REG_NOERROR, 0)) + 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 (BE (dfa->nbackref, 0) && next_state != NULL) + { + /* Check OP_OPEN_SUBEXP in the current state in case that we use them + later. We must check them here, since the back references in the + next state might use them. */ + *err = check_subexp_matching_top (mctx, &next_state->nodes, + cur_idx); + if (BE (*err != REG_NOERROR, 0)) + return NULL; + + /* If the next state has back references. */ + if (next_state->has_backref) + { + *err = transit_state_bkref (mctx, &next_state->nodes); + if (BE (*err != REG_NOERROR, 0)) + 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 * +internal_function +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 + correspoding back references. */ + +static reg_errcode_t +internal_function +check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, + Idx str_idx) +{ + 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 (BE (err != REG_NOERROR, 0)) + 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. */ + +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 (BE (*err != REG_NOERROR, 0)) + 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 (BE (*err != REG_NOERROR, 0)) + { + 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 + +#ifdef RE_ENABLE_I18N +static reg_errcode_t +internal_function +transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) +{ + const re_dfa_t *const dfa = mctx->dfa; + 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 (BE (err != REG_NOERROR, 0)) + return err; +#ifdef DEBUG + assert (dfa->nexts[cur_node_idx] != REG_MISSING); +#endif + 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 (BE (err != REG_NOERROR, 0)) + 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 (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0)) + return err; + } + return REG_NOERROR; +} +#endif /* RE_ENABLE_I18N */ + +static reg_errcode_t +internal_function +transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) +{ + const re_dfa_t *const dfa = mctx->dfa; + 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 (BE (err != REG_NOERROR, 0)) + goto free_return; + + /* And add the epsilon closures (which is 'new_dest_nodes') of + the backreference to appropriate state_log. */ +#ifdef DEBUG + assert (dfa->nexts[node_idx] != REG_MISSING); +#endif + 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 (BE (mctx->state_log[dest_str_idx] == NULL + && err != REG_NOERROR, 0)) + 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 (BE (err != REG_NOERROR, 0)) + { + 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 (BE (mctx->state_log[dest_str_idx] == NULL + && err != REG_NOERROR, 0)) + 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 (BE (err != REG_NOERROR, 0)) + goto free_return; + err = transit_state_bkref (mctx, new_dest_nodes); + if (BE (err != REG_NOERROR, 0)) + 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 +internal_function __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 != REG_MISSING) + { + 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 (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0)) + { + /* 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 (BE (err != REG_NOERROR, 0)) + 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 (BE (err != REG_NOERROR, 0)) + 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 (BE (bkref_str_off >= mctx->input.valid_len, 0)) + { + /* If we are at the end of the input, we cannot match. */ + if (bkref_str_off >= mctx->input.len) + break; + + err = extend_buffers (mctx); + if (BE (err != REG_NOERROR, 0)) + 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 == REG_MISSING) + 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 (BE (err != REG_NOERROR, 0)) + return err; + sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str); + if (BE (sub_last == NULL, 0)) + return REG_ESPACE; + err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, + bkref_str_idx); + if (err == REG_NOMATCH) + continue; + } + } + 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 +internal_function +get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top, + re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str) +{ + 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 (BE (err != REG_NOERROR, 0)) + 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 +internal_function +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 REG_MISSING; +} + +/* Check whether the node TOP_NODE at TOP_STR can arrive to the node + LAST_NODE at LAST_STR. We record the path onto PATH since it will be + heavily reused. + Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */ + +static reg_errcode_t +internal_function __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 (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0)) + { + re_dfastate_t **new_array; + Idx old_alloc = path->alloc; + Idx new_alloc = old_alloc + last_str + mctx->max_mb_elem_len + 1; + if (BE (new_alloc < old_alloc, 0) + || BE (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc, 0)) + return REG_ESPACE; + new_array = re_realloc (path->array, re_dfastate_t *, new_alloc); + if (BE (new_array == NULL, 0)) + 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 (BE (err != REG_NOERROR, 0)) + return err; + err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); + if (BE (err != REG_NOERROR, 0)) + { + 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 (BE (err != REG_NOERROR, 0)) + 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 (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + } + cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); + if (BE (cur_state == NULL && err != REG_NOERROR, 0)) + { + 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 (BE (err != REG_NOERROR, 0)) + { + 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 (BE (err != REG_NOERROR, 0)) + { + 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 (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + err = expand_bkref_cache (mctx, &next_nodes, str_idx, + subexp_num, type); + if (BE (err != REG_NOERROR, 0)) + { + 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 (BE (cur_state == NULL && err != REG_NOERROR, 0)) + { + 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 +internal_function __attribute_warn_unused_result__ +check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, + re_node_set *cur_nodes, re_node_set *next_nodes) +{ + const re_dfa_t *const dfa = mctx->dfa; + bool ok; + Idx cur_idx; +#ifdef RE_ENABLE_I18N + reg_errcode_t err = REG_NOERROR; +#endif + re_node_set union_set; + re_node_set_init_empty (&union_set); + for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx) + { + int naccepted = 0; + Idx cur_node = cur_nodes->elems[cur_idx]; +#ifdef DEBUG + re_token_type_t type = dfa->nodes[cur_node].type; + assert (!IS_EPSILON_NODE (type)); +#endif +#ifdef RE_ENABLE_I18N + /* 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 (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&union_set); + return err; + } + } + ok = re_node_set_insert (&union_set, next_node); + if (BE (! ok, 0)) + { + re_node_set_free (&union_set); + return REG_ESPACE; + } + mctx->state_log[next_idx] = re_acquire_state (&err, dfa, + &union_set); + if (BE (mctx->state_log[next_idx] == NULL + && err != REG_NOERROR, 0)) + { + re_node_set_free (&union_set); + return err; + } + } + } +#endif /* RE_ENABLE_I18N */ + if (naccepted + || check_node_accept (mctx, dfa->nodes + cur_node, str_idx)) + { + ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]); + if (BE (! ok, 0)) + { + 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 +internal_function +check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, + Idx ex_subexp, int type) +{ + reg_errcode_t err; + Idx idx, outside_node; + re_node_set new_nodes; +#ifdef DEBUG + assert (cur_nodes->nelem); +#endif + err = re_node_set_alloc (&new_nodes, cur_nodes->nelem); + if (BE (err != REG_NOERROR, 0)) + 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 == REG_MISSING) + { + /* There are no problematic nodes, just merge them. */ + err = re_node_set_merge (&new_nodes, eclosure); + if (BE (err != REG_NOERROR, 0)) + { + 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 (BE (err != REG_NOERROR, 0)) + { + 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 +internal_function __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 (BE (! ok, 0)) + return REG_ESPACE; + } + break; + } + ok = re_node_set_insert (dst_nodes, cur_node); + if (BE (! ok, 0)) + 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 (BE (err != REG_NOERROR, 0)) + 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 +internal_function __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 == REG_MISSING) + 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 (BE (err != REG_NOERROR || err2 != REG_NOERROR + || err3 != REG_NOERROR, 0)) + { + 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 (BE (err != REG_NOERROR || ! ok, 0)) + { + 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 (BE (err != REG_NOERROR, 0)) + return err; + } + mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set); + re_node_set_free (&union_set); + if (BE (mctx->state_log[to_idx] == NULL + && err != REG_NOERROR, 0)) + return err; + } + } + while (ent++->more); + return REG_NOERROR; +} + +/* Build transition table for the state. + Return true if successful. */ + +static bool +internal_function +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; + bool dests_node_malloced = false; + bool dest_states_malloced = false; + Idx ndests; /* Number of the destination states from 'state'. */ + re_dfastate_t **trtable; + re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl; + re_node_set follows, *dests_node; + bitset_t *dests_ch; + bitset_t acceptable; + + struct dests_alloc + { + re_node_set dests_node[SBC_MAX]; + bitset_t dests_ch[SBC_MAX]; + } *dests_alloc; + + /* We build DFA states which corresponds to the destination nodes + from 'state'. 'dests_node[i]' represents the nodes which i-th + destination state contains, and 'dests_ch[i]' represents the + characters which i-th destination state accepts. */ + if (__libc_use_alloca (sizeof (struct dests_alloc))) + dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc)); + else + { + dests_alloc = re_malloc (struct dests_alloc, 1); + if (BE (dests_alloc == NULL, 0)) + return false; + dests_node_malloced = true; + } + dests_node = dests_alloc->dests_node; + dests_ch = dests_alloc->dests_ch; + + /* Initialize transiton 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 (BE (! REG_VALID_NONZERO_INDEX (ndests), 0)) + { + if (dests_node_malloced) + free (dests_alloc); + if (ndests == 0) + { + state->trtable = (re_dfastate_t **) + calloc (sizeof (re_dfastate_t *), SBC_MAX); + if (BE (state->trtable == NULL, 0)) + return false; + return true; + } + return false; + } + + err = re_node_set_alloc (&follows, ndests + 1); + if (BE (err != REG_NOERROR, 0)) + goto out_free; + + /* Avoid arithmetic overflow in size calculation. */ + if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX) + / (3 * sizeof (re_dfastate_t *))) + < ndests), + 0)) + goto out_free; + + if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX + + ndests * 3 * sizeof (re_dfastate_t *))) + dest_states = (re_dfastate_t **) + alloca (ndests * 3 * sizeof (re_dfastate_t *)); + else + { + dest_states = (re_dfastate_t **) + malloc (ndests * 3 * sizeof (re_dfastate_t *)); + if (BE (dest_states == NULL, 0)) + { +out_free: + if (dest_states_malloced) + free (dest_states); + re_node_set_free (&follows); + for (i = 0; i < ndests; ++i) + re_node_set_free (dests_node + i); + if (dests_node_malloced) + free (dests_alloc); + return false; + } + dest_states_malloced = true; + } + dest_states_word = dest_states + ndests; + dest_states_nl = dest_states_word + ndests; + 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 != REG_MISSING) + { + err = re_node_set_merge (&follows, dfa->eclosures + next_node); + if (BE (err != REG_NOERROR, 0)) + goto out_free; + } + } + dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0); + if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0)) + 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 (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0)) + 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 (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0)) + 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 (!BE (need_word_trtable, 0)) + { + /* 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 (BE (trtable == NULL, 0)) + 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 (BE (elem & 1, 0)) + { + /* 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 (BE (trtable == NULL, 0)) + 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 (BE (elem & 1, 0)) + { + /* 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; + } + } + + if (dest_states_malloced) + free (dest_states); + + re_node_set_free (&follows); + for (i = 0; i < ndests; ++i) + re_node_set_free (dests_node + i); + + if (dests_node_malloced) + free (dests_alloc); + + return true; +} + +/* Group all nodes belonging to STATE into several destinations. + Then for all destinations, set the nodes belonging to the destination + to DESTS_NODE[i] and set the characters accepted by the destination + to DEST_CH[i]. This function return the number of destinations. */ + +static Idx +internal_function +group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + re_node_set *dests_node, bitset_t *dests_ch) +{ + 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) + { +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + bitset_merge (accepts, dfa->sb_char); + else +#endif + bitset_set_all (accepts); + if (!(dfa->syntax & RE_DOT_NEWLINE)) + bitset_clear (accepts, '\n'); + if (dfa->syntax & RE_DOT_NOT_NULL) + bitset_clear (accepts, '\0'); + } +#ifdef RE_ENABLE_I18N + else if (type == OP_UTF8_PERIOD) + { + if (ASCII_CHARS % BITSET_WORD_BITS == 0) + 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'); + } +#endif + 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; + } +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j])); + else +#endif + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= dfa->word_char[j]); + if (!any_set) + continue; + } + if (constraint & NEXT_NOTWORD_CONSTRAINT) + { + bitset_word_t any_set = 0; + if (type == CHARACTER && node->word_char) + { + bitset_empty (accepts); + continue; + } +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j])); + else +#endif + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= ~dfa->word_char[j]); + if (!any_set) + 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 (BE (err != REG_NOERROR, 0)) + goto error_return; + ++ndests; + } + + /* Put the position in the current group. */ + ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]); + if (BE (! ok, 0)) + 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 (BE (err != REG_NOERROR, 0)) + goto error_return; + ++ndests; + bitset_empty (accepts); + } + } + return ndests; + error_return: + for (j = 0; j < ndests; ++j) + re_node_set_free (dests_node + j); + return REG_MISSING; +} + +#ifdef RE_ENABLE_I18N +/* Check how many bytes the node 'dfa->nodes[node_idx]' accepts. + Return the number of the bytes the node accepts. + STR_IDX is the current index of the input string. + + 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. */ + +static int +internal_function +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 (BE (node->type == OP_UTF8_PERIOD, 0)) + { + unsigned char c = re_string_byte_at (input, str_idx), d; + if (BE (c < 0xc2, 1)) + 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 /* _LIBC */ + 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; + int32_t idx; + /* This #include defines a local function! */ +# include <locale/weight.h> + + /* 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? */ + 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 (&cp); + if (idx > 0) + for (i = 0; i < cset->nequiv_classes; ++i) + { + int32_t equiv_class_idx = cset->equiv_classes[i]; + size_t weight_len = weights[idx & 0xffffff]; + if (weight_len == weights[equiv_class_idx & 0xffffff] + && (idx >> 24) == (equiv_class_idx >> 24)) + { + Idx cnt = 0; + + idx &= 0xffffff; + equiv_class_idx &= 0xffffff; + + while (cnt <= weight_len + && (weights[equiv_class_idx + 1 + cnt] + == weights[idx + 1 + cnt])) + ++cnt; + if (cnt > weight_len) + { + match_len = elem_len; + goto check_node_accept_bytes_match; + } + } + } + } + } + else +# endif /* _LIBC */ + { + /* match with range expression? */ +#if __GNUC__ >= 2 && ! (__STDC_VERSION__ < 199901L && defined __STRICT_ANSI__) + wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'}; +#else + wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'}; + cmp_buf[2] = wc; +#endif + for (i = 0; i < cset->nranges; ++i) + { + cmp_buf[0] = cset->range_starts[i]; + cmp_buf[4] = cset->range_ends[i]; + if (wcscoll (cmp_buf, cmp_buf + 2) <= 0 + && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0) + { + 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 +internal_function +find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) +{ + uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + 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) * (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 */ +#endif /* RE_ENABLE_I18N */ + +/* Check whether the node accepts the byte which is IDX-th + byte of the INPUT. */ + +static bool +internal_function +check_node_accept (const re_match_context_t *mctx, const re_token_t *node, + Idx idx) +{ + 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; + +#ifdef RE_ENABLE_I18N + case OP_UTF8_PERIOD: + if (ch >= ASCII_CHARS) + return false; + /* FALLTHROUGH */ +#endif + 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 +internal_function __attribute_warn_unused_result__ +extend_buffers (re_match_context_t *mctx) +{ + reg_errcode_t ret; + re_string_t *pstr = &mctx->input; + + /* Avoid overflow. */ + if (BE (SIZE_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0)) + return REG_ESPACE; + + /* Double the lengthes of the buffers. */ + ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); + if (BE (ret != REG_NOERROR, 0)) + 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 (BE (new_array == NULL, 0)) + return REG_ESPACE; + mctx->state_log = new_array; + } + + /* Then reconstruct the buffers. */ + if (pstr->icase) + { +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + { + ret = build_wcs_upper_buffer (pstr); + if (BE (ret != REG_NOERROR, 0)) + return ret; + } + else +#endif /* RE_ENABLE_I18N */ + build_upper_buffer (pstr); + } + else + { +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + build_wcs_buffer (pstr); + else +#endif /* RE_ENABLE_I18N */ + { + if (pstr->trans != NULL) + re_string_translate_buffer (pstr); + } + } + return REG_NOERROR; +} + + +/* Functions for matching context. */ + +/* Initialize MCTX. */ + +static reg_errcode_t +internal_function __attribute_warn_unused_result__ +match_ctx_init (re_match_context_t *mctx, int eflags, Idx n) +{ + mctx->eflags = eflags; + mctx->match_last = REG_MISSING; + if (n > 0) + { + /* Avoid overflow. */ + size_t max_object_size = + MAX (sizeof (struct re_backref_cache_entry), + sizeof (re_sub_match_top_t *)); + if (BE (SIZE_MAX / max_object_size < n, 0)) + return REG_ESPACE; + + mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n); + mctx->sub_tops = re_malloc (re_sub_match_top_t *, n); + if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0)) + 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 +internal_function +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); + } + free (top); + } + + mctx->nsub_tops = 0; + mctx->nbkref_ents = 0; +} + +/* Free all the memory associated with MCTX. */ + +static void +internal_function +match_ctx_free (re_match_context_t *mctx) +{ + /* First, free all the memory associated with MCTX->SUB_TOPS. */ + 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 +internal_function __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 (BE (new_entry == NULL, 0)) + { + 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 REG_MISSING if none is + found. Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX. */ + +static Idx +internal_function +search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) +{ + Idx left, right, mid, last; + 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 REG_MISSING; +} + +/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches + at STR_IDX. */ + +static reg_errcode_t +internal_function __attribute_warn_unused_result__ +match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) +{ +#ifdef DEBUG + assert (mctx->sub_tops != NULL); + assert (mctx->asub_tops > 0); +#endif + if (BE (mctx->nsub_tops == mctx->asub_tops, 0)) + { + Idx new_asub_tops = mctx->asub_tops * 2; + re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops, + re_sub_match_top_t *, + new_asub_tops); + if (BE (new_array == NULL, 0)) + return REG_ESPACE; + mctx->sub_tops = new_array; + mctx->asub_tops = new_asub_tops; + } + mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t)); + if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0)) + 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. */ + +static re_sub_match_last_t * +internal_function +match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx) +{ + re_sub_match_last_t *new_entry; + if (BE (subtop->nlasts == subtop->alasts, 0)) + { + Idx new_alasts = 2 * subtop->alasts + 1; + re_sub_match_last_t **new_array = re_realloc (subtop->lasts, + re_sub_match_last_t *, + new_alasts); + if (BE (new_array == NULL, 0)) + return NULL; + subtop->lasts = new_array; + subtop->alasts = new_alasts; + } + new_entry = calloc (1, sizeof (re_sub_match_last_t)); + if (BE (new_entry != NULL, 1)) + { + subtop->lasts[subtop->nlasts] = new_entry; + new_entry->node = node; + new_entry->str_idx = str_idx; + ++subtop->nlasts; + } + return new_entry; +} + +static void +internal_function +sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, + re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx) +{ + 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/gnu/rename.c b/gnu/rename.c new file mode 100644 index 00000000..7926c62d --- /dev/null +++ b/gnu/rename.c @@ -0,0 +1,475 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Work around rename bugs in some systems. + + Copyright (C) 2001-2003, 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Volker Borchert, Eric Blake. */ + +#include <config.h> + +#include <stdio.h> + +#undef rename + +#if (defined _WIN32 || 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 <errno.h> +# include <stdbool.h> +# include <stdlib.h> +# include <sys/stat.h> +# include <unistd.h> + +# define WIN32_LEAN_AND_MEAN +# include <windows.h> + +# include "dirname.h" + +/* 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)) + { + error = errno; + free (src_temp); + free (dst_temp); + errno = error; + 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 <errno.h> +# include <stdio.h> +# include <stdlib.h> +# include <string.h> +# include <sys/stat.h> +# include <unistd.h> + +# 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; + 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: + 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/gnu/renameat.c b/gnu/renameat.c new file mode 100644 index 00000000..8aca51f7 --- /dev/null +++ b/gnu/renameat.c @@ -0,0 +1,159 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Rename a file relative to open directories. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <stdio.h> + +#if HAVE_RENAMEAT + +# include <errno.h> +# include <stdbool.h> +# include <stdlib.h> +# include <string.h> +# include <sys/stat.h> + +# include "dirname.h" +# include "openat.h" + +# undef renameat + +/* renameat does not honor trailing / on Solaris 10. Solve it in a + similar manner to rename. No need to worry about bugs not present + on Solaris, since all other systems either lack renameat or honor + trailing slash correctly. */ + +int +rpl_renameat (int fd1, char const *src, int fd2, 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; + int ret_val = -1; + int rename_errno = ENOTDIR; + struct stat src_st; + struct stat dst_st; + + /* Let strace see any ENOENT failure. */ + if (!src_len || !dst_len) + return renameat (fd1, src, fd2, dst); + + src_slash = src[src_len - 1] == '/'; + dst_slash = dst[dst_len - 1] == '/'; + if (!src_slash && !dst_slash) + return renameat (fd1, src, fd2, dst); + + /* 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 (lstatat (fd1, src, &src_st)) + return -1; + if (lstatat (fd2, dst, &dst_st)) + { + if (errno != ENOENT || !S_ISDIR (src_st.st_mode)) + return -1; + } + else if (!S_ISDIR (dst_st.st_mode)) + { + errno = ENOTDIR; + return -1; + } + else if (!S_ISDIR (src_st.st_mode)) + { + errno = EISDIR; + return -1; + } + +# if RENAME_TRAILING_SLASH_SOURCE_BUG + /* See the lengthy comment in rename.c why Solaris 9 is forced to + GNU behavior, while Solaris 10 is left with POSIX behavior, + regarding symlinks with trailing slash. */ + 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 (lstatat (fd1, 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 (lstatat (fd2, 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 */ + + ret_val = renameat (fd1, src_temp, fd2, dst_temp); + rename_errno = errno; + out: + if (src_temp != src) + free (src_temp); + if (dst_temp != dst) + free (dst_temp); + errno = rename_errno; + return ret_val; +} + +#else /* !HAVE_RENAMEAT */ + +# include "openat-priv.h" + +/* Rename FILE1, in the directory open on descriptor FD1, to FILE2, in + the directory open on descriptor FD2. If possible, do it without + changing the working directory. Otherwise, resort to using + save_cwd/fchdir, then rename/restore_cwd. If either the save_cwd or + the restore_cwd fails, then give a diagnostic and exit nonzero. */ + +int +renameat (int fd1, char const *file1, int fd2, char const *file2) +{ + return at_func2 (fd1, file1, fd2, file2, rename); +} + +#endif /* !HAVE_RENAMEAT */ diff --git a/gnu/rewinddir.c b/gnu/rewinddir.c new file mode 100644 index 00000000..3718b207 --- /dev/null +++ b/gnu/rewinddir.c @@ -0,0 +1,51 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Restart reading the entries of a directory from the beginning. + Copyright (C) 2011-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <dirent.h> + +#include <errno.h> + +#include "dirent-private.h" + +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/gnu/rmdir.c b/gnu/rmdir.c new file mode 100644 index 00000000..91c6d4be --- /dev/null +++ b/gnu/rmdir.c @@ -0,0 +1,55 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Work around rmdir bugs. + + Copyright (C) 1988, 1990, 1999, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include <unistd.h> + +#include <errno.h> +#include <string.h> + +#include "dosname.h" + +#undef rmdir + +/* 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/gnu/rpmatch.c b/gnu/rpmatch.c new file mode 100644 index 00000000..6bfaa256 --- /dev/null +++ b/gnu/rpmatch.c @@ -0,0 +1,175 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Determine whether string value is affirmation or negative response + according to current locale's data. + + Copyright (C) 1996, 1998, 2000, 2002-2003, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <stdlib.h> + +#include <stdbool.h> +#include <stddef.h> + +#if ENABLE_NLS +# include <sys/types.h> +# include <limits.h> +# include <string.h> +# if HAVE_LANGINFO_YESEXPR +# include <langinfo.h> +# endif +# include <regex.h> +# include "gettext.h" +# define _(msgid) gettext (msgid) +# define N_(msgid) gettext_noop (msgid) + +# if HAVE_LANGINFO_YESEXPR +/* Return the localized regular expression pattern corresponding to + ENGLISH_PATTERN. NL_INDEX can be used with nl_langinfo. + The resulting string may only be used until the next nl_langinfo call. */ +static const char * +localized_pattern (const char *english_pattern, nl_item nl_index, + bool posixly_correct) +{ + const char *translated_pattern; + + /* We prefer to get the patterns from a PO file. It would be possible to + always use nl_langinfo (YESEXPR) instead of _("^[yY]"), and + nl_langinfo (NOEXPR) instead of _("^[nN]"), if we could assume that the + system's locale support is good. But this is not the case e.g. on Cygwin. + The localizations of gnulib.pot are of better quality in general. + Also, if we use locale info from non-free systems that don't have a + 'localedef' command, we deprive the users of the freedom to localize + this pattern for their preferred language. + But some programs, such as 'cp', 'mv', 'rm', 'find', 'xargs', are + specified by POSIX to use nl_langinfo (YESEXPR). We implement this + behaviour if POSIXLY_CORRECT is set, for the sake of these programs. */ + + /* If the user wants strict POSIX compliance, use nl_langinfo. */ + if (posixly_correct) + { + translated_pattern = nl_langinfo (nl_index); + /* Check against a broken system return value. */ + if (translated_pattern != NULL && translated_pattern[0] != '\0') + return translated_pattern; + } + + /* Look in the gnulib message catalog. */ + translated_pattern = _(english_pattern); + if (translated_pattern == english_pattern) + { + /* The gnulib message catalog provides no translation. + Try the system's message catalog. */ + translated_pattern = nl_langinfo (nl_index); + /* Check against a broken system return value. */ + if (translated_pattern != NULL && translated_pattern[0] != '\0') + return translated_pattern; + /* Fall back to English. */ + translated_pattern = english_pattern; + } + return translated_pattern; +} +# else +# define localized_pattern(english_pattern,nl_index,posixly_correct) \ + _(english_pattern) +# endif + +static int +try (const char *response, const char *pattern, char **lastp, regex_t *re) +{ + if (*lastp == NULL || strcmp (pattern, *lastp) != 0) + { + char *safe_pattern; + + /* The pattern has changed. */ + if (*lastp != NULL) + { + /* Free the old compiled pattern. */ + regfree (re); + free (*lastp); + *lastp = NULL; + } + /* Put the PATTERN into safe memory before calling regcomp. + (regcomp may call nl_langinfo, overwriting PATTERN's storage. */ + safe_pattern = strdup (pattern); + if (safe_pattern == NULL) + return -1; + /* Compile the pattern and cache it for future runs. */ + if (regcomp (re, safe_pattern, REG_EXTENDED) != 0) + return -1; + *lastp = safe_pattern; + } + + /* See if the regular expression matches RESPONSE. */ + return regexec (re, response, 0, NULL, 0) == 0; +} +#endif + + +int +rpmatch (const char *response) +{ +#if ENABLE_NLS + /* Match against one of the response patterns, compiling the pattern + first if necessary. */ + + /* We cache the response patterns and compiled regexps here. */ + static char *last_yesexpr, *last_noexpr; + static regex_t cached_yesre, cached_nore; + +# if HAVE_LANGINFO_YESEXPR + bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL); +# endif + + const char *yesexpr, *noexpr; + int result; + + /* TRANSLATORS: A regular expression testing for an affirmative answer + (english: "yes"). Testing the first character may be sufficient. + Take care to consider upper and lower case. + To enquire the regular expression that your system uses for this + purpose, you can use the command + locale -k LC_MESSAGES | grep '^yesexpr=' */ + yesexpr = localized_pattern (N_("^[yY]"), YESEXPR, posixly_correct); + result = try (response, yesexpr, &last_yesexpr, &cached_yesre); + if (result < 0) + return -1; + if (result) + return 1; + + /* TRANSLATORS: A regular expression testing for a negative answer + (english: "no"). Testing the first character may be sufficient. + Take care to consider upper and lower case. + To enquire the regular expression that your system uses for this + purpose, you can use the command + locale -k LC_MESSAGES | grep '^noexpr=' */ + noexpr = localized_pattern (N_("^[nN]"), NOEXPR, posixly_correct); + result = try (response, noexpr, &last_noexpr, &cached_nore); + if (result < 0) + return -1; + if (result) + return 0; + + return -1; +#else + /* Test against "^[yY]" and "^[nN]", hardcoded to avoid requiring regex */ + return (*response == 'y' || *response == 'Y' ? 1 + : *response == 'n' || *response == 'N' ? 0 : -1); +#endif +} diff --git a/gnu/safe-read.c b/gnu/safe-read.c new file mode 100644 index 00000000..46d61d5e --- /dev/null +++ b/gnu/safe-read.c @@ -0,0 +1,79 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* An interface to read and write that retries after interrupts. + + Copyright (C) 1993-1994, 1998, 2002-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#ifdef SAFE_WRITE +# include "safe-write.h" +#else +# include "safe-read.h" +#endif + +/* Get ssize_t. */ +#include <sys/types.h> +#include <unistd.h> + +#include <errno.h> + +#ifdef EINTR +# define IS_EINTR(x) ((x) == EINTR) +#else +# define IS_EINTR(x) 0 +#endif + +#include <limits.h> + +#ifdef SAFE_WRITE +# define safe_rw safe_write +# define rw write +#else +# define safe_rw safe_read +# define rw read +# undef const +# define const /* empty */ +#endif + +/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if + interrupted. Return the actual number of bytes read(written), zero for EOF, + or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */ +size_t +safe_rw (int fd, void const *buf, size_t count) +{ + /* Work around a bug in Tru64 5.1. Attempting to read more than + INT_MAX bytes fails with errno == EINVAL. See + <http://lists.gnu.org/archive/html/bug-gnu-utils/2002-04/msg00010.html>. + When decreasing COUNT, keep it block-aligned. */ + enum { BUGGY_READ_MAXIMUM = INT_MAX & ~8191 }; + + for (;;) + { + ssize_t result = rw (fd, buf, count); + + if (0 <= result) + return result; + else if (IS_EINTR (errno)) + continue; + else if (errno == EINVAL && BUGGY_READ_MAXIMUM < count) + count = BUGGY_READ_MAXIMUM; + else + return result; + } +} diff --git a/gnu/safe-read.h b/gnu/safe-read.h new file mode 100644 index 00000000..6103e9cc --- /dev/null +++ b/gnu/safe-read.h @@ -0,0 +1,49 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* An interface to read() that retries after interrupts. + Copyright (C) 2002, 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Some system calls may be interrupted and fail with errno = EINTR in the + following situations: + - The process is stopped and restarted (signal SIGSTOP and SIGCONT, user + types Ctrl-Z) on some platforms: MacOS X. + - The process receives a signal for which a signal handler was installed + with sigaction() with an sa_flags field that does not contain + SA_RESTART. + - The process receives a signal for which a signal handler was installed + with signal() and for which no call to siginterrupt(sig,0) was done, + on some platforms: AIX, HP-UX, IRIX, OSF/1, Solaris. + + This module provides a wrapper around read() that handles EINTR. */ + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SAFE_READ_ERROR ((size_t) -1) + +/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted. + Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR + upon error. */ +extern size_t safe_read (int fd, void *buf, size_t count); + + +#ifdef __cplusplus +} +#endif diff --git a/gnu/safe-write.c b/gnu/safe-write.c new file mode 100644 index 00000000..72c08022 --- /dev/null +++ b/gnu/safe-write.c @@ -0,0 +1,20 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* An interface to write that retries after interrupts. + Copyright (C) 2002, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#define SAFE_WRITE +#include "safe-read.c" diff --git a/gnu/safe-write.h b/gnu/safe-write.h new file mode 100644 index 00000000..ad36a04a --- /dev/null +++ b/gnu/safe-write.h @@ -0,0 +1,39 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* An interface to write() that retries after interrupts. + Copyright (C) 2002, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Some system calls may be interrupted and fail with errno = EINTR in the + following situations: + - The process is stopped and restarted (signal SIGSTOP and SIGCONT, user + types Ctrl-Z) on some platforms: MacOS X. + - The process receives a signal for which a signal handler was installed + with sigaction() with an sa_flags field that does not contain + SA_RESTART. + - The process receives a signal for which a signal handler was installed + with signal() and for which no call to siginterrupt(sig,0) was done, + on some platforms: AIX, HP-UX, IRIX, OSF/1, Solaris. + + This module provides a wrapper around write() that handles EINTR. */ + +#include <stddef.h> + +#define SAFE_WRITE_ERROR ((size_t) -1) + +/* Write up to COUNT bytes at BUF to descriptor FD, retrying if interrupted. + Return the actual number of bytes written, zero for EOF, or SAFE_WRITE_ERROR + upon error. */ +extern size_t safe_write (int fd, const void *buf, size_t count); diff --git a/gnu/same-inode.h b/gnu/same-inode.h new file mode 100644 index 00000000..07b5a929 --- /dev/null +++ b/gnu/same-inode.h @@ -0,0 +1,35 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Determine whether two stat buffers refer to the same file. + + Copyright (C) 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef SAME_INODE_H +# define SAME_INODE_H 1 + +# ifdef __VMS +# 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) +# else +# define SAME_INODE(a, b) \ + ((a).st_ino == (b).st_ino \ + && (a).st_dev == (b).st_dev) +# endif + +#endif diff --git a/gnu/save-cwd.c b/gnu/save-cwd.c new file mode 100644 index 00000000..c33c803f --- /dev/null +++ b/gnu/save-cwd.c @@ -0,0 +1,101 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* save-cwd.c -- Save and restore current working directory. + + Copyright (C) 1995, 1997-1998, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#include <config.h> + +#include "save-cwd.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include "chdir-long.h" +#include "unistd--.h" +#include "cloexec.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); + if (!GNULIB_FCNTL_SAFER) + cwd->desc = fd_safer (cwd->desc); + if (cwd->desc < 0) + { + cwd->name = getcwd (NULL, 0); + return cwd->name ? 0 : -1; + } + + set_cloexec_flag (cwd->desc, true); + 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/gnu/save-cwd.h b/gnu/save-cwd.h new file mode 100644 index 00000000..3162e66c --- /dev/null +++ b/gnu/save-cwd.h @@ -0,0 +1,36 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Save and restore current working directory. + + Copyright (C) 1995, 1997-1998, 2003, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* 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/gnu/savedir.c b/gnu/savedir.c new file mode 100644 index 00000000..c5d6a573 --- /dev/null +++ b/gnu/savedir.c @@ -0,0 +1,147 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* savedir.c -- save the list of files in a directory in a string + + Copyright (C) 1990, 1997-2001, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ + +#include <config.h> + +#include "savedir.h" + +#include <sys/types.h> + +#include <errno.h> + +#include "dirent--.h" +#ifndef _D_EXACT_NAMLEN +# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name) +#endif + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include "xalloc.h" + +#ifndef NAME_SIZE_DEFAULT +# define NAME_SIZE_DEFAULT 512 +#endif + +/* Return a freshly allocated string containing the file names + in directory DIRP, separated by '\0' characters; + the end is marked by two '\0' characters in a row. + Return NULL (setting errno) if DIRP cannot be read. + If DIRP is NULL, return NULL without affecting errno. */ + +char * +streamsavedir (DIR *dirp) +{ + char *name_space; + size_t allocated = NAME_SIZE_DEFAULT; + size_t used = 0; + int save_errno; + + if (dirp == NULL) + return NULL; + + name_space = xmalloc (allocated); + + for (;;) + { + struct dirent const *dp; + char const *entry; + + errno = 0; + dp = readdir (dirp); + if (! dp) + break; + + /* Skip "", ".", and "..". "" is returned by at least one buggy + implementation: Solaris 2.4 readdir on NFS file systems. */ + entry = dp->d_name; + if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0') + { + size_t entry_size = _D_EXACT_NAMLEN (dp) + 1; + if (used + entry_size < used) + xalloc_die (); + if (allocated <= used + entry_size) + { + do + { + if (2 * allocated < allocated) + xalloc_die (); + allocated *= 2; + } + while (allocated <= used + entry_size); + + name_space = xrealloc (name_space, allocated); + } + memcpy (name_space + used, entry, entry_size); + used += entry_size; + } + } + name_space[used] = '\0'; + save_errno = errno; + if (save_errno != 0) + { + free (name_space); + errno = save_errno; + return NULL; + } + return name_space; +} + +/* Like savedirstreamp (DIRP), except also close DIRP. */ + +static char * +savedirstream (DIR *dirp) +{ + char *name_space = streamsavedir (dirp); + if (dirp && closedir (dirp) != 0) + { + int save_errno = errno; + free (name_space); + errno = save_errno; + return NULL; + } + return name_space; +} + +/* Return a freshly allocated string containing the file names + in directory DIR, separated by '\0' characters; + the end is marked by two '\0' characters in a row. + Return NULL (setting errno) if DIR cannot be opened, read, or closed. */ + +char * +savedir (char const *dir) +{ + return savedirstream (opendir (dir)); +} + +/* Return a freshly allocated string containing the file names + in directory FD, separated by '\0' characters; + the end is marked by two '\0' characters in a row. + Return NULL (setting errno) if FD cannot be read or closed. */ + +/* deprecated */ +char * +fdsavedir (int fd) +{ + return savedirstream (fdopendir (fd)); +} diff --git a/gnu/savedir.h b/gnu/savedir.h new file mode 100644 index 00000000..650691e7 --- /dev/null +++ b/gnu/savedir.h @@ -0,0 +1,31 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Save the list of files in a directory in a string. + + Copyright (C) 1997, 1999, 2001, 2003, 2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ + +#ifndef _GL_SAVEDIR_H +#define _GL_SAVEDIR_H + +#include <dirent.h> +char *streamsavedir (DIR *dirp); +char *savedir (char const *dir); +char *fdsavedir (int fd); /* deprecated */ + +#endif diff --git a/gnu/setenv.c b/gnu/setenv.c new file mode 100644 index 00000000..c1484fad --- /dev/null +++ b/gnu/setenv.c @@ -0,0 +1,392 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1992, 1995-2003, 2005-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#if !_LIBC +# define _GL_USE_STDLIB_ALLOC 1 +# include <config.h> +#endif + +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the name == NULL test below. */ +#define _GL_ARG_NONNULL(params) + +#include <alloca.h> + +/* Specification. */ +#include <stdlib.h> + +#include <errno.h> +#ifndef __set_errno +# define __set_errno(ev) ((errno) = (ev)) +#endif + +#include <string.h> +#if _LIBC || HAVE_UNISTD_H +# include <unistd.h> +#endif + +#if !_LIBC +# include "malloca.h" +#endif + +#if _LIBC || !HAVE_SETENV + +#if !_LIBC +# define __environ environ +#endif + +#if _LIBC +/* This lock protects against simultaneous modifications of 'environ'. */ +# include <bits/libc-lock.h> +__libc_lock_define_initialized (static, envlock) +# define LOCK __libc_lock_lock (envlock) +# define UNLOCK __libc_lock_unlock (envlock) +#else +# define LOCK +# define UNLOCK +#endif + +/* In the GNU C library we must keep the namespace clean. */ +#ifdef _LIBC +# define setenv __setenv +# define clearenv __clearenv +# define tfind __tfind +# define tsearch __tsearch +#endif + +/* In the GNU C library implementation we try to be more clever and + allow arbitrarily many changes of the environment given that the used + values are from a small set. Outside glibc this will eat up all + memory after a while. */ +#if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \ + && defined __GNUC__) +# define USE_TSEARCH 1 +# include <search.h> +typedef int (*compar_fn_t) (const void *, const void *); + +/* This is a pointer to the root of the search tree with the known + values. */ +static void *known_values; + +# define KNOWN_VALUE(Str) \ + ({ \ + void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \ + value != NULL ? *(char **) value : NULL; \ + }) +# define STORE_VALUE(Str) \ + tsearch (Str, &known_values, (compar_fn_t) strcmp) + +#else +# undef USE_TSEARCH + +# define KNOWN_VALUE(Str) NULL +# define STORE_VALUE(Str) do { } while (0) + +#endif + + +/* If this variable is not a null pointer we allocated the current + environment. */ +static char **last_environ; + + +/* This function is used by 'setenv' and 'putenv'. The difference between + the two functions is that for the former must create a new string which + is then placed in the environment, while the argument of 'putenv' + must be used directly. This is all complicated by the fact that we try + to reuse values once generated for a 'setenv' call since we can never + free the strings. */ +int +__add_to_environ (const char *name, const char *value, const char *combined, + int replace) +{ + char **ep; + size_t size; + const size_t namelen = strlen (name); + const size_t vallen = value != NULL ? strlen (value) + 1 : 0; + + LOCK; + + /* We have to get the pointer now that we have the lock and not earlier + since another thread might have created a new environment. */ + ep = __environ; + + size = 0; + if (ep != NULL) + { + for (; *ep != NULL; ++ep) + if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') + break; + else + ++size; + } + + if (ep == NULL || *ep == NULL) + { + char **new_environ; +#ifdef USE_TSEARCH + char *new_value; +#endif + + /* We allocated this space; we can extend it. */ + new_environ = + (char **) (last_environ == NULL + ? malloc ((size + 2) * sizeof (char *)) + : realloc (last_environ, (size + 2) * sizeof (char *))); + if (new_environ == NULL) + { + /* It's easier to set errno to ENOMEM than to rely on the + 'malloc-posix' and 'realloc-posix' gnulib modules. */ + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + + /* If the whole entry is given add it. */ + if (combined != NULL) + /* We must not add the string to the search tree since it belongs + to the user. */ + new_environ[size] = (char *) combined; + else + { + /* See whether the value is already known. */ +#ifdef USE_TSEARCH +# ifdef _LIBC + new_value = (char *) alloca (namelen + 1 + vallen); + __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), + value, vallen); +# else + new_value = (char *) malloca (namelen + 1 + vallen); + if (new_value == NULL) + { + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + memcpy (new_value, name, namelen); + new_value[namelen] = '='; + memcpy (&new_value[namelen + 1], value, vallen); +# endif + + new_environ[size] = KNOWN_VALUE (new_value); + if (new_environ[size] == NULL) +#endif + { + new_environ[size] = (char *) malloc (namelen + 1 + vallen); + if (new_environ[size] == NULL) + { +#if defined USE_TSEARCH && !defined _LIBC + freea (new_value); +#endif + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + +#ifdef USE_TSEARCH + memcpy (new_environ[size], new_value, namelen + 1 + vallen); +#else + memcpy (new_environ[size], name, namelen); + new_environ[size][namelen] = '='; + memcpy (&new_environ[size][namelen + 1], value, vallen); +#endif + /* And save the value now. We cannot do this when we remove + the string since then we cannot decide whether it is a + user string or not. */ + STORE_VALUE (new_environ[size]); + } +#if defined USE_TSEARCH && !defined _LIBC + freea (new_value); +#endif + } + + if (__environ != last_environ) + memcpy ((char *) new_environ, (char *) __environ, + size * sizeof (char *)); + + new_environ[size + 1] = NULL; + + last_environ = __environ = new_environ; + } + else if (replace) + { + char *np; + + /* Use the user string if given. */ + if (combined != NULL) + np = (char *) combined; + else + { +#ifdef USE_TSEARCH + char *new_value; +# ifdef _LIBC + new_value = alloca (namelen + 1 + vallen); + __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), + value, vallen); +# else + new_value = malloca (namelen + 1 + vallen); + if (new_value == NULL) + { + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + memcpy (new_value, name, namelen); + new_value[namelen] = '='; + memcpy (&new_value[namelen + 1], value, vallen); +# endif + + np = KNOWN_VALUE (new_value); + if (np == NULL) +#endif + { + np = (char *) malloc (namelen + 1 + vallen); + if (np == NULL) + { +#if defined USE_TSEARCH && !defined _LIBC + freea (new_value); +#endif + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + +#ifdef USE_TSEARCH + memcpy (np, new_value, namelen + 1 + vallen); +#else + memcpy (np, name, namelen); + np[namelen] = '='; + memcpy (&np[namelen + 1], value, vallen); +#endif + /* And remember the value. */ + STORE_VALUE (np); + } +#if defined USE_TSEARCH && !defined _LIBC + freea (new_value); +#endif + } + + *ep = np; + } + + UNLOCK; + + return 0; +} + +int +setenv (const char *name, const char *value, int replace) +{ + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) + { + __set_errno (EINVAL); + return -1; + } + + return __add_to_environ (name, value, NULL, replace); +} + +/* The 'clearenv' was planned to be added to POSIX.1 but probably + never made it. Nevertheless the POSIX.9 standard (POSIX bindings + for Fortran 77) requires this function. */ +int +clearenv (void) +{ + LOCK; + + if (__environ == last_environ && __environ != NULL) + { + /* We allocated this environment so we can free it. */ + free (__environ); + last_environ = NULL; + } + + /* Clear the environment pointer removes the whole environment. */ + __environ = NULL; + + UNLOCK; + + return 0; +} + +#ifdef _LIBC +static void +free_mem (void) +{ + /* Remove all traces. */ + clearenv (); + + /* Now remove the search tree. */ + __tdestroy (known_values, free); + known_values = NULL; +} +text_set_element (__libc_subfreeres, free_mem); + + +# undef setenv +# undef clearenv +weak_alias (__setenv, setenv) +weak_alias (__clearenv, clearenv) +#endif + +#endif /* _LIBC || !HAVE_SETENV */ + +/* The rest of this file is called into use when replacing an existing + but buggy setenv. Known bugs include failure to diagnose invalid + name, and consuming a leading '=' from value. */ +#if HAVE_SETENV + +# undef setenv +# if !HAVE_DECL_SETENV +extern int setenv (const char *, const char *, int); +# endif +# define STREQ(a, b) (strcmp (a, b) == 0) + +int +rpl_setenv (const char *name, const char *value, int replace) +{ + int result; + if (!name || !*name || strchr (name, '=')) + { + errno = EINVAL; + return -1; + } + /* Call the real setenv even if replace is 0, in case implementation + has underlying data to update, such as when environ changes. */ + result = setenv (name, value, replace); + if (result == 0 && replace && *value == '=') + { + char *tmp = getenv (name); + if (!STREQ (tmp, value)) + { + int saved_errno; + size_t len = strlen (value); + tmp = malloca (len + 2); + /* Since leading '=' is eaten, double it up. */ + *tmp = '='; + memcpy (tmp + 1, value, len + 1); + result = setenv (name, tmp, replace); + saved_errno = errno; + freea (tmp); + errno = saved_errno; + } + } + return result; +} + +#endif /* HAVE_SETENV */ diff --git a/gnu/signal.in.h b/gnu/signal.in.h new file mode 100644 index 00000000..2fae59f2 --- /dev/null +++ b/gnu/signal.in.h @@ -0,0 +1,449 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A GNU-like <signal.h>. + + Copyright (C) 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#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 + <signal.h> -> <ucontext.h> -> <signal.h>. + 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 + <csignal> -> </usr/include/signal.h> -> <sys/ucontext.h> -> <signal.h>. + 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 <signal.h>, but in <sys/types.h>. + On Solaris 10, <signal.h> includes <sys/types.h>, which eventually includes + us; so include <sys/types.h> now, before the second inclusion guard. */ +#include <sys/types.h> + +/* 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 + +/* MacOS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6 declare + pthread_sigmask in <pthread.h>, not in <signal.h>. + 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 __GLIBC__ +# include <pthread.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. */ + +/* 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 *new_mask, sigset_t *old_mask)); +_GL_CXXALIAS_RPL (pthread_sigmask, int, + (int how, const sigset_t *new_mask, sigset_t *old_mask)); +# else +# if !@HAVE_PTHREAD_SIGMASK@ +_GL_FUNCDECL_SYS (pthread_sigmask, int, + (int how, const sigset_t *new_mask, sigset_t *old_mask)); +# endif +_GL_CXXALIAS_SYS (pthread_sigmask, int, + (int how, const sigset_t *new_mask, sigset_t *old_mask)); +# endif +_GL_CXXALIASWARN (pthread_sigmask); +#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 +_GL_CXXALIASWARN (raise); +#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 + +/* Test whether a given signal is contained in a signal set. */ +# if @HAVE_POSIX_SIGNALBLOCKING@ +/* This function is defined as a macro on MacOS 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 MacOS 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 MacOS 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 MacOS 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 MacOS 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 *set, sigset_t *old_set)); +# endif +_GL_CXXALIAS_SYS (sigprocmask, int, + (int operation, const sigset_t *set, sigset_t *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 +_GL_CXXALIAS_SYS (signal, _gl_function_taking_int_returning_void_t, + (int sig, _gl_function_taking_int_returning_void_t func)); +# endif +_GL_CXXALIASWARN (signal); + +# 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/gnu/size_max.h b/gnu/size_max.h new file mode 100644 index 00000000..2821e512 --- /dev/null +++ b/gnu/size_max.h @@ -0,0 +1,33 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* size_max.h -- declare SIZE_MAX through system headers + Copyright (C) 2005-2006, 2009-2012 Free Software Foundation, Inc. + Written by Simon Josefsson. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef GNULIB_SIZE_MAX_H +#define GNULIB_SIZE_MAX_H + +/* Get SIZE_MAX declaration on systems like Solaris 7/8/9. */ +# include <limits.h> +/* Get SIZE_MAX declaration on systems like glibc 2. */ +# if HAVE_STDINT_H +# include <stdint.h> +# 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/gnu/sleep.c b/gnu/sleep.c new file mode 100644 index 00000000..9ac3a29b --- /dev/null +++ b/gnu/sleep.c @@ -0,0 +1,78 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Pausing execution of the current thread. + Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2007. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#include <limits.h> + +#include "verify.h" + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include <windows.h> + +unsigned int +sleep (unsigned int seconds) +{ + unsigned int remaining; + + /* Sleep for 1 second many times, because + 1. Sleep is not interruptiple by Ctrl-C, + 2. we want to avoid arithmetic overflow while multiplying with 1000. */ + for (remaining = seconds; remaining > 0; remaining--) + Sleep (1000); + + return remaining; +} + +#elif HAVE_SLEEP + +# undef sleep + +/* Guarantee unlimited sleep and a reasonable return value. Cygwin + 1.5.x rejects attempts to sleep more than 49.7 days (2**32 + milliseconds), but uses uninitialized memory which results in a + garbage answer. Similarly, Linux 2.6.9 with glibc 2.3.4 has a too + small return value when asked to sleep more than 24.85 days. */ +unsigned int +rpl_sleep (unsigned int seconds) +{ + /* This requires int larger than 16 bits. */ + verify (UINT_MAX / 24 / 24 / 60 / 60); + const unsigned int limit = 24 * 24 * 60 * 60; + while (limit < seconds) + { + unsigned int result; + seconds -= limit; + result = sleep (limit); + if (result) + return seconds + result; + } + return sleep (seconds); +} + +#else /* !HAVE_SLEEP */ + + #error "Please port gnulib sleep.c to your platform, possibly using usleep() or select(), then report this to bug-gnulib." + +#endif diff --git a/gnu/snprintf.c b/gnu/snprintf.c new file mode 100644 index 00000000..99b51b48 --- /dev/null +++ b/gnu/snprintf.c @@ -0,0 +1,74 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Formatted output to strings. + Copyright (C) 2004, 2006-2012 Free Software Foundation, Inc. + Written by Simon Josefsson and Paul Eggert. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include <stdio.h> + +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#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/gnu/stat-macros.h b/gnu/stat-macros.h new file mode 100644 index 00000000..00112cef --- /dev/null +++ b/gnu/stat-macros.h @@ -0,0 +1,5 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* All the mode bits that can be affected by chmod. */ +#define CHMOD_MODE_BITS \ + (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) diff --git a/gnu/stat-time.h b/gnu/stat-time.h new file mode 100644 index 00000000..54a94461 --- /dev/null +++ b/gnu/stat-time.h @@ -0,0 +1,191 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* stat-related time functions. + + Copyright (C) 2005, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#ifndef STAT_TIME_H +#define STAT_TIME_H 1 + +#include <sys/stat.h> +#include <time.h> + +/* 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 defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC +# ifdef 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. */ +static inline long int +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. */ +static inline long int +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. */ +static inline long int +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. */ +static inline long int +get_stat_birthtime_ns (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 + /* Avoid a "parameter unused" warning. */ + (void) st; + return 0; +# endif +} + +/* Return *ST's access time. */ +static inline struct timespec +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. */ +static inline struct timespec +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. */ +static inline struct timespec +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. */ +static inline struct timespec +get_stat_birthtime (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 __WIN32__) && ! defined __CYGWIN__ + /* Native Windows platforms (but not Cygwin) put the "file creation + time" in st_ctime (!). See + <http://msdn2.microsoft.com/de-de/library/14h5k7ff(VS.80).aspx>. */ + t.tv_sec = st->st_ctime; + t.tv_nsec = 0; +#else + /* Birth time is not supported. */ + t.tv_sec = -1; + t.tv_nsec = -1; + /* Avoid a "parameter unused" warning. */ + (void) st; +#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 time stamps. 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; +} + +#endif diff --git a/gnu/stat.c b/gnu/stat.c new file mode 100644 index 00000000..9df74d6c --- /dev/null +++ b/gnu/stat.c @@ -0,0 +1,125 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Work around platform bugs in stat. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +/* If the user's config.h happens to include <sys/stat.h>, let it include only + the system's <sys/stat.h> here, so that orig_stat doesn't recurse to + rpl_stat. */ +#define __need_system_sys_stat_h +#include <config.h> + +/* Get the original definition of stat. It might be defined as a macro. */ +#include <sys/types.h> +#include <sys/stat.h> +#undef __need_system_sys_stat_h + +static inline int +orig_stat (const char *filename, struct stat *buf) +{ + return stat (filename, buf); +} + +/* Specification. */ +/* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc + eliminates this include because of the preliminary #include <sys/stat.h> + above. */ +#include "sys/stat.h" + +#include <errno.h> +#include <limits.h> +#include <stdbool.h> +#include <string.h> +#include "dosname.h" +#include "verify.h" + +#if REPLACE_FUNC_STAT_DIR +# include "pathmax.h" + /* The only known systems where REPLACE_FUNC_STAT_DIR is needed also + have a constant PATH_MAX. */ +# ifndef PATH_MAX +# error "Please port this replacement to your platform" +# endif +#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 *st) +{ + int result = orig_stat (name, st); +#if REPLACE_FUNC_STAT_FILE + /* Solaris 9 mistakenly succeeds when given a non-directory with a + trailing slash. */ + if (result == 0 && !S_ISDIR (st->st_mode)) + { + size_t len = strlen (name); + if (ISSLASH (name[len - 1])) + { + errno = ENOTDIR; + return -1; + } + } +#endif /* REPLACE_FUNC_STAT_FILE */ +#if REPLACE_FUNC_STAT_DIR + + if (result == -1 && errno == ENOENT) + { + /* Due to mingw's oddities, there are some directories (like + c:\) where stat() only succeeds with a trailing slash, and + other directories (like c:\windows) where stat() only + succeeds without a trailing slash. But we want the two to be + synonymous, since chdir() manages either style. Likewise, Mingw also + reports ENOENT for names longer than PATH_MAX, when we want + ENAMETOOLONG, and for stat("file/"), when we want ENOTDIR. + Fortunately, mingw PATH_MAX is small enough for stack + allocation. */ + char fixed_name[PATH_MAX + 1] = {0}; + size_t len = strlen (name); + bool check_dir = false; + verify (PATH_MAX <= 4096); + if (PATH_MAX <= len) + errno = ENAMETOOLONG; + else if (len) + { + strcpy (fixed_name, name); + if (ISSLASH (fixed_name[len - 1])) + { + check_dir = true; + while (len && ISSLASH (fixed_name[len - 1])) + fixed_name[--len] = '\0'; + if (!len) + fixed_name[0] = '/'; + } + else + fixed_name[len++] = '/'; + result = orig_stat (fixed_name, st); + if (result == 0 && check_dir && !S_ISDIR (st->st_mode)) + { + result = -1; + errno = ENOTDIR; + } + } + } +#endif /* REPLACE_FUNC_STAT_DIR */ + return result; +} diff --git a/gnu/stdalign.in.h b/gnu/stdalign.in.h new file mode 100644 index 00000000..c57a5a64 --- /dev/null +++ b/gnu/stdalign.in.h @@ -0,0 +1,93 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A substitute for ISO C11 <stdalign.h>. + + Copyright 2011-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Paul Eggert and Bruno Haible. */ + +#ifndef _GL_STDALIGN_H +#define _GL_STDALIGN_H + +/* ISO C11 <stdalign.h> for platforms that lack it. + + References: + ISO C11 (latest free draft + <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>) + sections 6.5.3.4, 6.7.5, 7.15. + C++11 (latest free draft + <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf>) + 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 __alignof__ operator, which can yield a + better-performing alignment for an object of that type. For + example, on x86 with GCC, __alignof__ (double) and __alignof__ + (long long) are 8, whereas alignof (double) and alignof (long long) + are 4 unless the option '-malign-double' is used. + + 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 <stddef.h> +#if defined __cplusplus + template <class __t> struct __alignof_helper { char __a; __t __b; }; +# define _Alignof(type) offsetof (__alignof_helper<type>, __b) +#else +# define _Alignof(type) offsetof (struct { char __a; type __b; }, __b) +#endif +#define alignof _Alignof +#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 __GNUC__ || __IBMC__ || __IBMCPP__ || 0x5110 <= __SUNPRO_C +# define _Alignas(a) __attribute__ ((__aligned__ (a))) +#elif 1300 <= _MSC_VER +# define _Alignas(a) __declspec (align (a)) +#endif +#ifdef _Alignas +# define alignas _Alignas +# define __alignas_is_defined 1 +#endif + +#endif /* _GL_STDALIGN_H */ diff --git a/gnu/stdarg.in.h b/gnu/stdarg.in.h new file mode 100644 index 00000000..6cbe8bf4 --- /dev/null +++ b/gnu/stdarg.in.h @@ -0,0 +1,38 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Substitute for and wrapper around <stdarg.h>. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _@GUARD_PREFIX@_STDARG_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STDARG_H@ + +#ifndef _@GUARD_PREFIX@_STDARG_H +#define _@GUARD_PREFIX@_STDARG_H + +#ifndef va_copy +# define va_copy(a,b) ((a) = (b)) +#endif + +#endif /* _@GUARD_PREFIX@_STDARG_H */ +#endif /* _@GUARD_PREFIX@_STDARG_H */ diff --git a/gnu/stdbool.in.h b/gnu/stdbool.in.h new file mode 100644 index 00000000..80a2d148 --- /dev/null +++ b/gnu/stdbool.in.h @@ -0,0 +1,124 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 2001-2003, 2006-2012 Free Software Foundation, Inc. + Written by Bruno Haible <haible@clisp.cons.org>, 2001. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_STDBOOL_H +#define _GL_STDBOOL_H + +/* ISO C 99 <stdbool.h> for platforms that lack it. */ + +/* Usage suggestions: + + Programs that use <stdbool.h> should be aware of some limitations + and standards compliance issues. + + Standards compliance: + + - <stdbool.h> 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: + + - <stdbool.h> 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 <sys/socket.h> 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 <OS.h> /* defines bool but not _Bool */ +# undef false +# undef true +#endif + +/* For the sake of symbolic names in gdb, we 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 if we do + this, values of type '_Bool' may 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 we add a negative value to the + enum; this ensures that '_Bool' promotes to 'int'. */ +#if defined __cplusplus || (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 + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html + Similar bugs are likely with other compilers as well; this file + wouldn't be used if <stdbool.h> 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@ +typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool; +# endif +# endif +#endif +#define bool _Bool + +/* The other macros must be usable in preprocessor directives. */ +#define false 0 +#define true 1 +#define __bool_true_false_are_defined 1 + +#endif /* _GL_STDBOOL_H */ diff --git a/gnu/stddef.in.h b/gnu/stddef.in.h new file mode 100644 index 00000000..9684b739 --- /dev/null +++ b/gnu/stddef.in.h @@ -0,0 +1,89 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues. + + Copyright (C) 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Eric Blake. */ + +/* + * POSIX 2008 <stddef.h> for platforms that have issues. + * <http://www.opengroup.org/susv3xbd/stddef.h.html> + */ + +#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 <stddef.h> that blindly + redefines NULL even when __need_wint_t was defined, even though + wint_t is not normally provided by <stddef.h>. 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 +# undef _@GUARD_PREFIX@_STDDEF_H +# define _GL_STDDEF_WINT_T +# endif +# @INCLUDE_NEXT@ @NEXT_STDDEF_H@ +# endif + +#else +/* Normal invocation convention. */ + +# ifndef _@GUARD_PREFIX@_STDDEF_H + +/* The include_next requires a split double-inclusion guard. */ + +# @INCLUDE_NEXT@ @NEXT_STDDEF_H@ + +# ifndef _@GUARD_PREFIX@_STDDEF_H +# define _@GUARD_PREFIX@_STDDEF_H + +/* On NetBSD 5.0, the definition of NULL lacks proper parentheses. */ +#if @REPLACE_NULL@ +# undef NULL +# ifdef __cplusplus + /* 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 + +/* Some platforms lack wchar_t. */ +#if !@HAVE_WCHAR_T@ +# define wchar_t int +#endif + +# endif /* _@GUARD_PREFIX@_STDDEF_H */ +# endif /* _@GUARD_PREFIX@_STDDEF_H */ +#endif /* __need_XXX */ diff --git a/gnu/stdint.in.h b/gnu/stdint.in.h new file mode 100644 index 00000000..7796840b --- /dev/null +++ b/gnu/stdint.in.h @@ -0,0 +1,611 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 2001-2002, 2004-2012 Free Software Foundation, Inc. + Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. + This file is part of gnulib. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* + * ISO C 99 <stdint.h> for platforms that lack it. + * <http://www.opengroup.org/susv3xbd/stdint.h.html> + */ + +#ifndef _@GUARD_PREFIX@_STDINT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* When including a system file that in turn includes <inttypes.h>, + use the system <inttypes.h>, not our substitute. This avoids + problems with (for example) VMS, whose <sys/bitypes.h> includes + <inttypes.h>. */ +#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + +/* 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 <stdint.h> 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 <stdint.h> 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 <stdint.h>. + Include it before <inttypes.h>, since any "#include <stdint.h>" + in <inttypes.h> 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 + +/* <sys/types.h> defines some of the stdint.h types as well, on glibc, + IRIX 6.5, and OpenBSD 3.8 (via <machine/types.h>). + AIX 5.2 <sys/types.h> isn't needed and causes troubles. + MacOS X 10.4.6 <sys/types.h> includes <stdint.h> (which is us), but + relies on the system <stdint.h> definitions, so include + <sys/types.h> after @NEXT_STDINT_H@. */ +#if @HAVE_SYS_TYPES_H@ && ! defined _AIX +# include <sys/types.h> +#endif + +/* Get LONG_MIN, LONG_MAX, ULONG_MAX. */ +#include <limits.h> + +#if @HAVE_INTTYPES_H@ + /* In OpenBSD 3.8, <inttypes.h> includes <machine/types.h>, which defines + int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__. + <inttypes.h> also defines intptr_t and uintptr_t. */ +# include <inttypes.h> +#elif @HAVE_SYS_INTTYPES_H@ + /* Solaris 7 <sys/inttypes.h> has the types except the *_fast*_t types, and + the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ +# include <sys/inttypes.h> +#endif + +#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__ + /* Linux libc4 >= 4.6.7 and libc5 have a <sys/bitypes.h> that defines + int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is + included by <sys/types.h>. */ +# include <sys/bitypes.h> +#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. */ + +#define _STDINT_MIN(signed, bits, zero) \ + ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero)) + +#define _STDINT_MAX(signed, bits, zero) \ + ((signed) \ + ? ~ _STDINT_MIN (signed, bits, zero) \ + : /* The expression for the unsigned case. The subtraction of (signed) \ + is a nop in the unsigned case and avoids "signed integer overflow" \ + warnings in the signed case. */ \ + ((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) + +#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 +# elif @HAVE_LONG_LONG_INT@ +# 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 +# elif @HAVE_UNSIGNED_LONG_LONG_INT@ +# 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 <pthread.h> 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 <stdint.h> 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. Assume that 'long int' + is fast enough for all narrower integers. */ + +#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 long int gl_int_fast8_t; +typedef unsigned long int gl_uint_fast8_t; +typedef long int gl_int_fast16_t; +typedef unsigned long int gl_uint_fast16_t; +typedef long int gl_int_fast32_t; +typedef unsigned long int gl_uint_fast32_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 */ + +#undef intptr_t +#undef uintptr_t +typedef long int gl_intptr_t; +typedef unsigned long int gl_uintptr_t; +#define intptr_t gl_intptr_t +#define uintptr_t gl_uintptr_t + +/* 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 @HAVE_LONG_LONG_INT@ && 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 @HAVE_UNSIGNED_LONG_LONG_INT@ && 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 LONG_MIN +#define INT_FAST8_MAX LONG_MAX +#define UINT_FAST8_MAX ULONG_MAX + +#undef INT_FAST16_MIN +#undef INT_FAST16_MAX +#undef UINT_FAST16_MAX +#define INT_FAST16_MIN LONG_MIN +#define INT_FAST16_MAX LONG_MAX +#define UINT_FAST16_MAX ULONG_MAX + +#undef INT_FAST32_MIN +#undef INT_FAST32_MAX +#undef UINT_FAST32_MAX +#define INT_FAST32_MIN LONG_MIN +#define INT_FAST32_MAX LONG_MAX +#define UINT_FAST32_MAX ULONG_MAX + +#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 +#define INTPTR_MIN LONG_MIN +#define INTPTR_MAX LONG_MAX +#define UINTPTR_MAX ULONG_MAX + +/* 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_MIN (1, 64, 0l) +# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) +# else +# define PTRDIFF_MIN _STDINT_MIN (1, 32, 0) +# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) +# endif +#else +# define PTRDIFF_MIN \ + _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +# define PTRDIFF_MAX \ + _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +#endif + +/* sig_atomic_t limits */ +#undef SIG_ATOMIC_MIN +#undef SIG_ATOMIC_MAX +#define SIG_ATOMIC_MIN \ + _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ + 0@SIG_ATOMIC_T_SUFFIX@) +#define SIG_ATOMIC_MAX \ + _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 + <wchar.h> -> <stdio.h> -> <getopt.h> -> <stdlib.h>, and the latter includes + <stdint.h> and assumes its types are already defined. */ +#if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX) + /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be + included before <wchar.h>. */ +# include <stddef.h> +# include <stdio.h> +# include <time.h> +# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +# include <wchar.h> +# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +#endif +#undef WCHAR_MIN +#undef WCHAR_MAX +#define WCHAR_MIN \ + _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) +#define WCHAR_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) + +/* wint_t limits */ +#undef WINT_MIN +#undef WINT_MAX +#define WINT_MIN \ + _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +#define WINT_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) + +/* 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 +#elif @HAVE_LONG_LONG_INT@ +# define INT64_C(x) x##LL +#endif +#if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# define UINT64_C(x) x##UL +#elif defined _MSC_VER +# define UINT64_C(x) x##ui64 +#elif @HAVE_UNSIGNED_LONG_LONG_INT@ +# define UINT64_C(x) x##ULL +#endif + +/* 7.18.4.2. Macros for greatest-width integer constants */ + +#ifndef INTMAX_C +# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +# define INTMAX_C(x) x##LL +# elif defined GL_INT64_T +# define INTMAX_C(x) INT64_C(x) +# else +# define INTMAX_C(x) x##L +# endif +#endif + +#ifndef UINTMAX_C +# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +# define UINTMAX_C(x) x##ULL +# elif defined GL_UINT64_T +# define UINTMAX_C(x) UINT64_C(x) +# else +# define UINTMAX_C(x) x##UL +# endif +#endif + +#endif /* _@GUARD_PREFIX@_STDINT_H */ +#endif /* !defined _@GUARD_PREFIX@_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ diff --git a/gnu/stdio-impl.h b/gnu/stdio-impl.h new file mode 100644 index 00000000..874df7e0 --- /dev/null +++ b/gnu/stdio-impl.h @@ -0,0 +1,112 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Implementation details of FILE streams. + Copyright (C) 2007-2008, 2010-2012 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 <http://www.gnu.org/licenses/>. */ + +/* 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. */ + + +/* BSD stdio derived implementations. */ + +#if defined __NetBSD__ /* NetBSD */ +/* Get __NetBSD_Version__. */ +# include <sys/param.h> +#endif + +#if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ + +# if defined __DragonFly__ /* DragonFly */ + /* See <http://www.dragonflybsd.org/cvsweb/src/lib/libc/stdio/priv_stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>. */ +# 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 <http://www.dragonflybsd.org/cvsweb/src/include/stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>. */ +# define _p pub._p +# define _flags pub._flags +# define _r pub._r +# define _w pub._w +# else +# define fp_ fp +# endif + +# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ /* NetBSD >= 1.5ZA, OpenBSD */ + /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> + and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */ + struct __sfileext + { + struct __sbuf _ub; /* ungetc buffer */ + /* More fields, not relevant here. */ + }; +# define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub +# else /* FreeBSD, NetBSD <= 1.5Z, DragonFly, MacOS X, Cygwin */ +# define fp_ub fp_->_ub +# endif + +# define HASUB(fp) (fp_ub._base != NULL) + +#endif + + +/* SystemV derived implementations. */ + +#ifdef __TANDEM /* NonStop Kernel */ +# ifndef _IOERR +/* These values were determined by the program 'stdioext-flags' at + <http://lists.gnu.org/archive/html/bug-gnulib/2010-12/msg00165.html>. */ +# 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) +# else +# define fp_ fp +# endif + +# if defined _SCO_DS /* OpenServer */ +# define _cnt __cnt +# define _ptr __ptr +# define _base __base +# define _flag __flag +# endif + +#endif diff --git a/gnu/stdio.in.h b/gnu/stdio.in.h new file mode 100644 index 00000000..62c68015 --- /dev/null +++ b/gnu/stdio.in.h @@ -0,0 +1,1352 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A GNU-like <stdio.h>. + + Copyright (C) 2004, 2007-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#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 + <stdio.h> -> <getopt.h> -> <ctype.h> -> <sys/localedef.h> -> + <sys/lc_core.h> -> <nl_types.h> -> <mesg.h> -> <stdio.h>. + 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 <stdarg.h> + +#include <stddef.h> + +/* Get off_t and ssize_t. Needed on many systems, including glibc 2.8 + and eglibc 2.11.2. */ +#include <sys/types.h> + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ +#endif + +/* _GL_ATTRIBUTE_FORMAT_PRINTF + indicates to GCC that the function takes a format string and arguments, + where the format string directives are the ones standardized by ISO C99 + and POSIX. */ +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) +# define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter, first_argument) \ + _GL_ATTRIBUTE_FORMAT ((__gnu_printf__, formatstring_parameter, first_argument)) +#else +# define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter, first_argument) \ + _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) +#endif + +/* _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM is like _GL_ATTRIBUTE_FORMAT_PRINTF, + except that it indicates to GCC that the supported format string directives + are the ones of the system printf(), rather than the ones standardized by + ISO C99 and POSIX. */ +#define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ + _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) + +/* _GL_ATTRIBUTE_FORMAT_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)) + +/* Solaris 10 declares renameat in <unistd.h>, not in <stdio.h>. */ +/* But in any case avoid namespace pollution on glibc systems. */ +#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __sun \ + && ! defined __GLIBC__ +# include <unistd.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. */ + +/* Macros for stringification. */ +#define _GL_STDIO_STRINGIZE(token) #token +#define _GL_STDIO_MACROEXPAND_AND_STRINGIZE(token) _GL_STDIO_STRINGIZE(token) + + +#if @GNULIB_DPRINTF@ +# if @REPLACE_DPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define dprintf rpl_dprintf +# endif +_GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *format, ...)); +# else +# if !@HAVE_DPRINTF@ +_GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (dprintf, int, (int fd, const char *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 +_GL_CXXALIASWARN (fclose); +#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_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_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode)); +# else +_GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode)); +# endif +_GL_CXXALIASWARN (fdopen); +#elif 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"); +#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 +_GL_CXXALIASWARN (fflush); +#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 +_GL_CXXALIASWARN (fgetc); +#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 *s, int n, FILE *stream) + _GL_ARG_NONNULL ((1, 3))); +_GL_CXXALIAS_RPL (fgets, char *, (char *s, int n, FILE *stream)); +# else +_GL_CXXALIAS_SYS (fgets, char *, (char *s, int n, FILE *stream)); +# endif +_GL_CXXALIASWARN (fgets); +#endif + +#if @GNULIB_FOPEN@ +# if @REPLACE_FOPEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fopen +# define fopen rpl_fopen +# endif +_GL_FUNCDECL_RPL (fopen, FILE *, (const char *filename, const char *mode) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (fopen, FILE *, (const char *filename, const char *mode)); +# else +_GL_CXXALIAS_SYS (fopen, FILE *, (const char *filename, const char *mode)); +# endif +_GL_CXXALIASWARN (fopen); +#elif 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 + +#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 *fp, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((1, 2))); +# else +_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 3) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_RPL (fprintf, int, (FILE *fp, const char *format, ...)); +# else +_GL_CXXALIAS_SYS (fprintf, int, (FILE *fp, const char *format, ...)); +# endif +_GL_CXXALIASWARN (fprintf); +#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 +_GL_CXXALIASWARN (fputc); +#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 *string, FILE *stream) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (fputs, int, (const char *string, FILE *stream)); +# else +_GL_CXXALIAS_SYS (fputs, int, (const char *string, FILE *stream)); +# endif +_GL_CXXALIASWARN (fputs); +#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 *ptr, size_t s, size_t n, FILE *stream) + _GL_ARG_NONNULL ((4))); +_GL_CXXALIAS_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)); +# else +_GL_CXXALIAS_SYS (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)); +# endif +_GL_CXXALIASWARN (fread); +#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 *filename, const char *mode, FILE *stream) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (freopen, FILE *, + (const char *filename, const char *mode, FILE *stream)); +# else +_GL_CXXALIAS_SYS (freopen, FILE *, + (const char *filename, const char *mode, FILE *stream)); +# endif +_GL_CXXALIASWARN (freopen); +#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 *stream, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (fscanf, int, (FILE *stream, const char *format, ...)); +# else +_GL_CXXALIAS_SYS (fscanf, int, (FILE *stream, const char *format, ...)); +# endif +_GL_CXXALIASWARN (fscanf); +#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 +_GL_CXXALIASWARN (fseek); +#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 +_GL_CXXALIASWARN (ftell); +#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 *ptr, size_t s, size_t n, FILE *stream) + _GL_ARG_NONNULL ((1, 4))); +_GL_CXXALIAS_RPL (fwrite, size_t, + (const void *ptr, size_t s, size_t n, FILE *stream)); +# else +_GL_CXXALIAS_SYS (fwrite, size_t, + (const void *ptr, size_t s, size_t n, FILE *stream)); + +/* Work around glibc bug 11959 + <http://sources.redhat.com/bugzilla/show_bug.cgi?id=11959>, + which sometimes causes an unwanted diagnostic for fwrite calls. + This affects only function declaration attributes, so it's not + needed for C++. */ +# if !defined __cplusplus && 0 < __USE_FORTIFY_LEVEL +static inline size_t _GL_ARG_NONNULL ((1, 4)) +rpl_fwrite (const void *ptr, size_t s, size_t n, FILE *stream) +{ + size_t r = fwrite (ptr, s, n, stream); + (void) r; + return r; +} +# undef fwrite +# define fwrite rpl_fwrite +# endif +# endif +_GL_CXXALIASWARN (fwrite); +#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 +_GL_CXXALIASWARN (getc); +#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 +_GL_CXXALIASWARN (getchar); +#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 **lineptr, size_t *linesize, int delimiter, + FILE *stream) + _GL_ARG_NONNULL ((1, 2, 4))); +_GL_CXXALIAS_RPL (getdelim, ssize_t, + (char **lineptr, size_t *linesize, int delimiter, + FILE *stream)); +# else +# if !@HAVE_DECL_GETDELIM@ +_GL_FUNCDECL_SYS (getdelim, ssize_t, + (char **lineptr, size_t *linesize, int delimiter, + FILE *stream) + _GL_ARG_NONNULL ((1, 2, 4))); +# endif +_GL_CXXALIAS_SYS (getdelim, ssize_t, + (char **lineptr, size_t *linesize, int delimiter, + FILE *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 **lineptr, size_t *linesize, FILE *stream) + _GL_ARG_NONNULL ((1, 2, 3))); +_GL_CXXALIAS_RPL (getline, ssize_t, + (char **lineptr, size_t *linesize, FILE *stream)); +# else +# if !@HAVE_DECL_GETLINE@ +_GL_FUNCDECL_SYS (getline, ssize_t, + (char **lineptr, size_t *linesize, FILE *stream) + _GL_ARG_NONNULL ((1, 2, 3))); +# endif +_GL_CXXALIAS_SYS (getline, ssize_t, + (char **lineptr, size_t *linesize, FILE *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 + +#if @GNULIB_GETS@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gets +# define gets rpl_gets +# endif +_GL_FUNCDECL_RPL (gets, char *, (char *s) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (gets, char *, (char *s)); +# else +_GL_CXXALIAS_SYS (gets, char *, (char *s)); +# undef gets +# endif +_GL_CXXALIASWARN (gets); +/* It is very rare that the developer ever has full control of stdin, + so any use of gets warrants an unconditional warning. Assume it is + always declared, since it is required by C89. */ +_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); +#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 (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 (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 (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 (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, "popen 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 +_GL_CXXALIASWARN (perror); +#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_CXXALIAS_RPL (popen, FILE *, (const char *cmd, const char *mode)); +# else +# if !@HAVE_POPEN@ +_GL_FUNCDECL_SYS (popen, FILE *, (const char *cmd, const char *mode) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (popen, FILE *, (const char *cmd, const char *mode)); +# endif +_GL_CXXALIASWARN (popen); +#elif defined GNULIB_POSIXCHECK +# undef popen +# if HAVE_RAW_DECL_POPEN +_GL_WARN_ON_USE (popen, "popen is buggy on some platforms - " + "use gnulib module popen or pipe for more portability"); +# endif +#endif + +#if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@ +# if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \ + || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) +# if defined __GNUC__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +/* Don't break __attribute__((format(printf,M,N))). */ +# define printf __printf__ +# endif +# if @GNULIB_PRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ +_GL_FUNCDECL_RPL_1 (__printf__, int, + (const char *format, ...) + __asm__ (@ASM_SYMBOL_PREFIX@ + _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) + _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2) + _GL_ARG_NONNULL ((1))); +# else +_GL_FUNCDECL_RPL_1 (__printf__, int, + (const char *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 *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (printf, int, (const char *format, ...)); +# endif +# define GNULIB_overrides_printf 1 +# else +_GL_CXXALIAS_SYS (printf, int, (const char *format, ...)); +# endif +_GL_CXXALIASWARN (printf); +#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 +_GL_CXXALIASWARN (putc); +#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 +_GL_CXXALIASWARN (putchar); +#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 +_GL_CXXALIASWARN (puts); +#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 +_GL_CXXALIASWARN (remove); +#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 +_GL_CXXALIASWARN (rename); +#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__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef scanf +/* Don't break __attribute__((format(scanf,M,N))). */ +# define scanf __scanf__ +# endif +_GL_FUNCDECL_RPL_1 (__scanf__, int, + (const char *format, ...) + __asm__ (@ASM_SYMBOL_PREFIX@ + _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_scanf)) + _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *format, ...)); +# else +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef scanf +# define scanf rpl_scanf +# endif +_GL_FUNCDECL_RPL (scanf, int, (const char *format, ...) + _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (scanf, int, (const char *format, ...)); +# endif +# else +_GL_CXXALIAS_SYS (scanf, int, (const char *format, ...)); +# endif +_GL_CXXALIASWARN (scanf); +#endif + +#if @GNULIB_SNPRINTF@ +# if @REPLACE_SNPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define snprintf rpl_snprintf +# endif +_GL_FUNCDECL_RPL (snprintf, int, + (char *str, size_t size, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4) + _GL_ARG_NONNULL ((3))); +_GL_CXXALIAS_RPL (snprintf, int, + (char *str, size_t size, const char *format, ...)); +# else +# if !@HAVE_DECL_SNPRINTF@ +_GL_FUNCDECL_SYS (snprintf, int, + (char *str, size_t size, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4) + _GL_ARG_NONNULL ((3))); +# endif +_GL_CXXALIAS_SYS (snprintf, int, + (char *str, size_t size, const char *format, ...)); +# endif +_GL_CXXALIASWARN (snprintf); +#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 sprintf should be handled like gets + (for example, OpenBSD issues a link warning for both functions), + since both 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 +_GL_FUNCDECL_RPL (sprintf, int, (char *str, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (sprintf, int, (char *str, const char *format, ...)); +# else +_GL_CXXALIAS_SYS (sprintf, int, (char *str, const char *format, ...)); +# endif +_GL_CXXALIASWARN (sprintf); +#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_TMPFILE@ +# if @REPLACE_TMPFILE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define tmpfile rpl_tmpfile +# endif +_GL_FUNCDECL_RPL (tmpfile, FILE *, (void)); +_GL_CXXALIAS_RPL (tmpfile, FILE *, (void)); +# else +_GL_CXXALIAS_SYS (tmpfile, FILE *, (void)); +# endif +_GL_CXXALIASWARN (tmpfile); +#elif 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 + +#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 +_GL_FUNCDECL_RPL (asprintf, int, + (char **result, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF (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 (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 +_GL_FUNCDECL_RPL (vasprintf, int, + (char **result, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF (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 (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 *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (vdprintf, int, (int fd, const char *format, va_list args)); +# else +# if !@HAVE_VDPRINTF@ +_GL_FUNCDECL_SYS (vdprintf, int, (int fd, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((2))); +# endif +/* Need to cast, because on Solaris, the third parameter will likely be + __va_list args. */ +_GL_CXXALIAS_SYS_CAST (vdprintf, int, + (int fd, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vdprintf); +#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 *fp, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((1, 2))); +# else +_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 0) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args)); +# else +/* Need to cast, because on Solaris, the third parameter is + __va_list args + and GCC's fixincludes did not change this to __gnuc_va_list. */ +_GL_CXXALIAS_SYS_CAST (vfprintf, int, + (FILE *fp, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vfprintf); +#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 *stream, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 0) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (vfscanf, int, + (FILE *stream, const char *format, va_list args)); +# else +_GL_CXXALIAS_SYS (vfscanf, int, + (FILE *stream, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vfscanf); +#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 *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF (1, 0) + _GL_ARG_NONNULL ((1))); +# else +_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 0) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_RPL (vprintf, int, (const char *format, va_list args)); +# else +/* Need to cast, because on Solaris, the second parameter is + __va_list args + and GCC's fixincludes did not change this to __gnuc_va_list. */ +_GL_CXXALIAS_SYS_CAST (vprintf, int, (const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vprintf); +#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 *format, va_list args) + _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 0) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (vscanf, int, (const char *format, va_list args)); +# else +_GL_CXXALIAS_SYS (vscanf, int, (const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vscanf); +#endif + +#if @GNULIB_VSNPRINTF@ +# if @REPLACE_VSNPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vsnprintf rpl_vsnprintf +# endif +_GL_FUNCDECL_RPL (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) + _GL_ARG_NONNULL ((3))); +_GL_CXXALIAS_RPL (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args)); +# else +# if !@HAVE_DECL_VSNPRINTF@ +_GL_FUNCDECL_SYS (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) + _GL_ARG_NONNULL ((3))); +# endif +_GL_CXXALIAS_SYS (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vsnprintf); +#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 +_GL_FUNCDECL_RPL (vsprintf, int, + (char *str, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (vsprintf, int, + (char *str, const char *format, va_list args)); +# else +/* Need to cast, because on Solaris, the third parameter is + __va_list args + and GCC's fixincludes did not change this to __gnuc_va_list. */ +_GL_CXXALIAS_SYS_CAST (vsprintf, int, + (char *str, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vsprintf); +#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/gnu/stdlib.in.h b/gnu/stdlib.in.h new file mode 100644 index 00000000..8928e4ab --- /dev/null +++ b/gnu/stdlib.in.h @@ -0,0 +1,920 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A GNU-like <stdlib.h>. + + Copyright (C) 1995, 2001-2004, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined __need_malloc_and_calloc +/* Special invocation convention inside glibc header files. */ + +#@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 <stddef.h> + +/* MirBSD 10 defines WEXITSTATUS in <sys/wait.h>, not in <stdlib.h>. */ +#if @GNULIB_SYSTEM_POSIX@ && !defined WEXITSTATUS +# include <sys/wait.h> +#endif + +/* Solaris declares getloadavg() in <sys/loadavg.h>. */ +#if (@GNULIB_GETLOADAVG@ || defined GNULIB_POSIXCHECK) && @HAVE_SYS_LOADAVG_H@ +# include <sys/loadavg.h> +#endif + +/* Native Windows platforms declare mktemp() in <io.h>. */ +#if 0 && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +# include <io.h> +#endif + +#if @GNULIB_RANDOM_R@ + +/* OSF/1 5.1 declares 'struct random_data' in <random.h>, which is included + from <stdlib.h> if _REENTRANT is defined. Include it whenever we need + 'struct random_data'. */ +# if @HAVE_RANDOM_H@ +# include <random.h> +# endif + +# if !@HAVE_STRUCT_RANDOM_DATA@ || @REPLACE_RANDOM_R@ || !@HAVE_RANDOM_R@ +# include <stdint.h> +# endif + +# if !@HAVE_STRUCT_RANDOM_DATA@ +/* Define 'struct random_data'. + But allow multiple gnulib generated <stdlib.h> 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_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +/* On MacOS X 10.3, only <unistd.h> declares mkstemp. */ +/* On MacOS X 10.5, only <unistd.h> declares mkstemps. */ +/* On Cygwin 1.7.1, only <unistd.h> declares getsubopt. */ +/* But avoid namespace pollution on glibc systems and native Windows. */ +# include <unistd.h> +#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_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_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 @REPLACE_CALLOC@ +# 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_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size)); +# else +_GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size)); +# endif +_GL_CXXALIASWARN (calloc); +#elif 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 + +#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_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name)); +# else +# if !@HAVE_CANONICALIZE_FILE_NAME@ +_GL_FUNCDECL_SYS (canonicalize_file_name, char *, (const char *name) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name)); +# endif +_GL_CXXALIASWARN (canonicalize_file_name); +#elif 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 + +#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:2001 specification. + http://www.opengroup.org/susv3xsh/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 @REPLACE_MALLOC@ +# 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_CXXALIAS_RPL (malloc, void *, (size_t size)); +# else +_GL_CXXALIAS_SYS (malloc, void *, (size_t size)); +# endif +_GL_CXXALIASWARN (malloc); +#elif 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 + +/* 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 *pwc, const char *s, size_t n)); +_GL_CXXALIAS_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); +# else +_GL_CXXALIAS_SYS (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); +# endif +_GL_CXXALIASWARN (mbtowc); +#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 <fcntl.h>) + 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 <fcntl.h>) + 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_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 !@HAVE_PTSNAME@ +_GL_FUNCDECL_SYS (ptsname, char *, (int fd)); +# endif +_GL_CXXALIAS_SYS (ptsname, char *, (int fd)); +_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 +_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)); +# else +_GL_CXXALIAS_SYS (putenv, int, (char *string)); +# endif +_GL_CXXALIASWARN (putenv); +#endif + + +#if @GNULIB_RANDOM_R@ +# if !@HAVE_RANDOM_R@ +# ifndef RAND_MAX +# define RAND_MAX 2147483647 +# endif +# endif +#endif + + +#if @GNULIB_RANDOM@ +# if !@HAVE_RANDOM@ +_GL_FUNCDECL_SYS (random, long, (void)); +# endif +_GL_CXXALIAS_SYS (random, long, (void)); +_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 !@HAVE_RANDOM@ +_GL_FUNCDECL_SYS (srandom, void, (unsigned int seed)); +# endif +_GL_CXXALIAS_SYS (srandom, void, (unsigned int seed)); +_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 !@HAVE_RANDOM@ +_GL_FUNCDECL_SYS (initstate, char *, + (unsigned int seed, char *buf, size_t buf_size) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (initstate, char *, + (unsigned int seed, char *buf, size_t buf_size)); +_GL_CXXALIASWARN (initstate); +#elif defined GNULIB_POSIXCHECK +# undef initstate +# if HAVE_RAW_DECL_INITSTATE_R +_GL_WARN_ON_USE (initstate, "initstate is unportable - " + "use gnulib module random for portability"); +# endif +#endif + +#if @GNULIB_RANDOM@ +# if !@HAVE_RANDOM@ +_GL_FUNCDECL_SYS (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (setstate, char *, (char *arg_state)); +_GL_CXXALIASWARN (setstate); +#elif defined GNULIB_POSIXCHECK +# undef setstate +# if HAVE_RAW_DECL_SETSTATE_R +_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 +_GL_CXXALIAS_SYS (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 +_GL_CXXALIAS_SYS (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 @REPLACE_REALLOC@ +# 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_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size)); +# else +_GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size)); +# endif +_GL_CXXALIASWARN (realloc); +#elif 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 + +#if @GNULIB_REALPATH@ +# if @REPLACE_REALPATH@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define realpath rpl_realpath +# endif +_GL_FUNCDECL_RPL (realpath, char *, (const char *name, char *resolved) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (realpath, char *, (const char *name, char *resolved)); +# else +# if !@HAVE_REALPATH@ +_GL_FUNCDECL_SYS (realpath, char *, (const char *name, char *resolved) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (realpath, char *, (const char *name, char *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_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 +_GL_FUNCDECL_RPL (strtod, double, (const char *str, char **endp) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtod, double, (const char *str, char **endp)); +# else +# if !@HAVE_STRTOD@ +_GL_FUNCDECL_SYS (strtod, double, (const char *str, char **endp) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtod, double, (const char *str, char **endp)); +# endif +_GL_CXXALIASWARN (strtod); +#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_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 !@HAVE_STRTOLL@ +_GL_FUNCDECL_SYS (strtoll, long long, + (const char *string, char **endptr, int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoll, long long, + (const char *string, char **endptr, int base)); +_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_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 !@HAVE_STRTOULL@ +_GL_FUNCDECL_SYS (strtoull, unsigned long long, + (const char *string, char **endptr, int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoull, unsigned long long, + (const char *string, char **endptr, int base)); +_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 +_GL_CXXALIASWARN (wctomb); +#endif + + +#endif /* _@GUARD_PREFIX@_STDLIB_H */ +#endif /* _@GUARD_PREFIX@_STDLIB_H */ +#endif diff --git a/gnu/stpcpy.c b/gnu/stpcpy.c new file mode 100644 index 00000000..1034d06e --- /dev/null +++ b/gnu/stpcpy.c @@ -0,0 +1,51 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* stpcpy.c -- copy a string and return pointer to end of new string + Copyright (C) 1992, 1995, 1997-1998, 2006, 2009-2012 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 program is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or any + later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include <string.h> + +#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/gnu/strcasecmp.c b/gnu/strcasecmp.c new file mode 100644 index 00000000..f8bf22df --- /dev/null +++ b/gnu/strcasecmp.c @@ -0,0 +1,65 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Case-insensitive string comparison function. + Copyright (C) 1998-1999, 2005-2007, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include <string.h> + +#include <ctype.h> +#include <limits.h> + +#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 (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); +} diff --git a/gnu/strchrnul.c b/gnu/strchrnul.c new file mode 100644 index 00000000..b6c1c935 --- /dev/null +++ b/gnu/strchrnul.c @@ -0,0 +1,144 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Searching in a string. + Copyright (C) 2003, 2007-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <string.h> + +/* 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/gnu/strchrnul.valgrind b/gnu/strchrnul.valgrind new file mode 100644 index 00000000..b14fa130 --- /dev/null +++ b/gnu/strchrnul.valgrind @@ -0,0 +1,12 @@ +# Suppress a valgrind message about use of uninitialized memory in strchrnul(). +# 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/gnu/strdup.c b/gnu/strdup.c new file mode 100644 index 00000000..cf8871bb --- /dev/null +++ b/gnu/strdup.c @@ -0,0 +1,57 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1991, 1996-1998, 2002-2004, 2006-2007, 2009-2012 Free Software + Foundation, Inc. + + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _LIBC +# include <config.h> +#endif + +/* Get specification. */ +#include <string.h> + +#include <stdlib.h> + +#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/gnu/streq.h b/gnu/streq.h new file mode 100644 index 00000000..a0c2192b --- /dev/null +++ b/gnu/streq.h @@ -0,0 +1,178 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Optimized string comparison. + Copyright (C) 2001-2002, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>. */ + +#ifndef _GL_STREQ_H +#define _GL_STREQ_H + +#include <string.h> + +/* STREQ allows to optimize string comparison with a small literal string. + STREQ (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 (__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(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(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + (strcmp (s1, s2) == 0) + +#endif + +#endif /* _GL_STREQ_H */ diff --git a/gnu/strerror-override.c b/gnu/strerror-override.c new file mode 100644 index 00000000..014476ba --- /dev/null +++ b/gnu/strerror-override.c @@ -0,0 +1,291 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* strerror-override.c --- POSIX compatible system error routine + + Copyright (C) 2010-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2010. */ + +#include <config.h> + +#include "strerror-override.h" + +#include <errno.h> + +#if GNULIB_defined_EWINSOCK /* native Windows platforms */ +# if HAVE_WINSOCK2_H +# include <winsock2.h> +# endif +#endif + +/* 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 <errno.h> */ + 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"; + 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 ENOTRECOVERABLE: + return "State not recoverable"; + case EOWNERDEAD: + return "Owner died"; + 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 + + default: + return NULL; + } +} diff --git a/gnu/strerror-override.h b/gnu/strerror-override.h new file mode 100644 index 00000000..e764ae72 --- /dev/null +++ b/gnu/strerror-override.h @@ -0,0 +1,54 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* strerror-override.h --- POSIX compatible system error routine + + Copyright (C) 2010-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _GL_STRERROR_OVERRIDE_H +# define _GL_STRERROR_OVERRIDE_H + +# include <errno.h> +# include <stddef.h> + +/* 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_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 +extern const char *strerror_override (int errnum); +# else +# define strerror_override(ignored) NULL +# endif + +#endif /* _GL_STRERROR_OVERRIDE_H */ diff --git a/gnu/strerror.c b/gnu/strerror.c new file mode 100644 index 00000000..4482d19c --- /dev/null +++ b/gnu/strerror.c @@ -0,0 +1,72 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* strerror.c --- POSIX compatible system error routine + + Copyright (C) 2007-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <string.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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 (); + + return memcpy (buf, msg, len + 1); +} diff --git a/gnu/string.in.h b/gnu/string.in.h new file mode 100644 index 00000000..f7fa4a2a --- /dev/null +++ b/gnu/string.in.h @@ -0,0 +1,1013 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A GNU-like <string.h>. + + Copyright (C) 1995-1996, 2001-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _@GUARD_PREFIX@_STRING_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STRING_H@ + +#ifndef _@GUARD_PREFIX@_STRING_H +#define _@GUARD_PREFIX@_STRING_H + +/* NetBSD 5.0 mis-defines NULL. */ +#include <stddef.h> + +/* MirBSD defines mbslen as a macro. */ +#if @GNULIB_MBSLEN@ && defined __MirBSD__ +# include <wchar.h> +#endif + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The attribute __pure__ was added in gcc 2.96. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +#else +# define _GL_ATTRIBUTE_PURE /* empty */ +#endif + +/* NetBSD 5.0 declares strsignal in <unistd.h>, not in <string.h>. */ +/* But in any case avoid namespace pollution on glibc systems. */ +#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \ + && ! defined __GLIBC__ +# include <unistd.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. */ + + +/* 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 !@HAVE_FFSLL@ +_GL_FUNCDECL_SYS (ffsll, int, (long long int i)); +# endif +_GL_CXXALIAS_SYS (ffsll, int, (long long int i)); +_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 + + +/* 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) +# 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 +# if ! @HAVE_MEMCHR@ +_GL_FUNCDECL_SYS (memchr, void *, (void const *__s, int __c, size_t __n) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C" { const void * std::memchr (const void *, int, size_t); } + extern "C++" { void * std::memchr (void *, int, size_t); } */ +_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)); +# else +_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 (strchr, "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_CXXALIAS_RPL (strdup, char *, (char const *__s)); +# else +# if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup + /* strdup exists as a function and as a macro. Get rid of the macro. */ +# undef strdup +# endif +# if !(@HAVE_DECL_STRDUP@ || defined strdup) +_GL_FUNCDECL_SYS (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strdup, char *, (char const *__s)); +# endif +_GL_CXXALIASWARN (strdup); +#elif 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 +#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 *dest, const char *src, size_t n) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (strncat, char *, (char *dest, const char *src, size_t n)); +# else +_GL_CXXALIAS_SYS (strncat, char *, (char *dest, const char *src, size_t n)); +# endif +_GL_CXXALIASWARN (strncat); +#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 *__string, size_t __n) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strndup, char *, (char const *__string, size_t __n)); +# else +# if ! @HAVE_DECL_STRNDUP@ +_GL_FUNCDECL_SYS (strndup, char *, (char const *__string, size_t __n) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strndup, char *, (char const *__string, size_t __n)); +# endif +_GL_CXXALIASWARN (strndup); +#elif 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 + +/* 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 *__string, size_t __maxlen) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strnlen, size_t, (char const *__string, size_t __maxlen)); +# else +# if ! @HAVE_DECL_STRNLEN@ +_GL_FUNCDECL_SYS (strnlen, size_t, (char const *__string, size_t __maxlen) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strnlen, size_t, (char const *__string, 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)); +# else +_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 (strpbrk, "strpbrk cannot work correctly on character strings " + "in multibyte locales - " + "use mbspbrk if you care about internationalization"); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strpbrk +# if HAVE_RAW_DECL_STRPBRK +_GL_WARN_ON_USE (strpbrk, "strpbrk is unportable - " + "use gnulib module strpbrk for portability"); +# 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 (strrchr, "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)); +# else +_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: + http://www.opengroup.org/susv3xsh/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_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mbslen, size_t, (const char *string)); +# else +_GL_FUNCDECL_SYS (mbslen, size_t, (const char *string) _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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 *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 +_GL_CXXALIASWARN (strerror); +#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 + +#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_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 */ diff --git a/gnu/strings.in.h b/gnu/strings.in.h new file mode 100644 index 00000000..cc49efe5 --- /dev/null +++ b/gnu/strings.in.h @@ -0,0 +1,125 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A substitute <strings.h>. + + Copyright (C) 2007-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _@GUARD_PREFIX@_STRINGS_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* Minix 3.1.8 has a bug: <sys/types.h> must be included before <strings.h>. + But avoid namespace pollution on glibc systems. */ +#if defined __minix && !defined __GLIBC__ +# include <sys/types.h> +#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 <stddef.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 + + + /* 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/gnu/stripslash.c b/gnu/stripslash.c new file mode 100644 index 00000000..ad94346e --- /dev/null +++ b/gnu/stripslash.c @@ -0,0 +1,47 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* stripslash.c -- remove redundant trailing slashes from a file name + + Copyright (C) 1990, 2001, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#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/gnu/strncasecmp.c b/gnu/strncasecmp.c new file mode 100644 index 00000000..6dda6142 --- /dev/null +++ b/gnu/strncasecmp.c @@ -0,0 +1,65 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* strncasecmp.c -- case insensitive string comparator + Copyright (C) 1998-1999, 2005-2007, 2009-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include <string.h> + +#include <ctype.h> +#include <limits.h> + +#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 (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); +} diff --git a/gnu/strndup.c b/gnu/strndup.c new file mode 100644 index 00000000..b9e256d0 --- /dev/null +++ b/gnu/strndup.c @@ -0,0 +1,39 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A replacement function, for systems that lack strndup. + + Copyright (C) 1996-1998, 2001-2003, 2005-2007, 2009-2012 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +#include <string.h> + +#include <stdlib.h> + +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/gnu/strnlen.c b/gnu/strnlen.c new file mode 100644 index 00000000..ca24ba66 --- /dev/null +++ b/gnu/strnlen.c @@ -0,0 +1,33 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Find the length of STRING, but scan at most MAXLEN characters. + Copyright (C) 2005-2007, 2009-2012 Free Software Foundation, Inc. + Written by Simon Josefsson. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +#include <string.h> + +/* 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/gnu/strnlen1.c b/gnu/strnlen1.c new file mode 100644 index 00000000..8778c67b --- /dev/null +++ b/gnu/strnlen1.c @@ -0,0 +1,37 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + Copyright (C) 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "strnlen1.h" + +#include <string.h> + +/* 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/gnu/strnlen1.h b/gnu/strnlen1.h new file mode 100644 index 00000000..24bcecb7 --- /dev/null +++ b/gnu/strnlen1.h @@ -0,0 +1,42 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + Copyright (C) 2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _STRNLEN1_H +#define _STRNLEN1_H + +#include <stddef.h> + + +#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/gnu/strtoimax.c b/gnu/strtoimax.c new file mode 100644 index 00000000..683f99e7 --- /dev/null +++ b/gnu/strtoimax.c @@ -0,0 +1,77 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert string representation of a number into an intmax_t value. + + Copyright (C) 1999, 2001-2004, 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +/* Verify interface. */ +#include <inttypes.h> + +#include <stdlib.h> + +#include "verify.h" + +#ifdef UNSIGNED +# ifndef HAVE_DECL_STRTOULL +"this configure-time declaration test was not run" +# endif +# if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG_INT +unsigned long long int strtoull (char const *, char **, int); +# endif + +#else + +# ifndef HAVE_DECL_STRTOLL +"this configure-time declaration test was not run" +# endif +# if !HAVE_DECL_STRTOLL && HAVE_LONG_LONG_INT +long long int strtoll (char const *, char **, int); +# endif +#endif + +#ifdef UNSIGNED +# define Have_long_long HAVE_UNSIGNED_LONG_LONG_INT +# define Int uintmax_t +# define Unsigned unsigned +# define strtoimax strtoumax +# define strtol strtoul +# define strtoll strtoull +#else +# define Have_long_long HAVE_LONG_LONG_INT +# define Int intmax_t +# define Unsigned +#endif + +Int +strtoimax (char const *ptr, char **endptr, int base) +{ +#if Have_long_long + verify (sizeof (Int) == sizeof (Unsigned long int) + || sizeof (Int) == sizeof (Unsigned long long int)); + + if (sizeof (Int) != sizeof (Unsigned long int)) + return strtoll (ptr, endptr, base); +#else + verify (sizeof (Int) == sizeof (Unsigned long int)); +#endif + + return strtol (ptr, endptr, base); +} diff --git a/gnu/strtol.c b/gnu/strtol.c new file mode 100644 index 00000000..72043538 --- /dev/null +++ b/gnu/strtol.c @@ -0,0 +1,435 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert string representation of a number into an integer value. + + Copyright (C) 1991-1992, 1994-1999, 2003, 2005-2007, 2009-2012 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 program is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or any + later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#ifdef _LIBC +# define USE_NUMBER_GROUPING +#else +# include <config.h> +#endif + +#include <ctype.h> +#include <errno.h> +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#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 +# 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 +# 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 +# ifdef QUAD +# define strtol wcstoll +# else +# define strtol wcstol +# endif +# else +# ifdef QUAD +# 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 + +/* The extra casts in the following macros work around compiler bugs, + e.g., in Cray C 5.0.3.0. */ + +/* True if negative values of the signed integer type T use two's + complement, ones' complement, or signed magnitude representation, + respectively. Much GNU code assumes two's complement, but some + people like to be portable to all possible C hosts. */ +# define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) +# define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) +# define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) + +/* True if the arithmetic type T is signed. */ +# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* The maximum and minimum values for the integer type T. These + macros have undefined behavior if T is signed and has padding bits. + If this is a problem for you, please let us know how to fix it for + your host. */ +# define TYPE_MINIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) 0 \ + : TYPE_SIGNED_MAGNITUDE (t) \ + ? ~ (t) 0 \ + : ~ TYPE_MAXIMUM (t))) +# define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) + +# ifndef ULLONG_MAX +# define ULLONG_MAX TYPE_MAXIMUM (unsigned long long) +# endif +# ifndef LLONG_MAX +# define LLONG_MAX TYPE_MAXIMUM (long long int) +# endif +# ifndef LLONG_MIN +# define LLONG_MIN TYPE_MINIMUM (long long int) +# endif + +# 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 + + +/* 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 <wchar.h> +# include <wctype.h> +# 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 ((Ch), loc) +# define ISALPHA(Ch) __isalpha_l ((Ch), loc) +# define TOUPPER(Ch) __toupper_l ((Ch), loc) +# else +# define ISSPACE(Ch) isspace (Ch) +# define ISALPHA(Ch) isalpha (Ch) +# define TOUPPER(Ch) toupper (Ch) +# endif +#endif + +#define INTERNAL(X) INTERNAL1(X) +#define INTERNAL1(X) __##X##_internal +#define WEAKNAME(X) WEAKNAME1(X) + +#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, int group 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 <locale.h>. */ + 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; +} + +/* 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); +} diff --git a/gnu/strtoul.c b/gnu/strtoul.c new file mode 100644 index 00000000..b841deaa --- /dev/null +++ b/gnu/strtoul.c @@ -0,0 +1,21 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1991, 1997, 2009-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#define UNSIGNED 1 + +#include "strtol.c" diff --git a/gnu/strtoull.c b/gnu/strtoull.c new file mode 100644 index 00000000..60e181c3 --- /dev/null +++ b/gnu/strtoull.c @@ -0,0 +1,28 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Function to parse an 'unsigned long long int' from text. + Copyright (C) 1995-1997, 1999, 2009-2012 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 program is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or any + later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#define QUAD 1 + +#include "strtoul.c" + +#ifdef _LIBC +strong_alias (__strtoull_internal, __strtouq_internal) +weak_alias (strtoull, strtouq) +#endif diff --git a/gnu/strtoumax.c b/gnu/strtoumax.c new file mode 100644 index 00000000..44a2f8bb --- /dev/null +++ b/gnu/strtoumax.c @@ -0,0 +1,4 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define UNSIGNED 1 +#include "strtoimax.c" diff --git a/gnu/symlink.c b/gnu/symlink.c new file mode 100644 index 00000000..5e1a58e0 --- /dev/null +++ b/gnu/symlink.c @@ -0,0 +1,59 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Stub for symlink(). + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#include <errno.h> +#include <string.h> +#include <sys/stat.h> + + +#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 = EEXIST; + return -1; + } + return symlink (contents, name); +} + +#else /* !HAVE_SYMLINK */ + +/* The system does not support symlinks. */ +int +symlink (char const *contents _GL_UNUSED, + char const *name _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} + +#endif /* !HAVE_SYMLINK */ diff --git a/gnu/symlinkat.c b/gnu/symlinkat.c new file mode 100644 index 00000000..0211e319 --- /dev/null +++ b/gnu/symlinkat.c @@ -0,0 +1,78 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Create a symlink relative to an open directory. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <unistd.h> + +#if !HAVE_SYMLINK +/* Mingw lacks symlink, and it is more efficient to provide a trivial + wrapper than to go through at-func.c to call rpl_symlink. */ + +# include <errno.h> + +int +symlinkat (char const *path1 _GL_UNUSED, int fd _GL_UNUSED, + char const *path2 _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} + +#else /* HAVE_SYMLINK */ + +/* Our openat helper functions expect the directory parameter first, + not second. These shims make life easier. */ + +/* Like symlink, but with arguments reversed. */ +static int +symlink_reversed (char const *file, char const *contents) +{ + return symlink (contents, file); +} + +/* Like symlinkat, but with arguments reversed. */ + +static int +symlinkat_reversed (int fd, char const *file, char const *contents); + +# define AT_FUNC_NAME symlinkat_reversed +# define AT_FUNC_F1 symlink_reversed +# define AT_FUNC_POST_FILE_PARAM_DECLS , char const *contents +# define AT_FUNC_POST_FILE_ARGS , contents +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS + +/* Create a symlink FILE, in the directory open on descriptor FD, + holding CONTENTS. If possible, do it without changing the + working directory. Otherwise, resort to using save_cwd/fchdir, + then symlink/restore_cwd. If either the save_cwd or the restore_cwd + fails, then give a diagnostic and exit nonzero. */ + +int +symlinkat (char const *contents, int fd, char const *file) +{ + return symlinkat_reversed (fd, file, contents); +} + +#endif /* HAVE_SYMLINK */ diff --git a/gnu/sys_stat.in.h b/gnu/sys_stat.in.h new file mode 100644 index 00000000..937ae859 --- /dev/null +++ b/gnu/sys_stat.in.h @@ -0,0 +1,681 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Provide a more complete sys/stat header file. + Copyright (C) 2005-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Eric Blake, Paul Eggert, and Jim Meyering. */ + +/* This file is supposed to be used on platforms where <sys/stat.h> 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. */ +#include <sys/types.h> + +/* Get struct timespec. */ +#include <time.h> + +/* 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 mkdir rpl_mkdir" below, we need to include all + headers that may declare mkdir(). Native Windows platforms declare mkdir + in <io.h> and/or <direct.h>, not in <unistd.h>. */ +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# include <io.h> /* mingw32, mingw64 */ +# include <direct.h> /* mingw64, MSVC 9 */ +#endif + +/* Native Windows platforms declare umask() in <io.h>. */ +#if 0 && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +# include <io.h> +#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_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 + +/* S_IXUGO is a common extension to POSIX. */ +#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_FCHMODAT@ +# 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)); +_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 +_GL_CXXALIASWARN (fstat); +#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 *name, struct stat *st, int flags) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (fstatat, int, + (int fd, char const *name, struct stat *st, int flags)); +# else +# if !@HAVE_FSTATAT@ +_GL_FUNCDECL_SYS (fstatat, int, + (int fd, char const *name, struct stat *st, int flags) + _GL_ARG_NONNULL ((2, 3))); +# endif +_GL_CXXALIAS_SYS (fstatat, int, + (int fd, char const *name, struct stat *st, int flags)); +# endif +_GL_CXXALIASWARN (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_LCHMOD@ +/* Change the mode of FILENAME to MODE, without dereferencing it if FILENAME + denotes a symbolic link. */ +# if !@HAVE_LCHMOD@ +/* The lchmod replacement follows symbolic links. Callers should take + this into account; lchmod should be applied only to arguments that + are known to not be symbolic links. On hosts that lack lchmod, + this can lead to race conditions between the check and the + invocation of lchmod, but we know of no workarounds that are + reliable in general. You might try requesting support for lchmod + from your operating system supplier. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define lchmod chmod +# endif +/* Need to cast, because on mingw, the second parameter of chmod is + int mode. */ +_GL_CXXALIAS_RPL_CAST_1 (lchmod, chmod, int, + (const char *filename, mode_t mode)); +# else +# if 0 /* assume already declared */ +_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)); +# endif +# if @HAVE_LCHMOD@ +_GL_CXXALIASWARN (lchmod); +# endif +#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 *name, struct stat *buf)); +# elif @REPLACE_LSTAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef lstat +# define lstat rpl_lstat +# endif +_GL_FUNCDECL_RPL (lstat, int, (const char *name, struct stat *buf) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (lstat, int, (const char *name, struct stat *buf)); +# else +_GL_CXXALIAS_SYS (lstat, int, (const char *name, struct stat *buf)); +# endif +# if @HAVE_LSTAT@ +_GL_CXXALIASWARN (lstat); +# endif +#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 @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)); +#else +/* 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 <direct.h> and <io.h>, + which are included above. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# if !GNULIB_defined_rpl_mkdir +static inline 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) +# 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 +#endif +_GL_CXXALIASWARN (mkdir); + + +#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 !@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)); +_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 !@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)); +_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@ +/* 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. */ +# undef stat +# ifdef _LARGE_FILES + /* With _LARGE_FILES defined, AIX (only) defines stat to stat64, + so we have to replace stat64() instead of stat(). */ +# define stat stat64 +# undef stat64 +# define stat64(name, st) rpl_stat (name, st) +# else /* !_LARGE_FILES */ +# define stat(name, st) rpl_stat (name, st) +# endif /* !_LARGE_FILES */ +_GL_EXTERN_C int stat (const char *name, struct stat *buf) + _GL_ARG_NONNULL ((1, 2)); +# endif +#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_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/gnu/sys_time.in.h b/gnu/sys_time.in.h new file mode 100644 index 00000000..e4e30a67 --- /dev/null +++ b/gnu/sys_time.in.h @@ -0,0 +1,202 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Provide a more complete sys/time.h. + + Copyright (C) 2007-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Paul Eggert. */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined _@GUARD_PREFIX@_SYS_TIME_H + +/* Simply delegate to the system's header, without adding anything. */ +# if @HAVE_SYS_TIME_H@ +# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ +# endif + +#else + +# define _@GUARD_PREFIX@_SYS_TIME_H + +# if @HAVE_SYS_TIME_H@ +# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ +# else +# include <time.h> +# endif + +/* On native Windows with MSVC: + Get the 'struct timeval' type. */ +# if defined _MSC_VER && @HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H +# define _GL_INCLUDING_WINSOCK2_H +# include <winsock2.h> +# 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@ + +# 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); +# 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 <winsock2.h>. */ + +# 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 +# else + _GL_WARN_ON_USE (close, + "close() used without including <unistd.h>"); +# 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 <unistd.h>"); +# 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 <sys/socket.h>"); + _GL_WARN_ON_USE (connect, + "connect() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (accept, + "accept() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (bind, + "bind() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (getpeername, + "getpeername() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (getsockname, + "getsockname() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (getsockopt, + "getsockopt() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (listen, + "listen() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (recv, + "recv() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (send, + "send() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (recvfrom, + "recvfrom() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (sendto, + "sendto() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (setsockopt, + "setsockopt() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (shutdown, + "shutdown() used without including <sys/socket.h>"); +# 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 <sys/select.h>"); +# endif +# endif +# endif + +#endif /* _@GUARD_PREFIX@_SYS_TIME_H */ diff --git a/gnu/sys_types.in.h b/gnu/sys_types.in.h new file mode 100644 index 00000000..aeaddc13 --- /dev/null +++ b/gnu/sys_types.in.h @@ -0,0 +1,42 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Provide a more complete sys/types.h. + + Copyright (C) 2011-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#ifndef _@GUARD_PREFIX@_SYS_TYPES_H + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@ + +#ifndef _@GUARD_PREFIX@_SYS_TYPES_H +#define _@GUARD_PREFIX@_SYS_TYPES_H + +/* MSVC 9 defines size_t in <stddef.h>, not in <sys/types.h>. */ +/* But avoid namespace pollution on glibc systems. */ +#if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \ + && ! defined __GLIBC__ +# include <stddef.h> +#endif + +#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ +#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ diff --git a/gnu/sysexits.in.h b/gnu/sysexits.in.h new file mode 100644 index 00000000..0de6f95b --- /dev/null +++ b/gnu/sysexits.in.h @@ -0,0 +1,74 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* exit() exit codes for some BSD system programs. + Copyright (C) 2003, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Simon Josefsson based on sysexits(3) man page */ + +#ifndef _@GUARD_PREFIX@_SYSEXITS_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if @HAVE_SYSEXITS_H@ + +/* IRIX 6.5 has an <unistd.h> that defines a macro EX_OK with a nonzero + value. Override it. See + <http://lists.gnu.org/archive/html/bug-gnulib/2007-03/msg00361.html> */ +# ifdef __sgi +# include <unistd.h> +# undef EX_OK +# endif + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_SYSEXITS_H@ + +/* HP-UX 11 <sysexits.h> ends at EX_NOPERM. */ +# ifndef EX_CONFIG +# define EX_CONFIG 78 +# endif + +#endif + +#ifndef _@GUARD_PREFIX@_SYSEXITS_H +#define _@GUARD_PREFIX@_SYSEXITS_H + +#if !@HAVE_SYSEXITS_H@ + +# define EX_OK 0 /* same value as EXIT_SUCCESS */ + +# define EX_USAGE 64 +# define EX_DATAERR 65 +# define EX_NOINPUT 66 +# define EX_NOUSER 67 +# define EX_NOHOST 68 +# define EX_UNAVAILABLE 69 +# define EX_SOFTWARE 70 +# define EX_OSERR 71 +# define EX_OSFILE 72 +# define EX_CANTCREAT 73 +# define EX_IOERR 74 +# define EX_TEMPFAIL 75 +# define EX_PROTOCOL 76 +# define EX_NOPERM 77 +# define EX_CONFIG 78 + +#endif + +#endif /* _@GUARD_PREFIX@_SYSEXITS_H */ +#endif /* _@GUARD_PREFIX@_SYSEXITS_H */ diff --git a/gnu/tempname.c b/gnu/tempname.c new file mode 100644 index 00000000..5684e743 --- /dev/null +++ b/gnu/tempname.c @@ -0,0 +1,311 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* tempname.c - generate the name of a temporary file. + + Copyright (C) 1991-2003, 2005-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Extracted from glibc sysdeps/posix/tempname.c. See also tmpdir.c. */ + +#if !_LIBC +# include <config.h> +# include "tempname.h" +#endif + +#include <sys/types.h> +#include <assert.h> + +#include <errno.h> +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +#include <stdio.h> +#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 <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include <fcntl.h> +#include <sys/time.h> +#include <stdint.h> +#include <unistd.h> + +#include <sys/stat.h> + +#if _LIBC +# define struct_stat64 struct stat64 +#else +# define struct_stat64 struct stat +# define __gen_tempname gen_tempname +# define __getpid getpid +# define __gettimeofday gettimeofday +# define __mkdir mkdir +# define __open open +# define __lxstat64(version, file, buf) lstat (file, buf) +#endif + +#if ! (HAVE___SECURE_GETENV || _LIBC) +# define __secure_getenv getenv +#endif + +#ifdef _LIBC +# include <hp-timing.h> +# if HP_TIMING_AVAIL +# define RANDOM_BITS(Var) \ + if (__builtin_expect (value == UINT64_C (0), 0)) \ + { \ + /* If this is the first time this function is used initialize \ + the variable we accumulate the value in to some somewhat \ + random value. If we'd not do this programs at startup time \ + might have a reduced set of possible names, at least on slow \ + machines. */ \ + struct timeval tv; \ + __gettimeofday (&tv, NULL); \ + value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \ + } \ + HP_TIMING_NOW (Var) +# endif +#endif + +/* Use the widest available unsigned type if uint64_t is not + available. The algorithm below extracts a number less than 62**6 + (approximately 2**35.725) from uint64_t, so ancient hosts where + uintmax_t is only 32 bits lose about 3.725 bits of randomness, + which is better than not having mkstemp at all. */ +#if !defined UINT64_MAX && !defined uint64_t +# define uint64_t uintmax_t +#endif + +#if _LIBC +/* Return nonzero if DIR is an existent directory. */ +static int +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, + 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 */ + +/* 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 "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 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. */ +int +__gen_tempname (char *tmpl, int suffixlen, int flags, int kind) +{ + int len; + char *XXXXXX; + static uint64_t value; + uint64_t random_time_bits; + unsigned int count; + int fd = -1; + int save_errno = errno; + struct_stat64 st; + + /* 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 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. */ +#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 + + len = strlen (tmpl); + if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) + { + __set_errno (EINVAL); + return -1; + } + + /* This is where the Xs start. */ + XXXXXX = &tmpl[len - 6 - suffixlen]; + + /* Get some more or less random data. */ +#ifdef RANDOM_BITS + RANDOM_BITS (random_time_bits); +#else + { + struct timeval tv; + __gettimeofday (&tv, NULL); + random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; + } +#endif + value += random_time_bits ^ __getpid (); + + for (count = 0; count < attempts; value += 7777, ++count) + { + uint64_t v = value; + + /* Fill in the random bits. */ + XXXXXX[0] = letters[v % 62]; + v /= 62; + XXXXXX[1] = letters[v % 62]; + v /= 62; + XXXXXX[2] = letters[v % 62]; + v /= 62; + XXXXXX[3] = letters[v % 62]; + v /= 62; + XXXXXX[4] = letters[v % 62]; + v /= 62; + XXXXXX[5] = letters[v % 62]; + + switch (kind) + { + case __GT_FILE: + fd = __open (tmpl, + (flags & ~O_ACCMODE) + | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + break; + + case __GT_DIR: + fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); + break; + + case __GT_NOCREATE: + /* This case is backward from the other three. __gen_tempname + succeeds if __xstat fails because the name does not exist. + Note the continue to bypass the common logic at the bottom + of the loop. */ + if (__lxstat64 (_STAT_VER, tmpl, &st) < 0) + { + if (errno == ENOENT) + { + __set_errno (save_errno); + return 0; + } + else + /* Give up now. */ + return -1; + } + continue; + + default: + assert (! "invalid KIND in __gen_tempname"); + abort (); + } + + 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; +} diff --git a/gnu/tempname.h b/gnu/tempname.h new file mode 100644 index 00000000..7996577c --- /dev/null +++ b/gnu/tempname.h @@ -0,0 +1,52 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Create a temporary file or directory. + + Copyright (C) 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* header written by Eric Blake */ + +#ifndef GL_TEMPNAME_H +# define GL_TEMPNAME_H + +# include <stdio.h> + +# 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 + +/* 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); + +#endif /* GL_TEMPNAME_H */ diff --git a/gnu/time.in.h b/gnu/time.in.h new file mode 100644 index 00000000..1391bee6 --- /dev/null +++ b/gnu/time.in.h @@ -0,0 +1,251 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A more-standard <time.h>. + + Copyright (C) 2007-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#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. Also, Solaris 8 <time.h> eventually includes itself + recursively; if that is happening, just include the system <time.h> + without adding our own declarations. */ +#if (defined __need_time_t || defined __need_clock_t \ + || defined __need_timespec \ + || defined _@GUARD_PREFIX@_TIME_H) + +# @INCLUDE_NEXT@ @NEXT_TIME_H@ + +#else + +# define _@GUARD_PREFIX@_TIME_H + +# @INCLUDE_NEXT@ @NEXT_TIME_H@ + +/* NetBSD 5.0 mis-defines NULL. */ +# include <stddef.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. */ + +/* Some systems don't define struct timespec (e.g., AIX 4.1, Ultrix 4.3). + Or they define it with the wrong member names or define it in <sys/time.h> + (e.g., FreeBSD circa 1997). Stock Mingw does not define it, but the + pthreads-win32 library defines it in <pthread.h>. */ +# if ! @TIME_H_DEFINES_STRUCT_TIMESPEC@ +# if @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ +# include <sys/time.h> +# elif @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@ +# include <pthread.h> +/* The pthreads-win32 <pthread.h> also defines a couple of broken macros. */ +# undef asctime_r +# undef ctime_r +# undef gmtime_r +# undef localtime_r +# undef rand_r +# undef strtok_r +# 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 +/* Per http://austingroupbugs.net/view.php?id=327, POSIX 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 + +/* Sleep for at least RQTP seconds unless interrupted, If interrupted, + return -1 and store the remaining time into RMTP. See + <http://www.opengroup.org/susv3xsh/nanosleep.html>. */ +# 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 + +/* 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 +_GL_CXXALIASWARN (mktime); +# endif + +/* Convert TIMER to RESULT, assuming local time and UTC respectively. See + <http://www.opengroup.org/susv3xsh/localtime_r.html> and + <http://www.opengroup.org/susv3xsh/gmtime_r.html>. */ +# 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 + +/* Parse BUF as a time stamp, assuming FORMAT specifies its layout, and store + the resulting broken-down time into TM. See + <http://www.opengroup.org/susv3xsh/strptime.html>. */ +# 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 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, "asctime_r can overrun buffers in some cases - " + "better use strftime (or even sprintf) instead"); +# endif +# if defined GNULIB_POSIXCHECK +# undef ctime +_GL_WARN_ON_USE (asctime, "ctime can overrun buffers in some cases - " + "better use strftime (or even sprintf) instead"); +# endif +# if defined GNULIB_POSIXCHECK +# undef ctime_r +_GL_WARN_ON_USE (asctime, "ctime_r can overrun buffers in some cases - " + "better use strftime (or even sprintf) instead"); +# endif + +#endif diff --git a/gnu/time_r.c b/gnu/time_r.c new file mode 100644 index 00000000..f2d59bcf --- /dev/null +++ b/gnu/time_r.c @@ -0,0 +1,47 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Reentrant time functions like localtime_r. + + Copyright (C) 2003, 2006-2007, 2010-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +#include <time.h> + +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/gnu/timespec.h b/gnu/timespec.h new file mode 100644 index 00000000..de192c61 --- /dev/null +++ b/gnu/timespec.h @@ -0,0 +1,84 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* timespec -- System time interface + + Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#if ! defined TIMESPEC_H +# define TIMESPEC_H + +# include <time.h> + +/* Return negative, zero, positive if A < B, A == B, A > B, respectively. + + For each time stamp T, this code assumes that either: + + * T.tv_nsec is in the range 0..999999999; or + * T.tv_sec corresponds to a valid leap second on a host that supports + leap seconds, and T.tv_nsec is in the range 1000000000..1999999999; or + * T.tv_sec is the minimum time_t value and T.tv_nsec is -1; or + T.tv_sec is the maximum time_t value and T.tv_nsec is 2000000000. + This allows for special struct timespec values that are less or + greater than all possible valid time stamps. + + In all these cases, it is safe to subtract two tv_nsec values and + convert the result to integer without worrying about overflow on + any platform of interest to the GNU project, since all such + platforms have 32-bit int or wider. + + Replacing "(int) (a.tv_nsec - b.tv_nsec)" with something like + "a.tv_nsec < b.tv_nsec ? -1 : a.tv_nsec > b.tv_nsec" would cause + this function to work in some cases where the above assumption is + violated, but not in all cases (e.g., a.tv_sec==1, a.tv_nsec==-2, + b.tv_sec==0, b.tv_nsec==999999999) and is arguably not worth the + extra instructions. Using a subtraction has the advantage of + detecting some invalid cases on platforms that detect integer + overflow. + + The (int) cast avoids a gcc -Wconversion warning. */ + +static inline int +timespec_cmp (struct timespec a, struct timespec b) +{ + return (a.tv_sec < b.tv_sec ? -1 + : a.tv_sec > b.tv_sec ? 1 + : (int) (a.tv_nsec - b.tv_nsec)); +} + +/* Return -1, 0, 1, depending on the sign of A. A.tv_nsec must be + nonnegative. */ +static inline int +timespec_sign (struct timespec a) +{ + return a.tv_sec < 0 ? -1 : a.tv_sec || a.tv_nsec; +} + +struct timespec timespec_add (struct timespec, struct timespec); +struct timespec timespec_sub (struct timespec, struct timespec); +struct timespec dtotimespec (double); + +/* Return an approximation to A, of type 'double'. */ +static inline double +timespectod (struct timespec a) +{ + return a.tv_sec + a.tv_nsec / 1e9; +} + +void gettime (struct timespec *); +int settime (struct timespec const *); + +#endif diff --git a/gnu/uinttostr.c b/gnu/uinttostr.c new file mode 100644 index 00000000..70458ecc --- /dev/null +++ b/gnu/uinttostr.c @@ -0,0 +1,5 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define anytostr uinttostr +#define inttype unsigned int +#include "anytostr.c" diff --git a/gnu/umaxtostr.c b/gnu/umaxtostr.c new file mode 100644 index 00000000..6dad2166 --- /dev/null +++ b/gnu/umaxtostr.c @@ -0,0 +1,5 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define anytostr umaxtostr +#define inttype uintmax_t +#include "anytostr.c" diff --git a/gnu/unistd--.h b/gnu/unistd--.h new file mode 100644 index 00000000..b5a2b0f1 --- /dev/null +++ b/gnu/unistd--.h @@ -0,0 +1,34 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Like unistd.h, but redefine some names to avoid glitches. + + Copyright (C) 2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <unistd.h> +#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/gnu/unistd-safer.h b/gnu/unistd-safer.h new file mode 100644 index 00000000..c96dc730 --- /dev/null +++ b/gnu/unistd-safer.h @@ -0,0 +1,33 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Invoke unistd-like functions, but avoid some glitches. + + Copyright (C) 2001, 2003, 2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* 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/gnu/unistd.in.h b/gnu/unistd.in.h new file mode 100644 index 00000000..1af7b699 --- /dev/null +++ b/gnu/unistd.in.h @@ -0,0 +1,1528 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Substitute for and wrapper around <unistd.h>. + Copyright (C) 2003-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* Special invocation convention: + - On mingw, several headers, including <winsock2.h>, include <unistd.h>, + but we need to ensure that both the system <unistd.h> and <winsock2.h> + are completely included before we replace gethostname. */ +#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \ + && !defined _GL_WINSOCK2_H_WITNESS && defined _WINSOCK2_H +/* <unistd.h> is being indirectly included for the first time from + <winsock2.h>; avoid declaring any overrides. */ +# if @HAVE_UNISTD_H@ +# @INCLUDE_NEXT@ @NEXT_UNISTD_H@ +# else +# error unexpected; report this to bug-gnulib@gnu.org +# endif +# define _GL_WINSOCK2_H_WITNESS + +/* Normal invocation. */ +#elif !defined _@GUARD_PREFIX@_UNISTD_H + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_UNISTD_H@ +# @INCLUDE_NEXT@ @NEXT_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 <winsock2.h> +# 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. */ +#include <stddef.h> + +/* mingw doesn't define the SEEK_* or *_FILENO macros in <unistd.h>. */ +/* Cygwin 1.7.1 declares symlinkat in <stdio.h>, not in <unistd.h>. */ +/* But avoid namespace pollution on glibc systems. */ +#if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \ + || ((@GNULIB_SYMLINKAT@ || defined GNULIB_POSIXCHECK) \ + && defined __CYGWIN__)) \ + && ! defined __GLIBC__ +# include <stdio.h> +#endif + +/* Cygwin 1.7.1 declares unlinkat in <fcntl.h>, not in <unistd.h>. */ +/* But avoid namespace pollution on glibc systems. */ +#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) && defined __CYGWIN__ \ + && ! defined __GLIBC__ +# include <fcntl.h> +#endif + +/* mingw fails to declare _exit in <unistd.h>. */ +/* mingw, MSVC, BeOS, Haiku declare environ in <stdlib.h>, not in + <unistd.h>. */ +/* Solaris declares getcwd not only in <unistd.h> but also in <stdlib.h>. */ +/* But avoid namespace pollution on glibc systems. */ +#ifndef __GLIBC__ +# include <stdlib.h> +#endif + +/* Native Windows platforms declare chdir, getcwd, rmdir in + <io.h> and/or <direct.h>, not in <unistd.h>. + They also declare access(), chmod(), close(), dup(), dup2(), isatty(), + lseek(), read(), unlink(), write() in <io.h>. */ +#if ((@GNULIB_CHDIR@ || @GNULIB_GETCWD@ || @GNULIB_RMDIR@ \ + || defined GNULIB_POSIXCHECK) \ + && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) +# include <io.h> /* mingw32, mingw64 */ +# include <direct.h> /* mingw64, MSVC 9 */ +#elif (@GNULIB_CLOSE@ || @GNULIB_DUP@ || @GNULIB_DUP2@ || @GNULIB_ISATTY@ \ + || @GNULIB_LSEEK@ || @GNULIB_READ@ || @GNULIB_UNLINK@ || @GNULIB_WRITE@ \ + || defined GNULIB_POSIXCHECK) \ + && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +# include <io.h> +#endif + +/* AIX and OSF/1 5.1 declare getdomainname in <netdb.h>, not in <unistd.h>. + NonStop Kernel declares gethostname in <netdb.h>, not in <unistd.h>. */ +/* But avoid namespace pollution on glibc systems. */ +#if ((@GNULIB_GETDOMAINNAME@ && (defined _AIX || defined __osf__)) \ + || (@GNULIB_GETHOSTNAME@ && defined __TANDEM)) \ + && !defined __GLIBC__ +# include <netdb.h> +#endif + +/* MSVC defines off_t in <sys/types.h>. */ +#if !@HAVE_UNISTD_H@ +/* Get off_t. */ +# include <sys/types.h> +#endif + +#if (@GNULIB_READ@ || @GNULIB_WRITE@ \ + || @GNULIB_READLINK@ || @GNULIB_READLINKAT@ \ + || @GNULIB_PREAD@ || @GNULIB_PWRITE@ || defined GNULIB_POSIXCHECK) +/* Get ssize_t. */ +# include <sys/types.h> +#endif + +/* Get getopt(), optarg, optind, opterr, optopt. + But avoid namespace pollution on glibc systems. */ +#if @GNULIB_UNISTD_H_GETOPT@ && !defined __GLIBC__ && !defined _GL_SYSTEM_GETOPT +# include <getopt.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. */ + + +/* Hide some function declarations from <winsock2.h>. */ + +#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 <sys/socket.h>"); + _GL_WARN_ON_USE (connect, + "connect() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (accept, + "accept() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (bind, + "bind() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (getpeername, + "getpeername() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (getsockname, + "getsockname() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (getsockopt, + "getsockopt() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (listen, + "listen() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (recv, + "recv() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (send, + "send() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (recvfrom, + "recvfrom() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (sendto, + "sendto() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (setsockopt, + "setsockopt() used without including <sys/socket.h>"); + _GL_WARN_ON_USE (shutdown, + "shutdown() used without including <sys/socket.h>"); +# 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 <sys/select.h>"); +# 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 defined GNULIB_POSIXCHECK +/* The access() function is a security risk. */ +_GL_WARN_ON_USE (access, "the access function is a security risk - " + "use the gnulib module faccessat instead"); +#endif + + +#if @GNULIB_CHDIR@ +_GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1))); +_GL_CXXALIASWARN (chdir); +#elif defined GNULIB_POSIXCHECK +# undef chdir +# if HAVE_RAW_DECL_CHDIR +_GL_WARN_ON_USE (chown, "chdir is not always in <unistd.h> - " + "use gnulib module chdir for portability"); +# endif +#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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html. */ +# if @REPLACE_CHOWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef chown +# define chown rpl_chown +# endif +_GL_FUNCDECL_RPL (chown, int, (const char *file, uid_t uid, gid_t gid) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (chown, int, (const char *file, uid_t uid, gid_t gid)); +# else +# if !@HAVE_CHOWN@ +_GL_FUNCDECL_SYS (chown, int, (const char *file, uid_t uid, gid_t gid) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (chown, int, (const char *file, uid_t uid, gid_t gid)); +# endif +_GL_CXXALIASWARN (chown); +#elif defined GNULIB_POSIXCHECK +# undef chown +# if HAVE_RAW_DECL_CHOWN +_GL_WARN_ON_USE (chown, "chown fails to follow symlinks on some systems and " + "doesn't treat a uid or gid of -1 on some systems - " + "use gnulib module chown for portability"); +# endif +#endif + + +#if @GNULIB_CLOSE@ +# if @REPLACE_CLOSE@ +/* Automatically included by modules that need a replacement for close. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef close +# define close rpl_close +# endif +_GL_FUNCDECL_RPL (close, int, (int fd)); +_GL_CXXALIAS_RPL (close, int, (int fd)); +# else +_GL_CXXALIAS_SYS (close, int, (int fd)); +# endif +_GL_CXXALIASWARN (close); +#elif @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ +# undef close +# define close close_used_without_requesting_gnulib_module_close +#elif defined GNULIB_POSIXCHECK +# undef close +/* Assume close is always declared. */ +_GL_WARN_ON_USE (close, "close does not portably work on sockets - " + "use gnulib module close for portability"); +#endif + + +#if @GNULIB_DUP@ +# if @REPLACE_DUP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define dup rpl_dup +# endif +_GL_FUNCDECL_RPL (dup, int, (int oldfd)); +_GL_CXXALIAS_RPL (dup, int, (int oldfd)); +# else +_GL_CXXALIAS_SYS (dup, int, (int oldfd)); +# endif +_GL_CXXALIASWARN (dup); +#elif defined GNULIB_POSIXCHECK +# undef dup +# if HAVE_RAW_DECL_DUP +_GL_WARN_ON_USE (dup, "dup is unportable - " + "use gnulib module dup for portability"); +# endif +#endif + + +#if @GNULIB_DUP2@ +/* Copy the file descriptor OLDFD into file descriptor NEWFD. Do nothing if + NEWFD = OLDFD, otherwise close NEWFD first if it is open. + Return newfd if successful, otherwise -1 and errno set. + See the POSIX:2008 specification + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html>. */ +# if @REPLACE_DUP2@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define dup2 rpl_dup2 +# endif +_GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd)); +_GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd)); +# else +# if !@HAVE_DUP2@ +_GL_FUNCDECL_SYS (dup2, int, (int oldfd, int newfd)); +# endif +_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 +#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 <fcntl.h>) + 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 + <http://www.kernel.org/doc/man-pages/online/pages/man2/dup3.2.html>. */ +# 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 !@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 <crt_externs.h> +# 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 +static inline char *** +rpl_environ (void) +{ + return &environ; +} +_GL_WARN_ON_USE (rpl_environ, "environ is unportable - " + "use gnulib module environ for portability"); +# undef environ +# define environ (*rpl_environ ()) +# endif +#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_FACCESSAT@ +# 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)); +_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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html>. */ +# 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 openat 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html>. */ +# 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html>. */ +# 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html>. */ +# if !@HAVE_FTRUNCATE@ +_GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length)); +# endif +_GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length)); +_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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html>. + 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)); +# 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 +#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 !@HAVE_GETDTABLESIZE@ +_GL_FUNCDECL_SYS (getdtablesize, int, (void)); +# endif +_GL_CXXALIAS_SYS (getdtablesize, int, (void)); +_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_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 <http://www.opengroup.org/susv3xsh/getlogin.html>. + + Most programs don't need to use this function, because the information is + available through environment variables: + ${LOGNAME-$USER} on Unix platforms, + $USERNAME on native Windows platforms. + */ +# if !@HAVE_GETLOGIN@ +_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 <http://www.opengroup.org/susv3xsh/getlogin.html>. + + 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 +# 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 <OS.h> +# 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 <sys/param.h> +# 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 +static 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_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 +_GL_FUNCDECL_RPL (isatty, int, (int fd)); +_GL_CXXALIAS_RPL (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 +#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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/lchown.html>. */ +# 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html>. */ +# 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html>. */ +# 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)); +# 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 +#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 <fcntl.h>) + 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 + <http://www.kernel.org/doc/man-pages/online/pages/man2/pipe2.2.html>. */ +# 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html>. */ +# 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html>. */ +# 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html>. */ +# 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)); +# else +/* Need to cast, because on mingw, the third parameter is + unsigned int count + and the return type is 'int'. */ +_GL_CXXALIAS_SYS_CAST (read, ssize_t, (int fd, void *buf, size_t count)); +# 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>. */ +# if @REPLACE_READLINK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define readlink rpl_readlink +# endif +_GL_FUNCDECL_RPL (readlink, ssize_t, + (const char *file, char *buf, size_t bufsize) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (readlink, ssize_t, + (const char *file, char *buf, size_t bufsize)); +# else +# if !@HAVE_READLINK@ +_GL_FUNCDECL_SYS (readlink, ssize_t, + (const char *file, char *buf, size_t bufsize) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (readlink, ssize_t, + (const char *file, char *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 !@HAVE_READLINKAT@ +_GL_FUNCDECL_SYS (readlinkat, ssize_t, + (int fd, char const *file, char *buf, size_t len) + _GL_ARG_NONNULL ((2, 3))); +# endif +_GL_CXXALIAS_SYS (readlinkat, ssize_t, + (int fd, char const *file, char *buf, size_t len)); +_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)); +# 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 +#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, MacOS 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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/sleep.html>. */ +# 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_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 !@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)); +_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_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)); +# 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 +#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 openat 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 + <http://www.opengroup.org/susv3xsh/usleep.html>. */ +# 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 +_GL_CXXALIAS_SYS (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 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html>. */ +# 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)); +# else +/* Need to cast, because on mingw, the third parameter is + unsigned int count + and the return type is 'int'. */ +_GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t count)); +# endif +_GL_CXXALIASWARN (write); +#endif + + +#endif /* _@GUARD_PREFIX@_UNISTD_H */ +#endif /* _@GUARD_PREFIX@_UNISTD_H */ diff --git a/gnu/unitypes.in.h b/gnu/unitypes.in.h new file mode 100644 index 00000000..0f5fa261 --- /dev/null +++ b/gnu/unitypes.in.h @@ -0,0 +1,28 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Elementary types for the GNU UniString library. + Copyright (C) 2002, 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _UNITYPES_H +#define _UNITYPES_H + +/* Get uint8_t, uint16_t, uint32_t. */ +#include <stdint.h> + +/* Type representing a Unicode character. */ +typedef uint32_t ucs4_t; + +#endif /* _UNITYPES_H */ diff --git a/gnu/uniwidth.in.h b/gnu/uniwidth.in.h new file mode 100644 index 00000000..58c93c46 --- /dev/null +++ b/gnu/uniwidth.in.h @@ -0,0 +1,71 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Display width functions. + Copyright (C) 2001-2002, 2005, 2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _UNIWIDTH_H +#define _UNIWIDTH_H + +#include "unitypes.h" + +/* Get size_t. */ +#include <stddef.h> + +/* 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) +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) + __attribute__ ((__pure__)) +#endif + ; + +/* 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); +extern int + u16_width (const uint16_t *s, size_t n, const char *encoding); +extern int + u32_width (const uint32_t *s, size_t n, const char *encoding); + +/* Determine number of column positions required for S. */ +extern int + u8_strwidth (const uint8_t *s, const char *encoding); +extern int + u16_strwidth (const uint16_t *s, const char *encoding); +extern int + u32_strwidth (const uint32_t *s, const char *encoding); + + +#ifdef __cplusplus +} +#endif + +#endif /* _UNIWIDTH_H */ diff --git a/gnu/uniwidth/.gitignore b/gnu/uniwidth/.gitignore new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/gnu/uniwidth/.gitignore diff --git a/gnu/uniwidth/cjk.h b/gnu/uniwidth/cjk.h new file mode 100644 index 00000000..c6e5531d --- /dev/null +++ b/gnu/uniwidth/cjk.h @@ -0,0 +1,39 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Test for CJK encoding. + Copyright (C) 2001-2002, 2005-2007, 2009-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2002. + + 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 <http://www.gnu.org/licenses/>. */ + +#include "streq.h" + +static int +is_cjk_encoding (const char *encoding) +{ + if (0 + /* Legacy Japanese encodings */ + || STREQ (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0) + /* Legacy Chinese encodings */ + || STREQ (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) + || STREQ (encoding, "GBK", 'G', 'B', 'K', 0, 0, 0, 0, 0, 0) + || STREQ (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0) + || STREQ (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0) + /* Legacy Korean encodings */ + || STREQ (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) + || STREQ (encoding, "CP949", 'C', 'P', '9', '4', '9', 0, 0, 0, 0) + || STREQ (encoding, "JOHAB", 'J', 'O', 'H', 'A', 'B', 0, 0, 0, 0)) + return 1; + return 0; +} diff --git a/gnu/uniwidth/width.c b/gnu/uniwidth/width.c new file mode 100644 index 00000000..1b284c6e --- /dev/null +++ b/gnu/uniwidth/width.c @@ -0,0 +1,370 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Determine display width of Unicode character. + Copyright (C) 2001-2002, 2006-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2002. + + 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "uniwidth.h" + +#include "cjk.h" + +/* + * 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" + */ +static const unsigned char nonspacing_table_data[27*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 */ + 0x0f, 0x00, 0xff, 0x07, 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, 0x00, /* 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0880-0x08bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 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, 0x00, /* 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, 0x00, /* 0x0ac0-0x0aff */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, /* 0x0b00-0x0b3f */ + 0x1e, 0x20, 0x40, 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 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, /* 0x0c00-0x0c3f */ + 0xc1, 0x3d, 0x60, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0c40-0x0c7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0c80-0x0cbf */ + 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0cc0-0x0cff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d00-0x0d3f */ + 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0d40-0x0d7f */ + 0x00, 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, 0x1b, /* 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, 0x00, 0x00, 0x00, 0x00, /* 0x1140-0x117f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1180-0x11bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 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, 0x1c, 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, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1800-0x183f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1840-0x187f */ + 0x00, 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, 0x01, 0x00, 0x00, 0x00, 0x00, /* 0x1a00-0x1a3f */ + 0x00, 0x00, 0x40, 0x7f, 0xe5, 0x1f, 0xf8, 0x9f, /* 0x1a40-0x1a7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a80-0x1abf */ + 0x00, 0x00, 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, 0x03, 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, 0x00, 0x00, /* 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, 0x7f, 0x00, 0x00, 0xf0, /* 0x1dc0-0x1dff */ + /* 0x2000-0x21ff */ + 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, /* 0x2000-0x203f */ + 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 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, 0xfc, 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, 0x07, 0x30, /* 0xa640-0xa67f */ + 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, /* 0xa800-0xa83f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa840-0xa87f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa880-0xa8bf */ + 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, /* 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, 0x13, /* 0xa980-0xa9bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa9c0-0xa9ff */ + /* 0xaa00-0xabff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x66, 0x00, /* 0xaa00-0xaa3f */ + 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa40-0xaa7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xc1, /* 0xaa80-0xaabf */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 */ + /* 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, 0x7f, 0x00, 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 */ + /* 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, 0x00, 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 */ + /* 0x11000-0x111ff */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0x11000-0x1103f */ + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11040-0x1107f */ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x26, /* 0x11080-0x110bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110c0-0x110ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11100-0x1113f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11140-0x1117f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11180-0x111bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x111c0-0x111ff */ + /* 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 */ +}; +static const signed char nonspacing_table_ind[240] = { + 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, -1, -1, -1, -1, -1, /* 0xd000-0xdfff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe000-0xefff */ + -1, -1, -1, -1, -1, 20, -1, 21, /* 0xf000-0xffff */ + 22, -1, -1, -1, -1, 23, -1, -1, /* 0x10000-0x10fff */ + 24, -1, -1, -1, -1, -1, -1, -1, /* 0x11000-0x11fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x12000-0x12fff */ + -1, -1, -1, -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, -1, -1, -1, /* 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, -1, -1, /* 0x1b000-0x1bfff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1c000-0x1cfff */ + 25, 26, -1, -1, -1, -1, -1, -1 /* 0x1d000-0x1dfff */ +}; + +/* 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) < 240) + { + 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. + * Generated from "grep '^[^;]\{4,5\};[WF]' EastAsianWidth.txt" + * and "grep '^[^;]\{4,5\};[^WF]' EastAsianWidth.txt" + */ + if (uc >= 0x1100 + && ((uc < 0x1160) /* Hangul Jamo */ + || (uc >= 0x2329 && uc < 0x232b) /* Angle Brackets */ + || (uc >= 0x2e80 && uc < 0xa4d0 /* CJK ... Yi */ + && !(uc == 0x303f) && !(uc >= 0x4dc0 && uc < 0x4e00)) + || (uc >= 0xac00 && uc < 0xd7a4) /* Hangul Syllables */ + || (uc >= 0xf900 && uc < 0xfb00) /* CJK Compatibility Ideographs */ + || (uc >= 0xfe10 && uc < 0xfe20) /* Presentation Forms for Vertical */ + || (uc >= 0xfe30 && uc < 0xfe70) /* CJK Compatibility Forms */ + || (uc >= 0xff00 && uc < 0xff61) /* Fullwidth Forms */ + || (uc >= 0xffe0 && uc < 0xffe7) /* Fullwidth Signs */ + || (uc >= 0x20000 && uc <= 0x2ffff) /* Supplementary Ideographic Plane */ + || (uc >= 0x30000 && uc <= 0x3ffff) /* Tertiary Ideographic Plane */ + ) ) + 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/gnu/unlinkdir.c b/gnu/unlinkdir.c new file mode 100644 index 00000000..06336eba --- /dev/null +++ b/gnu/unlinkdir.c @@ -0,0 +1,56 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* unlinkdir.c - determine whether we can unlink directories + + Copyright (C) 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert, Jim Meyering, and David Bartley. */ + +#include <config.h> + +#include "unlinkdir.h" +#include "priv-set.h" +#include <unistd.h> + +#if ! UNLINK_CANNOT_UNLINK_DIR + +/* Return true if we cannot unlink directories, false if we might be + able to unlink directories. */ + +bool +cannot_unlink_dir (void) +{ + static bool initialized; + static bool cannot; + + if (! initialized) + { +# if defined PRIV_SYS_LINKDIR + /* We might be able to unlink directories if we cannot + determine our privileges, or if we have the + PRIV_SYS_LINKDIR privilege. */ + cannot = (priv_set_ismember (PRIV_SYS_LINKDIR) == 0); +# else + /* In traditional Unix, only root can unlink directories. */ + cannot = (geteuid () != 0); +# endif + initialized = true; + } + + return cannot; +} + +#endif diff --git a/gnu/unlinkdir.h b/gnu/unlinkdir.h new file mode 100644 index 00000000..a1a7275f --- /dev/null +++ b/gnu/unlinkdir.h @@ -0,0 +1,28 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* unlinkdir.h - determine (and maybe change) whether we can unlink directories + + Copyright (C) 2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert and Jim Meyering. */ + +#include <stdbool.h> + +#if UNLINK_CANNOT_UNLINK_DIR +# define cannot_unlink_dir() true +#else +bool cannot_unlink_dir (void); +#endif diff --git a/gnu/unlocked-io.h b/gnu/unlocked-io.h new file mode 100644 index 00000000..771f4b32 --- /dev/null +++ b/gnu/unlocked-io.h @@ -0,0 +1,138 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Prefer faster, non-thread-safe stdio functions if available. + + Copyright (C) 2001-2004, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* 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 <stdio.h> + +# if HAVE_DECL_CLEARERR_UNLOCKED +# undef clearerr +# define clearerr(x) clearerr_unlocked (x) +# else +# define clearerr_unlocked(x) clearerr (x) +# endif + +# if HAVE_DECL_FEOF_UNLOCKED +# undef feof +# define feof(x) feof_unlocked (x) +# else +# define feof_unlocked(x) feof (x) +# endif + +# if HAVE_DECL_FERROR_UNLOCKED +# undef ferror +# define ferror(x) ferror_unlocked (x) +# else +# define ferror_unlocked(x) ferror (x) +# endif + +# if HAVE_DECL_FFLUSH_UNLOCKED +# undef fflush +# define fflush(x) fflush_unlocked (x) +# else +# define fflush_unlocked(x) fflush (x) +# endif + +# if HAVE_DECL_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 +# 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 +# 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 +# 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 +# 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 +# undef getc +# define getc(x) getc_unlocked (x) +# else +# define getc_unlocked(x) getc (x) +# endif + +# if HAVE_DECL_GETCHAR_UNLOCKED +# undef getchar +# define getchar() getchar_unlocked () +# else +# define getchar_unlocked() getchar () +# endif + +# if HAVE_DECL_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 +# 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/gnu/unsetenv.c b/gnu/unsetenv.c new file mode 100644 index 00000000..d27a4d59 --- /dev/null +++ b/gnu/unsetenv.c @@ -0,0 +1,129 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 1992, 1995-2002, 2005-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the name == NULL test below. */ +#define _GL_ARG_NONNULL(params) + +/* Specification. */ +#include <stdlib.h> + +#include <errno.h> +#if !_LIBC +# define __set_errno(ev) ((errno) = (ev)) +#endif + +#include <string.h> +#include <unistd.h> + +#if !_LIBC +# define __environ environ +#endif + +#if _LIBC +/* This lock protects against simultaneous modifications of 'environ'. */ +# include <bits/libc-lock.h> +__libc_lock_define_initialized (static, envlock) +# define LOCK __libc_lock_lock (envlock) +# define UNLOCK __libc_lock_unlock (envlock) +#else +# define LOCK +# define UNLOCK +#endif + +/* In the GNU C library we must keep the namespace clean. */ +#ifdef _LIBC +# define unsetenv __unsetenv +#endif + +#if _LIBC || !HAVE_UNSETENV + +int +unsetenv (const char *name) +{ + size_t len; + char **ep; + + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) + { + __set_errno (EINVAL); + return -1; + } + + len = strlen (name); + + LOCK; + + ep = __environ; + while (*ep != NULL) + if (!strncmp (*ep, name, len) && (*ep)[len] == '=') + { + /* Found it. Remove this pointer by moving later ones back. */ + char **dp = ep; + + do + dp[0] = dp[1]; + while (*dp++); + /* Continue the loop in case NAME appears again. */ + } + else + ++ep; + + UNLOCK; + + return 0; +} + +#ifdef _LIBC +# undef unsetenv +weak_alias (__unsetenv, unsetenv) +#endif + +#else /* HAVE_UNSETENV */ + +# undef unsetenv +# if !HAVE_DECL_UNSETENV +# if VOID_UNSETENV +extern void unsetenv (const char *); +# else +extern int unsetenv (const char *); +# endif +# endif + +/* Call the underlying unsetenv, in case there is hidden bookkeeping + that needs updating beyond just modifying environ. */ +int +rpl_unsetenv (const char *name) +{ + int result = 0; + if (!name || !*name || strchr (name, '=')) + { + errno = EINVAL; + return -1; + } + while (getenv (name)) +# if !VOID_UNSETENV + result = +# endif + unsetenv (name); + return result; +} + +#endif /* HAVE_UNSETENV */ diff --git a/gnu/utimens.c b/gnu/utimens.c new file mode 100644 index 00000000..a8387459 --- /dev/null +++ b/gnu/utimens.c @@ -0,0 +1,535 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Set file access and modification times. + + Copyright (C) 2003-2012 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 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +/* derived from a function in touch.c */ + +#include <config.h> + +#include "utimens.h" + +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <unistd.h> + +#include "stat-time.h" +#include "timespec.h" + +#if HAVE_UTIME_H +# include <utime.h> +#endif + +/* Some systems (even some that do have <utime.h>) don't declare this + structure anywhere. */ +#ifndef HAVE_STRUCT_UTIMBUF +struct utimbuf +{ + long actime; + long modtime; +}; +#endif + +/* Avoid recursion with rpl_futimens or rpl_utimensat. */ +#undef futimens +#undef utimensat + +/* 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; + assert (timespec); + if ((timespec[0].tv_nsec != UTIME_NOW + && timespec[0].tv_nsec != UTIME_OMIT + && (timespec[0].tv_nsec < 0 || 1000000000 <= timespec[0].tv_nsec)) + || (timespec[1].tv_nsec != UTIME_NOW + && timespec[1].tv_nsec != UTIME_OMIT + && (timespec[1].tv_nsec < 0 || 1000000000 <= timespec[1].tv_nsec))) + { + 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, using stat + buffer 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[2]) +{ + 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 time stamps 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 time stamps 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 time stamps + of files in NFS file systems in some cases. We have no + configure-time test for this, but please see + <http://bugs.gentoo.org/show_bug.cgi?id=132673> 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__ + /* 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. FIXME: Simplify this in + 2012, 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 /* __linux__ */ +# if HAVE_UTIMENSAT + if (fd < 0) + { + result = utimensat (AT_FDCWD, file, ts, 0); +# ifdef __linux__ + /* Work around a kernel bug: + http://bugzilla.redhat.com/442352 + http://bugzilla.redhat.com/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 */ + + /* 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; + } + +#if 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 time stamps 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 time stamps 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__ + /* 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. FIXME: Simplify this in 2012, + 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 /* __linux__ */ + result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); +# ifdef __linux__ + /* Work around a kernel bug: + http://bugzilla.redhat.com/442352 + http://bugzilla.redhat.com/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/gnu/utimens.h b/gnu/utimens.h new file mode 100644 index 00000000..7690e74d --- /dev/null +++ b/gnu/utimens.h @@ -0,0 +1,21 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#include <time.h> +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 <fcntl.h> +# include <sys/stat.h> + +int fdutimensat (int fd, int dir, char const *name, struct timespec const [2], + int atflag); + +/* Using this function makes application code slightly more readable. */ +static inline int +lutimensat (int dir, char const *file, struct timespec const times[2]) +{ + return utimensat (dir, file, times, AT_SYMLINK_NOFOLLOW); +} +#endif diff --git a/gnu/utimensat.c b/gnu/utimensat.c new file mode 100644 index 00000000..fcfc015f --- /dev/null +++ b/gnu/utimensat.c @@ -0,0 +1,156 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Set the access and modification time of a file relative to directory fd. + Copyright (C) 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +#include <sys/stat.h> + +#include <errno.h> +#include <fcntl.h> + +#include "stat-time.h" +#include "timespec.h" +#include "utimens.h" + +#if HAVE_UTIMENSAT + +# undef utimensat + +/* If we have a native utimensat, but are compiling this file, then + utimensat was defined to rpl_utimensat by our replacement + sys/stat.h. We assume the native version might fail with ENOSYS, + or succeed without properly affecting ctime (as is the case when + using newer glibc but older Linux kernel). In this scenario, + rpl_utimensat checks whether the native version is usable, and + local_utimensat provides the fallback manipulation. */ + +static int local_utimensat (int, char const *, struct timespec const[2], int); +# define AT_FUNC_NAME local_utimensat + +/* Like utimensat, but work around native bugs. */ + +int +rpl_utimensat (int fd, char const *file, struct timespec const times[2], + int flag) +{ +# ifdef __linux__ + struct timespec ts[2]; +# endif + + /* See comments in utimens.c for details. */ + static int utimensat_works_really; /* 0 = unknown, 1 = yes, -1 = no. */ + if (0 <= utimensat_works_really) + { + int result; +# ifdef __linux__ + struct stat st; + /* As recently as Linux kernel 2.6.32 (Dec 2009), several file + systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, + but work if both times are either explicitly specified or + UTIME_NOW. Work around it with a preparatory [l]stat 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. FIXME: Simplify this in 2012, + when file system bugs are no longer common. */ + if (times && (times[0].tv_nsec == UTIME_OMIT + || times[1].tv_nsec == UTIME_OMIT)) + { + if (fstatat (fd, file, &st, flag)) + return -1; + if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) + return 0; + if (times[0].tv_nsec == UTIME_OMIT) + ts[0] = get_stat_atime (&st); + else + ts[0] = times[0]; + if (times[1].tv_nsec == UTIME_OMIT) + ts[1] = get_stat_mtime (&st); + else + ts[1] = times[1]; + times = ts; + } +# ifdef __hppa__ + /* Linux kernel 2.6.22.19 on hppa does not reject invalid tv_nsec + values. */ + else if (times + && ((times[0].tv_nsec != UTIME_NOW + && (times[0].tv_nsec < 0 + || times[0].tv_nsec >= 1000000000)) + || (times[1].tv_nsec != UTIME_NOW + && (times[1].tv_nsec < 0 + || times[1].tv_nsec >= 1000000000)))) + { + errno = EINVAL; + return -1; + } +# endif +# endif /* __linux__ */ + result = utimensat (fd, file, times, flag); + /* Linux kernel 2.6.25 has a bug where it returns EINVAL for + UTIME_NOW or UTIME_OMIT with non-zero tv_sec, which + local_utimensat works around. Meanwhile, EINVAL for a bad + flag is indeterminate whether the native utimensat works, but + local_utimensat will also reject it. */ + if (result == -1 && errno == EINVAL && (flag & ~AT_SYMLINK_NOFOLLOW)) + return result; + if (result == 0 || (errno != ENOSYS && errno != EINVAL)) + { + utimensat_works_really = 1; + return result; + } + } + /* No point in trying openat/futimens, since on Linux, futimens is + implemented with the same syscall as utimensat. Only avoid the + native utimensat due to an ENOSYS failure; an EINVAL error was + data-dependent, and the next caller may pass valid data. */ + if (0 <= utimensat_works_really && errno == ENOSYS) + utimensat_works_really = -1; + return local_utimensat (fd, file, times, flag); +} + +#else /* !HAVE_UTIMENSAT */ + +# define AT_FUNC_NAME utimensat + +#endif /* !HAVE_UTIMENSAT */ + +/* Set the access and modification time stamps of FILE to be + TIMESPEC[0] and TIMESPEC[1], respectively; relative to directory + FD. If flag is AT_SYMLINK_NOFOLLOW, change the times of a symlink, + or fail with ENOSYS if not possible. If TIMESPEC is null, set the + time stamps to the current time. If possible, do it without + changing the working directory. Otherwise, resort to using + save_cwd/fchdir, then utimens/restore_cwd. If either the save_cwd + or the restore_cwd fails, then give a diagnostic and exit nonzero. + Return 0 on success, -1 (setting errno) on failure. */ + +/* AT_FUNC_NAME is now utimensat or local_utimensat. */ +#define AT_FUNC_F1 lutimens +#define AT_FUNC_F2 utimens +#define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW +#define AT_FUNC_POST_FILE_PARAM_DECLS , struct timespec const ts[2], int flag +#define AT_FUNC_POST_FILE_ARGS , ts +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_F2 +#undef AT_FUNC_USE_F1_COND +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS diff --git a/gnu/vasnprintf.c b/gnu/vasnprintf.c new file mode 100644 index 00000000..362df660 --- /dev/null +++ b/gnu/vasnprintf.c @@ -0,0 +1,5609 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* vsprintf with automatic memory allocation. + Copyright (C) 1999, 2002-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* 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. */ + +/* Tell glibc's <stdio.h> to provide a prototype for snprintf(). + This must come before <config.h> because <config.h> may include + <features.h>, and once <features.h> has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifndef VASNPRINTF +# include <config.h> +#endif +#ifndef IN_LIBINTL +# include <alloca.h> +#endif + +/* Specification. */ +#ifndef VASNPRINTF +# if WIDE_CHAR_VERSION +# include "vasnwprintf.h" +# else +# include "vasnprintf.h" +# endif +#endif + +#include <locale.h> /* localeconv() */ +#include <stdio.h> /* snprintf(), sprintf() */ +#include <stdlib.h> /* abort(), malloc(), realloc(), free() */ +#include <string.h> /* memcpy(), strlen() */ +#include <errno.h> /* errno */ +#include <limits.h> /* CHAR_BIT */ +#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */ +#if HAVE_NL_LANGINFO +# include <langinfo.h> +#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 "verify.h" + +#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL +# include <math.h> +# include "float+.h" +#endif + +#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL +# include <math.h> +# include "isnand-nolibm.h" +#endif + +#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL +# include <math.h> +# include "isnanl-nolibm.h" +# include "fpucw.h" +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL +# include <math.h> +# include "isnand-nolibm.h" +# include "printf-frexp.h" +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL +# include <math.h> +# 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 +# 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 +# define SNPRINTF _snprintf +# 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. */ +#ifdef 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) && !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) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T +# if 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) && 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 (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 MacOS 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, then q:=0 and r:=a. + 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<b[0]<beta} + j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j]. + Normalise [q[m-1],...,q[0]], yields q. + If m>=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<intDsize. + Shift a and b left by s bits, copying them. r:=a. + r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=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<n: trivial case. q=0, r := copy of a. */ + r_ptr = roomptr; + r_len = a_len; + memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t)); + q_ptr = roomptr + a_len; + q_len = 0; + } + else if (b_len == 1) + { + /* n=1: single precision division. + beta^(m-1) <= a < beta^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) + 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, <beta). */ + { + mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */ + ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2]; + mp_twolimb_t c3 = /* b[n-2] * q* */ + (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star; + /* While c2 < c3, increase c2 and decrease c3. + Consider c3-c2. While it is > 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); + char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes)); + 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 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 inline 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 HAVE_LONG_LONG_INT + if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long long) * CHAR_BIT + * 0.30103 /* binary -> decimal */ + ) + + 1; /* turn floor into ceil */ + else +# endif + if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + 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 HAVE_LONG_LONG_INT + if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long long) * CHAR_BIT + * 0.333334 /* binary -> octal */ + ) + + 1; /* turn floor into ceil */ + else +# endif + if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + 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 HAVE_LONG_LONG_INT + if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long long) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else +# endif + if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + 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; + 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; + +#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(needed) \ + 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)) \ + goto out_of_memory; \ + if (result == resultbuf || result == NULL) \ + memory = (DCHAR_T *) malloc (memory_size); \ + else \ + memory = (DCHAR_T *) realloc (result, memory_size); \ + if (memory == NULL) \ + goto out_of_memory; \ + if (result == resultbuf && length > 0) \ + DCHAR_CPY (memory, result, length); \ + result = 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++] = (unsigned char) *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; +#if HAVE_LONG_LONG_INT + case TYPE_COUNT_LONGLONGINT_POINTER: + *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; + break; +#endif + default: + abort (); + } + } +#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; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + 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 (has_width && width > characters + && !(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) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION (xsum (length, converted_len)); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (has_width && width > characters + && (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 (has_width && width > characters + && !(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) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION (xsum (length, converted_len)); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (has_width && width > characters + && (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 (has_width && width > characters + && !(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) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION (xsum (length, converted_len)); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (has_width && width > characters + && (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 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && 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; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + 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 (has_width && width > characters + && !(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 (has_width && width > characters + && (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; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg_end, &state); +# else + count = wctomb (cbuf, *arg_end); +# endif + if (count < 0) + { + /* Cannot convert. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + if (precision < count) + 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; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg_end, &state); +# else + count = wctomb (cbuf, *arg_end); +# endif + 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 (); +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg, &state); +# else + count = wctomb (cbuf, *arg); +# endif + 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) + { + int saved_errno = errno; + free (tmpsrc); + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + free (tmpsrc); +# endif + + if (has_width) + { +# if ENABLE_UNISTDIO + /* Outside POSIX, it's preferrable 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 (has_width && width > w + && !(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 (); +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg, &state); +# else + count = wctomb (cbuf, *arg); +# endif + 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 (); +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg, &state); +# else + count = wctomb (cbuf, *arg); +# endif + 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 (xsum (length, tmpdst_len)); + DCHAR_CPY (result + length, tmpdst, tmpdst_len); + free (tmpdst); + length += tmpdst_len; +# endif + + if (has_width && width > w + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - w; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } +# endif + } +#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; + int has_width; + size_t width; + int has_precision; + size_t precision; + size_t tmp_length; + DCHAR_T tmpbuf[700]; + DCHAR_T *tmp; + DCHAR_T *pad_ptr; + DCHAR_T *p; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + 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; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + 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; + } + } + + /* 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. */ + if (has_width && p - tmp < width) + { + size_t pad = width - (p - tmp); + 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; + } + + { + size_t 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; + int has_width; + size_t width; + int has_precision; + size_t precision; + size_t tmp_length; + DCHAR_T tmpbuf[700]; + DCHAR_T *tmp; + DCHAR_T *pad_ptr; + DCHAR_T *p; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + 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; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + 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; + } + } + + /* 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 count = exponent + 1; + /* Note: count <= precision = ndigits. */ + for (; count > 0; count--) + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + size_t count = -exponent - 1; + *p++ = '0'; + *p++ = decimal_point_char (); + for (; count > 0; count--) + *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 __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 __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 count = exponent + 1; + /* Note: count <= precision = ndigits. */ + for (; count > 0; count--) + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + size_t count = -exponent - 1; + *p++ = '0'; + *p++ = decimal_point_char (); + for (; count > 0; count--) + *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 __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 __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 __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. */ + if (has_width && p - tmp < width) + { + size_t pad = width - (p - tmp); + 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; + } + + { + size_t 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 !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + int has_width; + size_t width; +#endif +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || 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 !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_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; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } +#endif + +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || 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++ = (unsigned char) *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++ = (unsigned char) *mp++; + while (--n > 0); + } + } + } + + switch (type) + { +#if HAVE_LONG_LONG_INT + case TYPE_LONGLONGINT: + case TYPE_ULONGLONGINT: +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + *fbp++ = 'I'; + *fbp++ = '6'; + *fbp++ = '4'; + break; +# else + *fbp++ = 'l'; + /*FALLTHROUGH*/ +# endif +#endif + 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 !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) + fbp[1] = '%'; + fbp[2] = 'n'; + fbp[3] = '\0'; +# else + /* On glibc2 systems from glibc >= 2.3 - probably also older + ones - we know that snprintf's return value conforms to + ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and + gl_SNPRINTF_TRUNCATION_C99 pass. + Therefore we can avoid using %n in this situation. + On glibc2 systems from 2004-10-18 or newer, the use of %n + in format strings in writable memory may crash the program + (if compiled with _FORTIFY_SOURCE=2), so we should avoid it + in this situation. */ + /* 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 + <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and + <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx> + So we should avoid %n in this situation. */ + fbp[1] = '\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; +#if HAVE_LONG_LONG_INT + 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; +#endif + 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 (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 + /* 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. Save and use the errno + that it has set, if any. */ + int saved_errno = errno; + + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = + (saved_errno != 0 + ? saved_errno + : (dp->conversion == 'c' || dp->conversion == 's' + ? EILSEQ + : EINVAL)); + return NULL; + } + +#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) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + ENSURE_ALLOCATION (xsum (length, tmpdst_len)); + 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 = (unsigned char) *--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 preferrable 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/gnu/vasnprintf.h b/gnu/vasnprintf.h new file mode 100644 index 00000000..7cfe451f --- /dev/null +++ b/gnu/vasnprintf.h @@ -0,0 +1,82 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* vsprintf with automatic memory allocation. + Copyright (C) 2002-2004, 2007-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _VASNPRINTF_H +#define _VASNPRINTF_H + +/* Get va_list. */ +#include <stdarg.h> + +/* Get size_t. */ +#include <stddef.h> + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ +#endif + +#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 *resultbuf, size_t *lengthp, const char *format, ...) + _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)); +extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0)); + +#ifdef __cplusplus +} +#endif + +#endif /* _VASNPRINTF_H */ diff --git a/gnu/vasprintf.c b/gnu/vasprintf.c new file mode 100644 index 00000000..b5d11b4d --- /dev/null +++ b/gnu/vasprintf.c @@ -0,0 +1,53 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Formatted output to strings. + Copyright (C) 1999, 2002, 2006-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#ifdef IN_LIBASPRINTF +# include "vasprintf.h" +#else +# include <stdio.h> +#endif + +#include <errno.h> +#include <limits.h> +#include <stdlib.h> + +#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/gnu/verify.h b/gnu/verify.h new file mode 100644 index 00000000..0f361cf8 --- /dev/null +++ b/gnu/verify.h @@ -0,0 +1,243 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Compile-time assert-like macros. + + Copyright (C) 2005-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* 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 works as per C11. + This is supported by GCC 4.6.0 and later, in C mode, and its use + here generates easier-to-read diagnostics when verify (R) fails. + + Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11. + This will likely be supported by future GCC versions, in C++ mode. + + Use this only with GCC. If we were willing to slow 'configure' + down we could also use it with other compilers, but since this + affects only the quality of diagnostics, why bother? */ +# if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus +# define _GL_HAVE__STATIC_ASSERT 1 +# endif +/* The condition (99 < __GNUC__) is temporary, until we know about the + first G++ release that supports static_assert. */ +# if (99 < __GNUC__) && defined __cplusplus +# define _GL_HAVE_STATIC_ASSERT 1 +# 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. + + * 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 <int w> + 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, preferably + with a diagnostic that includes the string-literal DIAGNOSTIC. + + Unfortunately, unlike C11, this implementation must appear as an + ordinary declaration, and cannot appear inside struct { ... }. */ + +# ifdef _GL_HAVE__STATIC_ASSERT +# define _GL_VERIFY _Static_assert +# 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_ASSERT && !defined _Static_assert +# define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) +# endif +# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert +# define static_assert _Static_assert /* C11 requires this #define. */ +# endif +# endif + +/* @assert.h omit start@ */ + +/* Each of these macros verifies that its argument R is nonzero. To + be portable, R should be an integer constant expression. Unlike + assert (R), there is no run-time overhead. + + There are two macros, since no single macro can be used in all + contexts in C. verify_true (R) is for scalar contexts, including + integer constant expression contexts. verify (R) is for declaration + contexts, e.g., the top level. */ + +/* Verify requirement R at compile-time, as an integer constant expression. + Return 1. This is equivalent to verify_expr (R, 1). + + verify_true is obsolescent; please use verify_expr instead. */ + +# define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") + +/* Verify requirement R at compile-time. Return the value of the + expression E. */ + +# 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 ';'. */ + +# define verify(R) _GL_VERIFY (R, "verify (" #R ")") + +/* @assert.h omit end@ */ + +#endif diff --git a/gnu/version-etc-fsf.c b/gnu/version-etc-fsf.c new file mode 100644 index 00000000..60275847 --- /dev/null +++ b/gnu/version-etc-fsf.c @@ -0,0 +1,32 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Variable with FSF copyright information, for version-etc. + Copyright (C) 1999-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#include <config.h> + +/* Specification. */ +#include "version-etc.h" + +/* Default copyright goes to the FSF. */ + +const char version_etc_copyright[] = + /* Do *not* mark this string for translation. %s is a copyright + symbol suitable for this locale, and %d is the copyright + year. */ + "Copyright %s %d Free Software Foundation, Inc."; diff --git a/gnu/version-etc.c b/gnu/version-etc.c new file mode 100644 index 00000000..7213088e --- /dev/null +++ b/gnu/version-etc.c @@ -0,0 +1,260 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Print --version and bug-reporting information in a consistent format. + Copyright (C) 1999-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#include <config.h> + +/* Specification. */ +#include "version-etc.h" + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#include "gettext.h" +#define _(msgid) gettext (msgid) + +/* If you use AM_INIT_AUTOMAKE's no-define option, + PACKAGE is not defined. Use PACKAGE_TARNAME instead. */ +#if ! defined PACKAGE && defined PACKAGE_TARNAME +# define PACKAGE PACKAGE_TARNAME +#endif + +enum { COPYRIGHT_YEAR = 2012 }; + +/* The three functions below display the --version information the + standard way. + + If COMMAND_NAME is NULL, the PACKAGE is assumed to be the name of + the program. The formats are therefore: + + PACKAGE VERSION + + or + + COMMAND_NAME (PACKAGE) VERSION. + + The functions differ in the way they are passed author names. */ + +/* Display the --version information the standard way. + + Author names are given in the array AUTHORS. N_AUTHORS is the + number of elements in the array. */ +void +version_etc_arn (FILE *stream, + const char *command_name, const char *package, + const char *version, + const char * const * authors, size_t n_authors) +{ + if (command_name) + fprintf (stream, "%s (%s) %s\n", command_name, package, version); + else + fprintf (stream, "%s %s\n", package, version); + +#ifdef PACKAGE_PACKAGER +# ifdef PACKAGE_PACKAGER_VERSION + fprintf (stream, _("Packaged by %s (%s)\n"), PACKAGE_PACKAGER, + PACKAGE_PACKAGER_VERSION); +# else + fprintf (stream, _("Packaged by %s\n"), PACKAGE_PACKAGER); +# endif +#endif + + /* TRANSLATORS: Translate "(C)" to the copyright symbol + (C-in-a-circle), if this symbol is available in the user's + locale. Otherwise, do not translate "(C)"; leave it as-is. */ + fprintf (stream, version_etc_copyright, _("(C)"), COPYRIGHT_YEAR); + + fputs (_("\ +\n\ +License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\ +This is free software: you are free to change and redistribute it.\n\ +There is NO WARRANTY, to the extent permitted by law.\n\ +\n\ +"), + stream); + + switch (n_authors) + { + case 0: + /* The caller must provide at least one author name. */ + abort (); + case 1: + /* TRANSLATORS: %s denotes an author name. */ + fprintf (stream, _("Written by %s.\n"), authors[0]); + break; + case 2: + /* TRANSLATORS: Each %s denotes an author name. */ + fprintf (stream, _("Written by %s and %s.\n"), authors[0], authors[1]); + break; + case 3: + /* TRANSLATORS: Each %s denotes an author name. */ + fprintf (stream, _("Written by %s, %s, and %s.\n"), + authors[0], authors[1], authors[2]); + break; + case 4: + /* TRANSLATORS: Each %s denotes an author name. + You can use line breaks, estimating that each author name occupies + ca. 16 screen columns and that a screen line has ca. 80 columns. */ + fprintf (stream, _("Written by %s, %s, %s,\nand %s.\n"), + authors[0], authors[1], authors[2], authors[3]); + break; + case 5: + /* TRANSLATORS: Each %s denotes an author name. + You can use line breaks, estimating that each author name occupies + ca. 16 screen columns and that a screen line has ca. 80 columns. */ + fprintf (stream, _("Written by %s, %s, %s,\n%s, and %s.\n"), + authors[0], authors[1], authors[2], authors[3], authors[4]); + break; + case 6: + /* TRANSLATORS: Each %s denotes an author name. + You can use line breaks, estimating that each author name occupies + ca. 16 screen columns and that a screen line has ca. 80 columns. */ + fprintf (stream, _("Written by %s, %s, %s,\n%s, %s, and %s.\n"), + authors[0], authors[1], authors[2], authors[3], authors[4], + authors[5]); + break; + case 7: + /* TRANSLATORS: Each %s denotes an author name. + You can use line breaks, estimating that each author name occupies + ca. 16 screen columns and that a screen line has ca. 80 columns. */ + fprintf (stream, _("Written by %s, %s, %s,\n%s, %s, %s, and %s.\n"), + authors[0], authors[1], authors[2], authors[3], authors[4], + authors[5], authors[6]); + break; + case 8: + /* TRANSLATORS: Each %s denotes an author name. + You can use line breaks, estimating that each author name occupies + ca. 16 screen columns and that a screen line has ca. 80 columns. */ + fprintf (stream, _("\ +Written by %s, %s, %s,\n%s, %s, %s, %s,\nand %s.\n"), + authors[0], authors[1], authors[2], authors[3], authors[4], + authors[5], authors[6], authors[7]); + break; + case 9: + /* TRANSLATORS: Each %s denotes an author name. + You can use line breaks, estimating that each author name occupies + ca. 16 screen columns and that a screen line has ca. 80 columns. */ + fprintf (stream, _("\ +Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, and %s.\n"), + authors[0], authors[1], authors[2], authors[3], authors[4], + authors[5], authors[6], authors[7], authors[8]); + break; + default: + /* 10 or more authors. Use an abbreviation, since the human reader + will probably not want to read the entire list anyway. */ + /* TRANSLATORS: Each %s denotes an author name. + You can use line breaks, estimating that each author name occupies + ca. 16 screen columns and that a screen line has ca. 80 columns. */ + fprintf (stream, _("\ +Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, %s, and others.\n"), + authors[0], authors[1], authors[2], authors[3], authors[4], + authors[5], authors[6], authors[7], authors[8]); + break; + } +} + +/* Display the --version information the standard way. See the initial + comment to this module, for more information. + + Author names are given in the NULL-terminated array AUTHORS. */ +void +version_etc_ar (FILE *stream, + const char *command_name, const char *package, + const char *version, const char * const * authors) +{ + size_t n_authors; + + for (n_authors = 0; authors[n_authors]; n_authors++) + ; + version_etc_arn (stream, command_name, package, version, authors, n_authors); +} + +/* Display the --version information the standard way. See the initial + comment to this module, for more information. + + Author names are given in the NULL-terminated va_list AUTHORS. */ +void +version_etc_va (FILE *stream, + const char *command_name, const char *package, + const char *version, va_list authors) +{ + size_t n_authors; + const char *authtab[10]; + + for (n_authors = 0; + n_authors < 10 + && (authtab[n_authors] = va_arg (authors, const char *)) != NULL; + n_authors++) + ; + version_etc_arn (stream, command_name, package, version, + authtab, n_authors); +} + + +/* Display the --version information the standard way. + + If COMMAND_NAME is NULL, the PACKAGE is assumed to be the name of + the program. The formats are therefore: + + PACKAGE VERSION + + or + + COMMAND_NAME (PACKAGE) VERSION. + + The authors names are passed as separate arguments, with an additional + NULL argument at the end. */ +void +version_etc (FILE *stream, + const char *command_name, const char *package, + const char *version, /* const char *author1, ...*/ ...) +{ + va_list authors; + + va_start (authors, version); + version_etc_va (stream, command_name, package, version, authors); + va_end (authors); +} + +void +emit_bug_reporting_address (void) +{ + /* TRANSLATORS: The placeholder indicates the bug-reporting address + for this package. Please add _another line_ saying + "Report translation bugs to <...>\n" with the address for translation + bugs (typically your translation team's web or email address). */ + printf (_("\nReport bugs to: %s\n"), PACKAGE_BUGREPORT); +#ifdef PACKAGE_PACKAGER_BUG_REPORTS + printf (_("Report %s bugs to: %s\n"), PACKAGE_PACKAGER, + PACKAGE_PACKAGER_BUG_REPORTS); +#endif +#ifdef PACKAGE_URL + printf (_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL); +#else + printf (_("%s home page: <http://www.gnu.org/software/%s/>\n"), + PACKAGE_NAME, PACKAGE); +#endif + fputs (_("General help using GNU software: <http://www.gnu.org/gethelp/>\n"), + stdout); +} diff --git a/gnu/version-etc.h b/gnu/version-etc.h new file mode 100644 index 00000000..ba63518b --- /dev/null +++ b/gnu/version-etc.h @@ -0,0 +1,80 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Print --version and bug-reporting information in a consistent format. + Copyright (C) 1999, 2003, 2005, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#ifndef VERSION_ETC_H +# define VERSION_ETC_H 1 + +# include <stdarg.h> +# include <stdio.h> + +/* The 'sentinel' attribute was added in gcc 4.0. */ +#ifndef _GL_ATTRIBUTE_SENTINEL +# if 4 <= __GNUC__ +# define _GL_ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__)) +# else +# define _GL_ATTRIBUTE_SENTINEL /* empty */ +# endif +#endif + +extern const char version_etc_copyright[]; + +/* The three functions below display the --version information in the + standard way: command and package names, package version, followed + by a short GPLv3+ notice and a list of up to 10 author names. + + If COMMAND_NAME is NULL, the PACKAGE is asumed to be the name of + the program. The formats are therefore: + + PACKAGE VERSION + + or + + COMMAND_NAME (PACKAGE) VERSION. + + The functions differ in the way they are passed author names: */ + +/* N_AUTHORS names are supplied in array AUTHORS. */ +extern void version_etc_arn (FILE *stream, + const char *command_name, const char *package, + const char *version, + const char * const * authors, size_t n_authors); + +/* Names are passed in the NULL-terminated array AUTHORS. */ +extern void version_etc_ar (FILE *stream, + const char *command_name, const char *package, + const char *version, const char * const * authors); + +/* Names are passed in the NULL-terminated va_list. */ +extern void version_etc_va (FILE *stream, + const char *command_name, const char *package, + const char *version, va_list authors); + +/* Names are passed as separate arguments, with an additional + NULL argument at the end. */ +extern void version_etc (FILE *stream, + const char *command_name, const char *package, + const char *version, + /* const char *author1, ..., NULL */ ...) + _GL_ATTRIBUTE_SENTINEL; + +/* Display the usual "Report bugs to" stanza. */ +extern void emit_bug_reporting_address (void); + +#endif /* VERSION_ETC_H */ diff --git a/gnu/vsnprintf.c b/gnu/vsnprintf.c new file mode 100644 index 00000000..c41c5984 --- /dev/null +++ b/gnu/vsnprintf.c @@ -0,0 +1,73 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Formatted output to strings. + Copyright (C) 2004, 2006-2012 Free Software Foundation, Inc. + Written by Simon Josefsson and Yoann Vandoorselaere <yoann@prelude-ids.org>. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/* Specification. */ +#include <stdio.h> + +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#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/gnu/wchar.in.h b/gnu/wchar.in.h new file mode 100644 index 00000000..f81595f8 --- /dev/null +++ b/gnu/wchar.in.h @@ -0,0 +1,1008 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A substitute for ISO C99 <wchar.h>, for platforms that have issues. + + Copyright (C) 2007-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Eric Blake. */ + +/* + * ISO C 99 <wchar.h> for platforms that have issues. + * <http://www.opengroup.org/susv3xbd/wchar.h.html> + * + * 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 __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H +/* Special invocation convention: + - Inside glibc and uClibc header files. + - On HP-UX 11.00 we have a sequence of nested includes + <wchar.h> -> <stdlib.h> -> <stdint.h>, and the latter includes <wchar.h>, + once indirectly <stdint.h> -> <sys/types.h> -> <inttypes.h> -> <wchar.h> + 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 <wchar.h>. + - On IRIX 6.5, similarly, we have an include <wchar.h> -> <wctype.h>, and + the latter includes <wchar.h>. But here, we have no way to detect whether + <wctype.h> 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 <features.h> /* for __GLIBC__ */ +#endif + +/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before + <wchar.h>. + BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be + included before <wchar.h>. + In some builds of uClibc, <wchar.h> is nonexistent and wchar_t is defined + by <stddef.h>. + But avoid namespace pollution on glibc systems. */ +#if !(defined __GLIBC__ && !defined __UCLIBC__) +# include <stddef.h> +#endif +#ifndef __GLIBC__ +# include <stdio.h> +# include <time.h> +#endif + +/* Include the original <wchar.h> 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 + +/* 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 +/* MSVC defines wint_t as 'unsigned short' in <crtdefs.h>. + This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be + "unchanged by default argument promotions". Override it. */ +# if defined _MSC_VER +# if !GNULIB_defined_wint_t +# include <crtdefs.h> +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. */ +#if !(@HAVE_MBSINIT@ && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@ +# if !GNULIB_defined_mbstate_t +typedef int rpl_mbstate_t; +# undef mbstate_t +# define mbstate_t rpl_mbstate_t +# define GNULIB_defined_mbstate_t 1 +# 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_CXXALIAS_RPL (btowc, wint_t, (int c)); +# else +# if !@HAVE_BTOWC@ +_GL_FUNCDECL_SYS (btowc, wint_t, (int c)); +# endif +_GL_CXXALIAS_SYS (btowc, wint_t, (int c)); +# endif +_GL_CXXALIASWARN (btowc); +#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_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)); +# endif +_GL_CXXALIAS_SYS (wctob, int, (wint_t wc)); +# endif +_GL_CXXALIASWARN (wctob); +#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 +_GL_CXXALIASWARN (mbsinit); +#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 *pwc, const char *s, size_t n, mbstate_t *ps)); +_GL_CXXALIAS_RPL (mbrtowc, size_t, + (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +# else +# if !@HAVE_MBRTOWC@ +_GL_FUNCDECL_SYS (mbrtowc, size_t, + (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +# endif +_GL_CXXALIAS_SYS (mbrtowc, size_t, + (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (mbrtowc); +#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 *s, size_t n, mbstate_t *ps)); +_GL_CXXALIAS_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +# else +# if !@HAVE_MBRLEN@ +_GL_FUNCDECL_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +# endif +_GL_CXXALIAS_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (mbrlen); +#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 *dest, const char **srcp, size_t len, mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (mbsrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t len, + mbstate_t *ps)); +# else +# if !@HAVE_MBSRTOWCS@ +_GL_FUNCDECL_SYS (mbsrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (mbsrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t len, + mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (mbsrtowcs); +#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 *dest, const char **srcp, size_t srclen, size_t len, + mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (mbsnrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t srclen, size_t len, + mbstate_t *ps)); +# else +# if !@HAVE_MBSNRTOWCS@ +_GL_FUNCDECL_SYS (mbsnrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t srclen, size_t len, + mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (mbsnrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t srclen, size_t len, + mbstate_t *ps)); +# 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 *s, wchar_t wc, mbstate_t *ps)); +_GL_CXXALIAS_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +# else +# if !@HAVE_WCRTOMB@ +_GL_FUNCDECL_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +# endif +_GL_CXXALIAS_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (wcrtomb); +#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 *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (wcsrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t len, + mbstate_t *ps)); +# else +# if !@HAVE_WCSRTOMBS@ +_GL_FUNCDECL_SYS (wcsrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (wcsrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t len, + mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (wcsrtombs); +#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 *dest, const wchar_t **srcp, size_t srclen, size_t len, + mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (wcsnrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t srclen, size_t len, + mbstate_t *ps)); +# else +# if !@HAVE_WCSNRTOMBS@ +_GL_FUNCDECL_SYS (wcsnrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t srclen, size_t len, + mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (wcsnrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t srclen, size_t len, + mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (wcsnrtombs); +#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_CXXALIAS_RPL (wcwidth, int, (wchar_t)); +# else +# if !@HAVE_DECL_WCWIDTH@ +/* wcwidth exists but is not declared. */ +_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t)); +# endif +_GL_CXXALIAS_SYS (wcwidth, int, (wchar_t)); +# endif +_GL_CXXALIASWARN (wcwidth); +#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)); +# 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)); +# else +_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)); +# endif +_GL_CXXALIAS_SYS (wmemcmp, int, + (const wchar_t *s1, const wchar_t *s2, size_t n)); +_GL_CXXALIASWARN (wmemcmp); +#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 *dest, const wchar_t *src, size_t n)); +# endif +_GL_CXXALIAS_SYS (wmemcpy, wchar_t *, + (wchar_t *dest, const wchar_t *src, size_t n)); +_GL_CXXALIASWARN (wmemcpy); +#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)); +_GL_CXXALIASWARN (wmemmove); +#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 + + +/* 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)); +_GL_CXXALIASWARN (wmemset); +#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)); +# endif +_GL_CXXALIAS_SYS (wcslen, size_t, (const wchar_t *s)); +_GL_CXXALIASWARN (wcslen); +#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)); +# 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 *dest, const wchar_t *src)); +# endif +_GL_CXXALIAS_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); +_GL_CXXALIASWARN (wcscpy); +#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 *dest, const wchar_t *src)); +# endif +_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *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 *dest, const wchar_t *src, size_t n)); +# endif +_GL_CXXALIAS_SYS (wcsncpy, wchar_t *, + (wchar_t *dest, const wchar_t *src, size_t n)); +_GL_CXXALIASWARN (wcsncpy); +#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 *dest, const wchar_t *src, size_t n)); +# endif +_GL_CXXALIAS_SYS (wcpncpy, wchar_t *, + (wchar_t *dest, const wchar_t *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 *dest, const wchar_t *src)); +# endif +_GL_CXXALIAS_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src)); +_GL_CXXALIASWARN (wcscat); +#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 *dest, const wchar_t *src, size_t n)); +# endif +_GL_CXXALIAS_SYS (wcsncat, wchar_t *, + (wchar_t *dest, const wchar_t *src, size_t n)); +_GL_CXXALIASWARN (wcsncat); +#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)); +# endif +_GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)); +_GL_CXXALIASWARN (wcscmp); +#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)); +# endif +_GL_CXXALIAS_SYS (wcsncmp, int, + (const wchar_t *s1, const wchar_t *s2, size_t n)); +_GL_CXXALIASWARN (wcsncmp); +#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)); +# 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)); +# 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)); +_GL_CXXALIASWARN (wcscoll); +#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 *s1, const wchar_t *s2, size_t n)); +# endif +_GL_CXXALIAS_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n)); +_GL_CXXALIASWARN (wcsxfrm); +#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 !@HAVE_WCSDUP@ +_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s)); +# endif +_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s)); +_GL_CXXALIASWARN (wcsdup); +#elif 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 +#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)); +# 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)); +# else +_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)); +# 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)); +# else +_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)); +# endif +_GL_CXXALIAS_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject)); +_GL_CXXALIASWARN (wcscspn); +#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)); +# endif +_GL_CXXALIAS_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept)); +_GL_CXXALIASWARN (wcsspn); +#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)); +# 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)); +# else +_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 *haystack, const wchar_t *needle)); +# 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 *, 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 (wcsstr, wchar_t *, + (wchar_t *haystack, const wchar_t *needle)); +_GL_CXXALIASWARN1 (wcsstr, const wchar_t *, + (const wchar_t *haystack, const wchar_t *needle)); +# else +_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 !@HAVE_WCSTOK@ +_GL_FUNCDECL_SYS (wcstok, wchar_t *, + (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); +# endif +_GL_CXXALIAS_SYS (wcstok, wchar_t *, + (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); +_GL_CXXALIASWARN (wcstok); +#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_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)); +# endif +_GL_CXXALIAS_SYS (wcswidth, int, (const wchar_t *s, size_t n)); +# endif +_GL_CXXALIASWARN (wcswidth); +#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 + + +#endif /* _@GUARD_PREFIX@_WCHAR_H */ +#endif /* _@GUARD_PREFIX@_WCHAR_H */ +#endif diff --git a/gnu/wcrtomb.c b/gnu/wcrtomb.c new file mode 100644 index 00000000..c563fbed --- /dev/null +++ b/gnu/wcrtomb.c @@ -0,0 +1,55 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Convert wide character to multibyte character. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <wchar.h> + +#include <errno.h> +#include <stdlib.h> + + +size_t +wcrtomb (char *s, wchar_t wc, mbstate_t *ps) +{ + /* This implementation of wcrtomb on top of wctomb() supports only + stateless encodings. ps must be in the initial state. */ + if (ps != NULL && !mbsinit (ps)) + { + errno = EINVAL; + return (size_t)(-1); + } + + if (s == NULL) + /* We know the NUL wide character corresponds to the NUL character. */ + return 1; + else + { + int ret = wctomb (s, wc); + + if (ret >= 0) + return ret; + else + { + errno = EILSEQ; + return (size_t)(-1); + } + } +} diff --git a/gnu/wctype.in.h b/gnu/wctype.in.h new file mode 100644 index 00000000..13865178 --- /dev/null +++ b/gnu/wctype.in.h @@ -0,0 +1,501 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A substitute for ISO C99 <wctype.h>, for platforms that lack it. + + Copyright (C) 2006-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Bruno Haible and Paul Eggert. */ + +/* + * ISO C 99 <wctype.h> for platforms that lack it. + * <http://www.opengroup.org/susv3xbd/wctype.h.html> + * + * iswctype, towctrans, towlower, towupper, wctrans, wctype, + * wctrans_t, and wctype_t are not yet implemented. + */ + +#ifndef _@GUARD_PREFIX@_WCTYPE_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if @HAVE_WINT_T@ +/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. + Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before + <wchar.h>. + BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be + included before <wchar.h>. */ +# include <stddef.h> +# include <stdio.h> +# include <time.h> +# include <wchar.h> +#endif + +/* Include the original <wctype.h> if it exists. + BeOS 5 has the functions but no <wctype.h>. */ +/* 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 + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +/* Solaris 2.6 <wctype.h> includes <widec.h> which includes <euc.h> 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 +/* MSVC defines wint_t as 'unsigned short' in <crtdefs.h>. + This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be + "unchanged by default argument promotions". Override it. */ +# if defined _MSC_VER +# if !GNULIB_defined_wint_t +# include <crtdefs.h> +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 <wctype.h> but lacks the functions. + Linux libc5 has <wctype.h> and the functions but they are broken. + Assume all 11 functions (all isw* except iswblank) are implemented the + same way, or not at all. */ +# if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@ + +/* IRIX 5.3 has macros but no functions, its isw* macros refer to an + undefined variable _ctmp_ and to <ctype.h> 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 <wctype.h> 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 + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswalnum +# else +iswalnum +# endif + (wint_t wc) +{ + return ((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')); +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswalpha +# else +iswalpha +# endif + (wint_t wc) +{ + return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswblank +# else +iswblank +# endif + (wint_t wc) +{ + return wc == ' ' || wc == '\t'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswcntrl +# else +iswcntrl +# endif + (wint_t wc) +{ + return (wc & ~0x1f) == 0 || wc == 0x7f; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswdigit +# else +iswdigit +# endif + (wint_t wc) +{ + return wc >= '0' && wc <= '9'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswgraph +# else +iswgraph +# endif + (wint_t wc) +{ + return wc >= '!' && wc <= '~'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswlower +# else +iswlower +# endif + (wint_t wc) +{ + return wc >= 'a' && wc <= 'z'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswprint +# else +iswprint +# endif + (wint_t wc) +{ + return wc >= ' ' && wc <= '~'; +} + +static 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'))); +} + +static 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'); +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswupper +# else +iswupper +# endif + (wint_t wc) +{ + return wc >= 'A' && wc <= 'Z'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswxdigit +# else +iswxdigit +# endif + (wint_t wc) +{ + return ((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F')); +} + +static inline wint_t +# if @REPLACE_TOWLOWER@ +rpl_towlower +# else +towlower +# endif + (wint_t wc) +{ + return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc); +} + +static inline wint_t +# if @REPLACE_TOWLOWER@ +rpl_towupper +# else +towupper +# endif + (wint_t wc) +{ + return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc); +} + +# elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@) +/* Only the iswblank function is missing. */ + +# 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 defined __MINGW32__ + +/* 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. */ + +static 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 + +static 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__ */ + +# define GNULIB_defined_wctype_functions 1 +#endif + +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); +#else +_GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswlower, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswprint, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswspace, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswupper, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc)); +#endif +_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); + +#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 +_GL_CXXALIASWARN (iswblank); +#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)); +_GL_CXXALIASWARN (wctype); +#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 !@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)); +_GL_CXXALIASWARN (iswctype); +#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 +_GL_CXXALIASWARN (towlower); +_GL_CXXALIASWARN (towupper); + +#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)); +_GL_CXXALIASWARN (wctrans); +#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)); +_GL_CXXALIASWARN (towctrans); +#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 + + +#endif /* _@GUARD_PREFIX@_WCTYPE_H */ +#endif /* _@GUARD_PREFIX@_WCTYPE_H */ diff --git a/gnu/wcwidth.c b/gnu/wcwidth.c new file mode 100644 index 00000000..518cfd71 --- /dev/null +++ b/gnu/wcwidth.c @@ -0,0 +1,52 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Determine the number of screen columns needed for a character. + Copyright (C) 2006-2007, 2010-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <wchar.h> + +/* Get iswprint. */ +#include <wctype.h> + +#include "localcharset.h" +#include "streq.h" +#include "uniwidth.h" + +int +wcwidth (wchar_t wc) +#undef wcwidth +{ + /* In UTF-8 locales, use a Unicode aware width function. */ + const char *encoding = locale_charset (); + if (STREQ (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0 ,0)) + { + /* We assume that in a UTF-8 locale, a wide character is the same as a + Unicode character. */ + return uc_width (wc, encoding); + } + 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/gnu/write.c b/gnu/write.c new file mode 100644 index 00000000..3138588c --- /dev/null +++ b/gnu/write.c @@ -0,0 +1,147 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* POSIX compatible write() function. + Copyright (C) 2008-2012 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +/* 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 __WIN32__) && ! defined __CYGWIN__ + +# include <errno.h> +# include <signal.h> +# include <io.h> + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include <windows.h> + +# include "msvc-inval.h" +# include "msvc-nothrow.h" + +# undef write + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static inline 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/gnu/xalloc-die.c b/gnu/xalloc-die.c new file mode 100644 index 00000000..c992abaa --- /dev/null +++ b/gnu/xalloc-die.c @@ -0,0 +1,43 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Report a memory allocation failure and exit. + + Copyright (C) 1997-2000, 2002-2004, 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "xalloc.h" + +#include <stdlib.h> + +#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/gnu/xalloc-oversized.h b/gnu/xalloc-oversized.h new file mode 100644 index 00000000..730c8a43 --- /dev/null +++ b/gnu/xalloc-oversized.h @@ -0,0 +1,40 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* xalloc-oversized.h -- memory allocation size checking + + Copyright (C) 1990-2000, 2003-2004, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef XALLOC_OVERSIZED_H_ +# define XALLOC_OVERSIZED_H_ + +# include <stddef.h> + +/* Return 1 if an array of N objects, each of size S, cannot exist due + to size arithmetic overflow. S must be positive and N must be + nonnegative. This is a macro, not an inline function, so that it + works correctly even when SIZE_MAX < N. + + By gnulib convention, SIZE_MAX represents overflow in size + calculations, so the conservative dividend to use here is + SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value. + However, malloc (SIZE_MAX) fails on all known hosts where + sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for + exactly-SIZE_MAX allocations on such hosts; this avoids a test and + branch when S is known to be 1. */ +# define xalloc_oversized(n, s) \ + ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) + +#endif /* !XALLOC_OVERSIZED_H_ */ diff --git a/gnu/xalloc.h b/gnu/xalloc.h new file mode 100644 index 00000000..e291506c --- /dev/null +++ b/gnu/xalloc.h @@ -0,0 +1,273 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* xalloc.h -- malloc with out-of-memory checking + + Copyright (C) 1990-2000, 2003-2004, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef XALLOC_H_ +# define XALLOC_H_ + +# include <stddef.h> + +# include "xalloc-oversized.h" + +# ifdef __cplusplus +extern "C" { +# endif + + +# if __GNUC__ >= 3 +# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +# else +# define _GL_ATTRIBUTE_MALLOC +# endif + +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) +# else +# define _GL_ATTRIBUTE_ALLOC_SIZE(args) +# endif + +/* 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); + +void *xmalloc (size_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); +void *xzalloc (size_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); +void *xcalloc (size_t n, size_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); +void *xrealloc (void *p, size_t s) + _GL_ATTRIBUTE_ALLOC_SIZE ((2)); +void *x2realloc (void *p, size_t *pn); +void *xmemdup (void const *p, size_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((2)); +char *xstrdup (char const *str) + _GL_ATTRIBUTE_MALLOC; + +/* 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)))) + + +# if HAVE_INLINE +# define static_inline static inline +# else +void *xnmalloc (size_t n, size_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); +void *xnrealloc (void *p, size_t n, size_t s) + _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); +void *x2nrealloc (void *p, size_t *pn, size_t s); +char *xcharalloc (size_t n) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); +# endif + +# ifdef static_inline + +/* Allocate an array of N objects, each with S bytes of memory, + dynamically, with error checking. S must be nonzero. */ + +static_inline void *xnmalloc (size_t n, size_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); +static_inline void * +xnmalloc (size_t n, size_t s) +{ + if (xalloc_oversized (n, s)) + xalloc_die (); + return xmalloc (n * s); +} + +/* 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. */ + +static_inline void *xnrealloc (void *p, size_t n, size_t s) + _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); +static_inline void * +xnrealloc (void *p, size_t n, size_t s) +{ + if (xalloc_oversized (n, s)) + xalloc_die (); + return xrealloc (p, n * s); +} + +/* If P is null, allocate a block of at least *PN such objects; + otherwise, reallocate P so that it contains more than *PN objects + each of S bytes. *PN must be nonzero unless P is null, and S must + be nonzero. Set *PN to the new number of objects, and return the + pointer to the new block. *PN is never set to zero, and the + returned pointer is never null. + + Repeated reallocations are guaranteed to make progress, either by + allocating an initial block with a nonzero size, or by allocating a + larger block. + + In the following implementation, nonzero sizes are increased by a + factor of approximately 1.5 so that repeated reallocations have + O(N) overall cost rather than O(N**2) cost, but the + specification for this function does not guarantee that rate. + + Here is an example of use: + + int *p = NULL; + size_t used = 0; + size_t allocated = 0; + + void + append_int (int value) + { + if (used == allocated) + p = x2nrealloc (p, &allocated, sizeof *p); + p[used++] = value; + } + + This causes x2nrealloc to allocate a block of some nonzero size the + first time it is called. + + To have finer-grained control over the initial size, set *PN to a + nonzero value before calling this function with P == NULL. For + example: + + int *p = NULL; + size_t used = 0; + size_t allocated = 0; + size_t allocated1 = 1000; + + void + append_int (int value) + { + if (used == allocated) + { + p = x2nrealloc (p, &allocated1, sizeof *p); + allocated = allocated1; + } + p[used++] = value; + } + + */ + +static_inline void * +x2nrealloc (void *p, size_t *pn, size_t s) +{ + size_t n = *pn; + + if (! p) + { + if (! n) + { + /* The approximate size to use for initial small allocation + requests, when the invoking code specifies an old size of + zero. This is the largest "small" request for the GNU C + library malloc. */ + enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; + + n = DEFAULT_MXFAST / s; + n += !n; + } + } + else + { + /* Set N = ceil (1.5 * N) so that progress is made if N == 1. + Check for overflow, so that N * S stays in size_t range. + The check is slightly conservative, but an exact check isn't + worth the trouble. */ + if ((size_t) -1 / 3 * 2 / s <= n) + xalloc_die (); + n += (n + 1) / 2; + } + + *pn = n; + return xrealloc (p, n * s); +} + +/* Return a pointer to a new buffer of N bytes. This is like xmalloc, + except it returns char *. */ + +static_inline char *xcharalloc (size_t n) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); +static_inline char * +xcharalloc (size_t n) +{ + return XNMALLOC (n, char); +} + +# endif + +# ifdef __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 <typename T> inline T * +xrealloc (T *p, size_t s) +{ + return (T *) xrealloc ((void *) p, s); +} + +template <typename T> inline T * +xnrealloc (T *p, size_t n, size_t s) +{ + return (T *) xnrealloc ((void *) p, n, s); +} + +template <typename T> inline T * +x2realloc (T *p, size_t *pn) +{ + return (T *) x2realloc ((void *) p, pn); +} + +template <typename T> inline T * +x2nrealloc (T *p, size_t *pn, size_t s) +{ + return (T *) x2nrealloc ((void *) p, pn, s); +} + +template <typename T> inline T * +xmemdup (T const *p, size_t s) +{ + return (T *) xmemdup ((void const *) p, s); +} + +# endif + + +#endif /* !XALLOC_H_ */ diff --git a/gnu/xasprintf.c b/gnu/xasprintf.c new file mode 100644 index 00000000..4524b254 --- /dev/null +++ b/gnu/xasprintf.c @@ -0,0 +1,36 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* vasprintf and asprintf with out-of-memory checking. + Copyright (C) 1999, 2002-2004, 2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "xvasprintf.h" + +char * +xasprintf (const char *format, ...) +{ + va_list args; + char *result; + + va_start (args, format); + result = xvasprintf (format, args); + va_end (args); + + return result; +} diff --git a/gnu/xgetcwd.c b/gnu/xgetcwd.c new file mode 100644 index 00000000..7ad430da --- /dev/null +++ b/gnu/xgetcwd.c @@ -0,0 +1,43 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* xgetcwd.c -- return current directory with unlimited length + + Copyright (C) 2001, 2003-2004, 2006-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#include <config.h> + +#include "xgetcwd.h" + +#include <errno.h> +#include <unistd.h> + +#include "xalloc.h" + +/* Return the current directory, newly allocated. + Upon an out-of-memory error, call xalloc_die. + Upon any other type of error, return NULL. */ + +char * +xgetcwd (void) +{ + char *cwd = getcwd (NULL, 0); + if (! cwd && errno == ENOMEM) + xalloc_die (); + return cwd; +} diff --git a/gnu/xgetcwd.h b/gnu/xgetcwd.h new file mode 100644 index 00000000..4e74e0a6 --- /dev/null +++ b/gnu/xgetcwd.h @@ -0,0 +1,19 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* prototype for xgetcwd + Copyright (C) 1995, 2001, 2003, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +extern char *xgetcwd (void); diff --git a/gnu/xmalloc.c b/gnu/xmalloc.c new file mode 100644 index 00000000..074f3bfa --- /dev/null +++ b/gnu/xmalloc.c @@ -0,0 +1,126 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* xmalloc.c -- malloc with out of memory checking + + Copyright (C) 1990-2000, 2002-2006, 2008-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#if ! HAVE_INLINE +# define static_inline +#endif +#include "xalloc.h" +#undef static_inline + +#include <stdlib.h> +#include <string.h> + +/* 1 if calloc is known to be compatible with GNU calloc. This + matters if we are not also using the calloc module, which defines + HAVE_CALLOC_GNU and supports the GNU API even on non-GNU platforms. */ +#if defined HAVE_CALLOC_GNU || (defined __GLIBC__ && !defined __UCLIBC__) +enum { HAVE_GNU_CALLOC = 1 }; +#else +enum { HAVE_GNU_CALLOC = 0 }; +#endif + +/* Allocate N bytes of memory dynamically, with error checking. */ + +void * +xmalloc (size_t n) +{ + void *p = malloc (n); + if (!p && n != 0) + xalloc_die (); + return p; +} + +/* Change the size of an allocated block of memory P to N bytes, + with error checking. */ + +void * +xrealloc (void *p, size_t n) +{ + if (!n && p) + { + /* The GNU and C99 realloc behaviors disagree here. Act like + GNU, even if the underlying realloc is C99. */ + free (p); + return NULL; + } + + p = realloc (p, n); + if (!p && n) + xalloc_die (); + return p; +} + +/* If P is null, allocate a block of at least *PN bytes; otherwise, + reallocate P so that it contains more than *PN bytes. *PN must be + nonzero unless P is null. Set *PN to the new block's size, and + return the pointer to the new block. *PN is never set to zero, and + the returned pointer is never null. */ + +void * +x2realloc (void *p, size_t *pn) +{ + return x2nrealloc (p, pn, 1); +} + +/* 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 memset (xmalloc (s), 0, s); +} + +/* Allocate zeroed memory for N elements of S bytes, with error + checking. S must be nonzero. */ + +void * +xcalloc (size_t n, size_t s) +{ + void *p; + /* Test for overflow, since some calloc implementations don't have + proper overflow checks. But omit overflow and size-zero tests if + HAVE_GNU_CALLOC, since GNU calloc catches overflow and never + returns NULL if successful. */ + if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s)) + || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0))) + xalloc_die (); + return p; +} + +/* 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); +} + +/* Clone STRING. */ + +char * +xstrdup (char const *string) +{ + return xmemdup (string, strlen (string) + 1); +} diff --git a/gnu/xsize.h b/gnu/xsize.h new file mode 100644 index 00000000..34b202d6 --- /dev/null +++ b/gnu/xsize.h @@ -0,0 +1,110 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* xsize.h -- Checked size_t computations. + + Copyright (C) 2003, 2008-2012 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _XSIZE_H +#define _XSIZE_H + +/* Get size_t. */ +#include <stddef.h> + +/* Get SIZE_MAX. */ +#include <limits.h> +#if HAVE_STDINT_H +# include <stdint.h> +#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. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +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. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +xsum3 (size_t size1, size_t size2, size_t size3) +{ + return xsum (xsum (size1, size2), size3); +} + +/* Sum of four sizes, with overflow check. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +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. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +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 an inline 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) + +#endif /* _XSIZE_H */ diff --git a/gnu/xstrndup.c b/gnu/xstrndup.c new file mode 100644 index 00000000..6d06eb97 --- /dev/null +++ b/gnu/xstrndup.c @@ -0,0 +1,38 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Duplicate a bounded initial segment of a string, with out-of-memory + checking. + Copyright (C) 2003, 2006-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "xstrndup.h" + +#include <string.h> +#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/gnu/xstrndup.h b/gnu/xstrndup.h new file mode 100644 index 00000000..60905f1a --- /dev/null +++ b/gnu/xstrndup.h @@ -0,0 +1,25 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Duplicate a bounded initial segment of a string, with out-of-memory + checking. + Copyright (C) 2003, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <stddef.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. */ +extern char *xstrndup (const char *string, size_t n); diff --git a/gnu/xstrtol-error.c b/gnu/xstrtol-error.c new file mode 100644 index 00000000..19dada8e --- /dev/null +++ b/gnu/xstrtol-error.c @@ -0,0 +1,100 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A more useful interface to strtol. + + Copyright (C) 1995-1996, 1998-1999, 2001-2004, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> +#include "xstrtol.h" + +#include <stdlib.h> + +#include "error.h" +#include "exitfail.h" +#include "gettext.h" + +#define N_(msgid) msgid + +/* Report an error for an invalid integer in an option argument. + + ERR is the error code returned by one of the xstrto* functions. + + Use OPT_IDX to decide whether to print the short option string "C" + or "-C" or a long option string derived from LONG_OPTION. OPT_IDX + is -2 if the short option "C" was used, without any leading "-"; it + is -1 if the short option "-C" was used; otherwise it is an index + into LONG_OPTIONS, which should have a name preceded by two '-' + characters. + + ARG is the option-argument containing the integer. + + After reporting an error, exit with status EXIT_STATUS if it is + nonzero. */ + +static void +xstrtol_error (enum strtol_error err, + int opt_idx, char c, struct option const *long_options, + char const *arg, + int exit_status) +{ + char const *hyphens = "--"; + char const *msgid; + char const *option; + char option_buffer[2]; + + switch (err) + { + default: + abort (); + + case LONGINT_INVALID: + msgid = N_("invalid %s%s argument '%s'"); + break; + + case LONGINT_INVALID_SUFFIX_CHAR: + case LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW: + msgid = N_("invalid suffix in %s%s argument '%s'"); + break; + + case LONGINT_OVERFLOW: + msgid = N_("%s%s argument '%s' too large"); + break; + } + + if (opt_idx < 0) + { + hyphens -= opt_idx; + option_buffer[0] = c; + option_buffer[1] = '\0'; + option = option_buffer; + } + else + option = long_options[opt_idx].name; + + error (exit_status, 0, gettext (msgid), hyphens, option, arg); +} + +/* Like xstrtol_error, except exit with a failure status. */ + +void +xstrtol_fatal (enum strtol_error err, + int opt_idx, char c, struct option const *long_options, + char const *arg) +{ + xstrtol_error (err, opt_idx, c, long_options, arg, exit_failure); + abort (); +} diff --git a/gnu/xstrtol.c b/gnu/xstrtol.c new file mode 100644 index 00000000..cd3f2098 --- /dev/null +++ b/gnu/xstrtol.c @@ -0,0 +1,243 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A more useful interface to strtol. + + Copyright (C) 1995-1996, 1998-2001, 2003-2007, 2009-2012 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Jim Meyering. */ + +#ifndef __strtol +# define __strtol strtol +# define __strtol_t long int +# define __xstrtol xstrtol +# define STRTOL_T_MINIMUM LONG_MIN +# define STRTOL_T_MAXIMUM LONG_MAX +#endif + +#include <config.h> + +#include "xstrtol.h" + +/* Some pre-ANSI implementations (e.g. SunOS 4) + need stderr defined if assertion checking is enabled. */ +#include <stdio.h> + +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +#include "intprops.h" + +/* xstrtoll.c and xstrtoull.c, which include this file, require that + ULLONG_MAX, LLONG_MAX, LLONG_MIN are defined, but <limits.h> does not + define them on all platforms. */ +#ifndef ULLONG_MAX +# define ULLONG_MAX TYPE_MAXIMUM (unsigned long long) +#endif +#ifndef LLONG_MAX +# define LLONG_MAX TYPE_MAXIMUM (long long int) +#endif +#ifndef LLONG_MIN +# define LLONG_MIN TYPE_MINIMUM (long long int) +#endif + +static strtol_error +bkm_scale (__strtol_t *x, int scale_factor) +{ + if (TYPE_SIGNED (__strtol_t) && *x < STRTOL_T_MINIMUM / scale_factor) + { + *x = STRTOL_T_MINIMUM; + return LONGINT_OVERFLOW; + } + if (STRTOL_T_MAXIMUM / scale_factor < *x) + { + *x = STRTOL_T_MAXIMUM; + return LONGINT_OVERFLOW; + } + *x *= scale_factor; + return LONGINT_OK; +} + +static strtol_error +bkm_scale_by_power (__strtol_t *x, int base, int power) +{ + strtol_error err = LONGINT_OK; + while (power--) + err |= bkm_scale (x, base); + return err; +} + +/* FIXME: comment. */ + +strtol_error +__xstrtol (const char *s, char **ptr, int strtol_base, + __strtol_t *val, const char *valid_suffixes) +{ + char *t_ptr; + char **p; + __strtol_t tmp; + strtol_error err = LONGINT_OK; + + assert (0 <= strtol_base && strtol_base <= 36); + + p = (ptr ? ptr : &t_ptr); + + if (! TYPE_SIGNED (__strtol_t)) + { + const char *q = s; + unsigned char ch = *q; + while (isspace (ch)) + ch = *++q; + if (ch == '-') + return LONGINT_INVALID; + } + + errno = 0; + tmp = __strtol (s, p, strtol_base); + + if (*p == s) + { + /* If there is no number but there is a valid suffix, assume the + number is 1. The string is invalid otherwise. */ + if (valid_suffixes && **p && strchr (valid_suffixes, **p)) + tmp = 1; + else + return LONGINT_INVALID; + } + else if (errno != 0) + { + if (errno != ERANGE) + return LONGINT_INVALID; + err = LONGINT_OVERFLOW; + } + + /* Let valid_suffixes == NULL mean "allow any suffix". */ + /* FIXME: update all callers except the ones that allow suffixes + after the number, changing last parameter NULL to "". */ + if (!valid_suffixes) + { + *val = tmp; + return err; + } + + if (**p != '\0') + { + int base = 1024; + int suffixes = 1; + strtol_error overflow; + + if (!strchr (valid_suffixes, **p)) + { + *val = tmp; + return err | LONGINT_INVALID_SUFFIX_CHAR; + } + + if (strchr (valid_suffixes, '0')) + { + /* The "valid suffix" '0' is a special flag meaning that + an optional second suffix is allowed, which can change + the base. A suffix "B" (e.g. "100MB") stands for a power + of 1000, whereas a suffix "iB" (e.g. "100MiB") stands for + a power of 1024. If no suffix (e.g. "100M"), assume + power-of-1024. */ + + switch (p[0][1]) + { + case 'i': + if (p[0][2] == 'B') + suffixes += 2; + break; + + case 'B': + case 'D': /* 'D' is obsolescent */ + base = 1000; + suffixes++; + break; + } + } + + switch (**p) + { + case 'b': + overflow = bkm_scale (&tmp, 512); + break; + + case 'B': + overflow = bkm_scale (&tmp, 1024); + break; + + case 'c': + overflow = 0; + break; + + case 'E': /* exa or exbi */ + overflow = bkm_scale_by_power (&tmp, base, 6); + break; + + case 'G': /* giga or gibi */ + case 'g': /* 'g' is undocumented; for compatibility only */ + overflow = bkm_scale_by_power (&tmp, base, 3); + break; + + case 'k': /* kilo */ + case 'K': /* kibi */ + overflow = bkm_scale_by_power (&tmp, base, 1); + break; + + case 'M': /* mega or mebi */ + case 'm': /* 'm' is undocumented; for compatibility only */ + overflow = bkm_scale_by_power (&tmp, base, 2); + break; + + case 'P': /* peta or pebi */ + overflow = bkm_scale_by_power (&tmp, base, 5); + break; + + case 'T': /* tera or tebi */ + case 't': /* 't' is undocumented; for compatibility only */ + overflow = bkm_scale_by_power (&tmp, base, 4); + break; + + case 'w': + overflow = bkm_scale (&tmp, 2); + break; + + case 'Y': /* yotta or 2**80 */ + overflow = bkm_scale_by_power (&tmp, base, 8); + break; + + case 'Z': /* zetta or 2**70 */ + overflow = bkm_scale_by_power (&tmp, base, 7); + break; + + default: + *val = tmp; + return err | LONGINT_INVALID_SUFFIX_CHAR; + } + + err |= overflow; + *p += suffixes; + if (**p) + err |= LONGINT_INVALID_SUFFIX_CHAR; + } + + *val = tmp; + return err; +} diff --git a/gnu/xstrtol.h b/gnu/xstrtol.h new file mode 100644 index 00000000..c15b21cf --- /dev/null +++ b/gnu/xstrtol.h @@ -0,0 +1,75 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* A more useful interface to strtol. + + Copyright (C) 1995-1996, 1998-1999, 2001-2004, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef XSTRTOL_H_ +# define XSTRTOL_H_ 1 + +# include <getopt.h> +# include <inttypes.h> + +# ifndef _STRTOL_ERROR +enum strtol_error + { + LONGINT_OK = 0, + + /* These two values can be ORed together, to indicate that both + errors occurred. */ + LONGINT_OVERFLOW = 1, + LONGINT_INVALID_SUFFIX_CHAR = 2, + + LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW = (LONGINT_INVALID_SUFFIX_CHAR + | LONGINT_OVERFLOW), + LONGINT_INVALID = 4 + }; +typedef enum strtol_error strtol_error; +# endif + +# define _DECLARE_XSTRTOL(name, type) \ + strtol_error name (const char *, char **, int, type *, const char *); +_DECLARE_XSTRTOL (xstrtol, long int) +_DECLARE_XSTRTOL (xstrtoul, unsigned long int) +_DECLARE_XSTRTOL (xstrtoimax, intmax_t) +_DECLARE_XSTRTOL (xstrtoumax, uintmax_t) + +#if HAVE_LONG_LONG_INT +_DECLARE_XSTRTOL (xstrtoll, long long int) +_DECLARE_XSTRTOL (xstrtoull, unsigned long long int) +#endif + +/* Report an error for an invalid integer in an option argument. + + ERR is the error code returned by one of the xstrto* functions. + + Use OPT_IDX to decide whether to print the short option string "C" + or "-C" or a long option string derived from LONG_OPTION. OPT_IDX + is -2 if the short option "C" was used, without any leading "-"; it + is -1 if the short option "-C" was used; otherwise it is an index + into LONG_OPTIONS, which should have a name preceded by two '-' + characters. + + ARG is the option-argument containing the integer. + + After reporting an error, exit with a failure status. */ + +void _Noreturn xstrtol_fatal (enum strtol_error, + int, char, struct option const *, + char const *); + +#endif /* not XSTRTOL_H_ */ diff --git a/gnu/xstrtoul.c b/gnu/xstrtoul.c new file mode 100644 index 00000000..63968db7 --- /dev/null +++ b/gnu/xstrtoul.c @@ -0,0 +1,8 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define __strtol strtoul +#define __strtol_t unsigned long int +#define __xstrtol xstrtoul +#define STRTOL_T_MINIMUM 0 +#define STRTOL_T_MAXIMUM ULONG_MAX +#include "xstrtol.c" diff --git a/gnu/xstrtoumax.c b/gnu/xstrtoumax.c new file mode 100644 index 00000000..fce8d5fd --- /dev/null +++ b/gnu/xstrtoumax.c @@ -0,0 +1,8 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define __strtol strtoumax +#define __strtol_t uintmax_t +#define __xstrtol xstrtoumax +#define STRTOL_T_MINIMUM 0 +#define STRTOL_T_MAXIMUM UINTMAX_MAX +#include "xstrtol.c" diff --git a/gnu/xvasprintf.c b/gnu/xvasprintf.c new file mode 100644 index 00000000..27c9b413 --- /dev/null +++ b/gnu/xvasprintf.c @@ -0,0 +1,112 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* vasprintf and asprintf with out-of-memory checking. + Copyright (C) 1999, 2002-2004, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "xvasprintf.h" + +#include <errno.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> + +#include "xalloc.h" + +/* Checked size_t computations. */ +#include "xsize.h" + +static inline char * +xstrcat (size_t argcount, va_list args) +{ + char *result; + va_list ap; + size_t totalsize; + size_t i; + char *p; + + /* Determine the total size. */ + totalsize = 0; + va_copy (ap, args); + for (i = argcount; i > 0; i--) + { + const char *next = va_arg (ap, const char *); + totalsize = xsum (totalsize, strlen (next)); + } + va_end (ap); + + /* Test for overflow in the summing pass above or in (totalsize + 1) below. + Also, don't return a string longer than INT_MAX, for consistency with + vasprintf(). */ + if (totalsize == SIZE_MAX || totalsize > INT_MAX) + { + errno = EOVERFLOW; + return NULL; + } + + /* Allocate and fill the result string. */ + result = XNMALLOC (totalsize + 1, char); + p = result; + for (i = argcount; i > 0; i--) + { + const char *next = va_arg (args, const char *); + size_t len = strlen (next); + memcpy (p, next, len); + p += len; + } + *p = '\0'; + + return result; +} + +char * +xvasprintf (const char *format, va_list args) +{ + char *result; + + /* Recognize the special case format = "%s...%s". It is a frequently used + idiom for string concatenation and needs to be fast. We don't want to + have a separate function xstrcat() for this purpose. */ + { + size_t argcount = 0; + const char *f; + + for (f = format;;) + { + if (*f == '\0') + /* Recognized the special case of string concatenation. */ + return xstrcat (argcount, args); + if (*f != '%') + break; + f++; + if (*f != 's') + break; + f++; + argcount++; + } + } + + if (vasprintf (&result, format, args) < 0) + { + if (errno == ENOMEM) + xalloc_die (); + return NULL; + } + + return result; +} diff --git a/gnu/xvasprintf.h b/gnu/xvasprintf.h new file mode 100644 index 00000000..436b60e3 --- /dev/null +++ b/gnu/xvasprintf.h @@ -0,0 +1,57 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* vasprintf and asprintf with out-of-memory checking. + Copyright (C) 2002-2004, 2006-2012 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _XVASPRINTF_H +#define _XVASPRINTF_H + +/* Get va_list. */ +#include <stdarg.h> + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Write formatted output to a string dynamically allocated with malloc(), + and return it. Upon [ENOMEM] memory allocation error, call xalloc_die. + On some other error + - [EOVERFLOW] resulting string length is > INT_MAX, + - [EINVAL] invalid format string, + - [EILSEQ] error during conversion between wide and multibyte characters, + return NULL. */ +extern char *xasprintf (const char *format, ...) + _GL_ATTRIBUTE_FORMAT ((__printf__, 1, 2)); +extern char *xvasprintf (const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT ((__printf__, 1, 0)); + +#ifdef __cplusplus +} +#endif + +#endif /* _XVASPRINTF_H */ |