aboutsummaryrefslogtreecommitdiffstats
path: root/grub-core/gnulib
diff options
context:
space:
mode:
authorJames <james.mckenzie@citrix.com>2012-11-16 10:41:01 +0000
committerJames <james.mckenzie@citrix.com>2012-11-16 10:41:01 +0000
commit041d1ea37802bf7178a31a53f96c26efa6b8fb7b (patch)
treec193e84ad1237f25a79d0f6a267722e44c73f56a /grub-core/gnulib
downloadgrub-1.99-041d1ea37802bf7178a31a53f96c26efa6b8fb7b.tar.gz
grub-1.99-041d1ea37802bf7178a31a53f96c26efa6b8fb7b.tar.bz2
grub-1.99-041d1ea37802bf7178a31a53f96c26efa6b8fb7b.zip
fish
Diffstat (limited to 'grub-core/gnulib')
-rw-r--r--grub-core/gnulib/Makefile.am1359
-rw-r--r--grub-core/gnulib/Makefile.in2107
-rw-r--r--grub-core/gnulib/alloca.c489
-rw-r--r--grub-core/gnulib/alloca.in.h56
-rw-r--r--grub-core/gnulib/argp-ba.c34
-rw-r--r--grub-core/gnulib/argp-eexst.c30
-rw-r--r--grub-core/gnulib/argp-fmtstream.c435
-rw-r--r--grub-core/gnulib/argp-fmtstream.h354
-rw-r--r--grub-core/gnulib/argp-fs-xinl.c42
-rw-r--r--grub-core/gnulib/argp-help.c1951
-rw-r--r--grub-core/gnulib/argp-namefrob.h157
-rw-r--r--grub-core/gnulib/argp-parse.c952
-rw-r--r--grub-core/gnulib/argp-pin.c27
-rw-r--r--grub-core/gnulib/argp-pv.c34
-rw-r--r--grub-core/gnulib/argp-pvh.c31
-rw-r--r--grub-core/gnulib/argp-xinl.c42
-rw-r--r--grub-core/gnulib/argp.h645
-rw-r--r--grub-core/gnulib/asnprintf.c35
-rw-r--r--grub-core/gnulib/basename-lgpl.c75
-rw-r--r--grub-core/gnulib/btowc.c39
-rw-r--r--grub-core/gnulib/config.charset683
-rw-r--r--grub-core/gnulib/dirname-lgpl.c86
-rw-r--r--grub-core/gnulib/dirname.h74
-rw-r--r--grub-core/gnulib/errno.in.h160
-rw-r--r--grub-core/gnulib/error.c394
-rw-r--r--grub-core/gnulib/error.h65
-rw-r--r--grub-core/gnulib/float+.h148
-rw-r--r--grub-core/gnulib/float.in.h62
-rw-r--r--grub-core/gnulib/fnmatch.c354
-rw-r--r--grub-core/gnulib/fnmatch.in.h68
-rw-r--r--grub-core/gnulib/fnmatch_loop.c1215
-rw-r--r--grub-core/gnulib/getdelim.c137
-rw-r--r--grub-core/gnulib/getline.c29
-rw-r--r--grub-core/gnulib/getopt.c1192
-rw-r--r--grub-core/gnulib/getopt.in.h249
-rw-r--r--grub-core/gnulib/getopt1.c170
-rw-r--r--grub-core/gnulib/getopt_int.h135
-rw-r--r--grub-core/gnulib/gettext.h280
-rw-r--r--grub-core/gnulib/intprops.h83
-rw-r--r--grub-core/gnulib/langinfo.in.h173
-rw-r--r--grub-core/gnulib/localcharset.c548
-rw-r--r--grub-core/gnulib/localcharset.h41
-rw-r--r--grub-core/gnulib/malloc.c60
-rw-r--r--grub-core/gnulib/mbrtowc.c386
-rw-r--r--grub-core/gnulib/mbsinit.c47
-rw-r--r--grub-core/gnulib/mbsrtowcs-state.c37
-rw-r--r--grub-core/gnulib/mbsrtowcs.c136
-rw-r--r--grub-core/gnulib/memchr.c172
-rw-r--r--grub-core/gnulib/memchr.valgrind14
-rw-r--r--grub-core/gnulib/mempcpy.c29
-rw-r--r--grub-core/gnulib/nl_langinfo.c270
-rw-r--r--grub-core/gnulib/printf-args.c188
-rw-r--r--grub-core/gnulib/printf-args.h155
-rw-r--r--grub-core/gnulib/printf-parse.c627
-rw-r--r--grub-core/gnulib/printf-parse.h180
-rw-r--r--grub-core/gnulib/progname.c92
-rw-r--r--grub-core/gnulib/progname.h62
-rw-r--r--grub-core/gnulib/rawmemchr.c136
-rw-r--r--grub-core/gnulib/rawmemchr.valgrind12
-rw-r--r--grub-core/gnulib/realloc.c91
-rw-r--r--grub-core/gnulib/ref-add.sin30
-rw-r--r--grub-core/gnulib/ref-del.sin25
-rw-r--r--grub-core/gnulib/regcomp.c3877
-rw-r--r--grub-core/gnulib/regex.c72
-rw-r--r--grub-core/gnulib/regex.h676
-rw-r--r--grub-core/gnulib/regex_internal.c1742
-rw-r--r--grub-core/gnulib/regex_internal.h873
-rw-r--r--grub-core/gnulib/regexec.c4416
-rw-r--r--grub-core/gnulib/size_max.h31
-rw-r--r--grub-core/gnulib/sleep.c75
-rw-r--r--grub-core/gnulib/stdbool.in.h122
-rw-r--r--grub-core/gnulib/stddef.in.h86
-rw-r--r--grub-core/gnulib/stdint.in.h568
-rw-r--r--grub-core/gnulib/stdio-write.c148
-rw-r--r--grub-core/gnulib/stdio.in.h1071
-rw-r--r--grub-core/gnulib/stdlib.in.h715
-rw-r--r--grub-core/gnulib/strcasecmp.c63
-rw-r--r--grub-core/gnulib/strchrnul.c142
-rw-r--r--grub-core/gnulib/strchrnul.valgrind12
-rw-r--r--grub-core/gnulib/streq.h176
-rw-r--r--grub-core/gnulib/strerror.c350
-rw-r--r--grub-core/gnulib/string.in.h945
-rw-r--r--grub-core/gnulib/strings.in.h93
-rw-r--r--grub-core/gnulib/stripslash.c45
-rw-r--r--grub-core/gnulib/strncasecmp.c63
-rw-r--r--grub-core/gnulib/strndup.c37
-rw-r--r--grub-core/gnulib/strnlen.c31
-rw-r--r--grub-core/gnulib/strnlen1.c35
-rw-r--r--grub-core/gnulib/strnlen1.h39
-rw-r--r--grub-core/gnulib/sys_wait.in.h106
-rw-r--r--grub-core/gnulib/sysexits.in.h71
-rw-r--r--grub-core/gnulib/unistd.in.h1326
-rw-r--r--grub-core/gnulib/vasnprintf.c5567
-rw-r--r--grub-core/gnulib/vasnprintf.h80
-rw-r--r--grub-core/gnulib/verify.h163
-rw-r--r--grub-core/gnulib/vsnprintf.c71
-rw-r--r--grub-core/gnulib/wchar.in.h428
-rw-r--r--grub-core/gnulib/wcrtomb.c53
-rw-r--r--grub-core/gnulib/wctype.in.h392
-rw-r--r--grub-core/gnulib/xsize.h108
100 files changed, 42857 insertions, 0 deletions
diff --git a/grub-core/gnulib/Makefile.am b/grub-core/gnulib/Makefile.am
new file mode 100644
index 0000000..fb1525f
--- /dev/null
+++ b/grub-core/gnulib/Makefile.am
@@ -0,0 +1,1359 @@
+## DO NOT EDIT! GENERATED AUTOMATICALLY!
+## Process this file with automake to produce Makefile.in.
+# Copyright (C) 2002-2010 Free Software Foundation, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License. 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=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex
+
+AUTOMAKE_OPTIONS = 1.5 gnits
+
+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
+
+
+EXTRA_DIST += alloca.c
+
+EXTRA_libgnu_a_SOURCES += alloca.c
+
+libgnu_a_LIBADD += @ALLOCA@
+libgnu_a_DEPENDENCIES += @ALLOCA@
+## 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.
+alloca.h: alloca.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ cat $(srcdir)/alloca.in.h; \
+ } > $@-t && \
+ mv -f $@-t $@
+MOSTLYCLEANFILES += alloca.h alloca.h-t
+
+EXTRA_DIST += alloca.in.h
+
+## end gnulib module alloca-opt
+
+## begin gnulib module 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/arg-nonnull.h, except that it has the copyright header cut off.
+arg-nonnull.h: $(top_srcdir)/build-aux/arg-nonnull.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/GL_ARG_NONNULL/,$$p' \
+ < $(top_srcdir)/build-aux/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/arg-nonnull.h
+
+## end gnulib module arg-nonnull
+
+## 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 btowc
+
+
+EXTRA_DIST += btowc.c
+
+EXTRA_libgnu_a_SOURCES += btowc.c
+
+## end gnulib module btowc
+
+## begin gnulib module 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/c++defs.h, except that it has the copyright header cut off.
+c++defs.h: $(top_srcdir)/build-aux/c++defs.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/_GL_CXXDEFS/,$$p' \
+ < $(top_srcdir)/build-aux/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/c++defs.h
+
+## end gnulib module c++defs
+
+## begin gnulib module configmake
+
+# Retrieve values of the variables through 'configure' followed by
+# 'make', not directly through 'configure', so that a user who
+# sets some of these variables consistently on the 'make' command
+# line gets correct results.
+#
+# One advantage of this approach, compared to the classical
+# approach of adding -DLIBDIR=\"$(libdir)\" etc. to AM_CPPFLAGS,
+# is that it protects against the use of undefined variables.
+# If, say, $(libdir) is not set in the Makefile, LIBDIR is not
+# defined by this module, and code using LIBDIR gives a
+# compilation error.
+#
+# Another advantage is that 'make' output is shorter.
+#
+# Listed in the same order as the GNU makefile conventions.
+# 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 && \
+ if test -f $@ && cmp $@-t $@ > /dev/null; then \
+ rm -f $@-t; \
+ else \
+ rm -f $@; mv $@-t $@; \
+ fi
+
+BUILT_SOURCES += configmake.h
+CLEANFILES += configmake.h configmake.h-t
+
+## end gnulib module configmake
+
+## begin gnulib module dirname-lgpl
+
+
+EXTRA_DIST += basename-lgpl.c dirname-lgpl.c dirname.h stripslash.c
+
+EXTRA_libgnu_a_SOURCES += basename-lgpl.c dirname-lgpl.c stripslash.c
+
+## end gnulib module dirname-lgpl
+
+## 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.
+errno.h: errno.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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 $@
+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 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.
+float.h: float.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \
+ < $(srcdir)/float.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += float.h float.h-t
+
+EXTRA_DIST += float.in.h
+
+## 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.
+fnmatch.h: fnmatch.in.h $(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 $@
+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 getdelim
+
+
+EXTRA_DIST += getdelim.c
+
+EXTRA_libgnu_a_SOURCES += getdelim.c
+
+## end gnulib module getdelim
+
+## 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 $(ARG_NONNULL_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''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 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 havelib
+
+
+EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath
+
+## end gnulib module havelib
+
+## begin gnulib module intprops
+
+
+EXTRA_DIST += intprops.h
+
+## end gnulib module intprops
+
+## 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 $(CXXDEFS_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''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 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 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 mbrtowc
+
+
+EXTRA_DIST += mbrtowc.c
+
+EXTRA_libgnu_a_SOURCES += mbrtowc.c
+
+## end gnulib module mbrtowc
+
+## 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-state.c mbsrtowcs.c
+
+EXTRA_libgnu_a_SOURCES += mbsrtowcs-state.c mbsrtowcs.c
+
+## end gnulib module mbsrtowcs
+
+## 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 nl_langinfo
+
+
+EXTRA_DIST += nl_langinfo.c
+
+EXTRA_libgnu_a_SOURCES += nl_langinfo.c
+
+## end gnulib module nl_langinfo
+
+## begin gnulib module progname
+
+libgnu_a_SOURCES += progname.h progname.c
+
+## end gnulib module progname
+
+## begin gnulib module rawmemchr
+
+
+EXTRA_DIST += rawmemchr.c rawmemchr.valgrind
+
+EXTRA_libgnu_a_SOURCES += rawmemchr.c
+
+## end gnulib module rawmemchr
+
+## 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 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 stdbool
+
+BUILT_SOURCES += $(STDBOOL_H)
+
+# We need the following in order to create <stdbool.h> when the system
+# doesn't have one that works.
+stdbool.h: stdbool.in.h
+ $(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 $@
+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.
+stddef.h: stddef.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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 $@
+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.
+stdint.h: stdint.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''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_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 $@
+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 $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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_FFLUSH''@|$(GNULIB_FFLUSH)|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_FREOPEN''@|$(GNULIB_FREOPEN)|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_GETDELIM''@|$(GNULIB_GETDELIM)|g' \
+ -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \
+ -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \
+ -e 's|@''GNULIB_OBSTACK_PRINTF_POSIX''@|$(GNULIB_OBSTACK_PRINTF_POSIX)|g' \
+ -e 's|@''GNULIB_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_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \
+ -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|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_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_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_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_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_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-write.c stdio.in.h
+
+EXTRA_libgnu_a_SOURCES += stdio-write.c
+
+## 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 $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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_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_PTSNAME''@|$(GNULIB_PTSNAME)|g' \
+ -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|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_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \
+ -e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \
+ -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_PTSNAME''@|$(HAVE_PTSNAME)|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_SETENV''@|$(HAVE_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_UNSETENV''@|$(HAVE_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_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+ -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|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 '/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)/stdlib.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += stdlib.h stdlib.h-t
+
+EXTRA_DIST += stdlib.in.h
+
+## end gnulib module stdlib
+
+## 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 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 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 $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|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_STRSIGNAL''@|$(GNULIB_STRSIGNAL)|g' \
+ -e 's|@''GNULIB_STRVERSCMP''@|$(GNULIB_STRVERSCMP)|g' \
+ < $(srcdir)/string.in.h | \
+ sed -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_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_STRDUP''@|$(REPLACE_STRDUP)|g' \
+ -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \
+ -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|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 $(WARN_ON_USE_H) $(ARG_NONNULL_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \
+ -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \
+ -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \
+ -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 sys_wait
+
+BUILT_SOURCES += sys/wait.h
+
+# We need the following in order to create <sys/wait.h> when the system
+# has one that is incomplete.
+sys/wait.h: sys_wait.in.h
+ $(AM_V_at)$(MKDIR_P) sys
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''NEXT_SYS_WAIT_H''@|$(NEXT_SYS_WAIT_H)|g' \
+ < $(srcdir)/sys_wait.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += sys/wait.h sys/wait.h-t
+MOSTLYCLEANDIRS += sys
+
+EXTRA_DIST += sys_wait.in.h
+
+## end gnulib module sys_wait
+
+## begin gnulib module 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.
+sysexits.h: sysexits.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''NEXT_SYSEXITS_H''@|$(NEXT_SYSEXITS_H)|g' \
+ < $(srcdir)/sysexits.in.h; \
+ } > $@-t && \
+ mv -f $@-t $@
+MOSTLYCLEANFILES += sysexits.h sysexits.h-t
+
+EXTRA_DIST += sysexits.in.h
+
+## end gnulib module sysexits
+
+## 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 $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \
+ -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \
+ -e 's|@''GNULIB_CLOSE''@|$(GNULIB_CLOSE)|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_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_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_PIPE2''@|$(GNULIB_PIPE2)|g' \
+ -e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \
+ -e 's|@''GNULIB_PWRITE''@|$(GNULIB_PWRITE)|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_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''@|$(GNULIB_UNISTD_H_GETOPT)|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_FSYNC''@|$(HAVE_FSYNC)|g' \
+ -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \
+ -e 's|@''HAVE_GETDOMAINNAME''@|$(HAVE_GETDOMAINNAME)|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_LCHOWN''@|$(HAVE_LCHOWN)|g' \
+ -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \
+ -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|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_SLEEP''@|$(HAVE_SLEEP)|g' \
+ -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \
+ -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \
+ -e 's|@''HAVE_TTYNAME_R''@|$(HAVE_TTYNAME_R)|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_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_OS_H''@|$(HAVE_OS_H)|g' \
+ -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \
+ -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_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \
+ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|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_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 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 verify
+
+libgnu_a_SOURCES += verify.h
+
+## end gnulib module verify
+
+## begin gnulib module vsnprintf
+
+
+EXTRA_DIST += vsnprintf.c
+
+EXTRA_libgnu_a_SOURCES += vsnprintf.c
+
+## end gnulib module vsnprintf
+
+## begin gnulib module 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/warn-on-use.h, except that it has the copyright header cut off.
+warn-on-use.h: $(top_srcdir)/build-aux/warn-on-use.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/^.ifndef/,$$p' \
+ < $(top_srcdir)/build-aux/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/warn-on-use.h
+
+## end gnulib module warn-on-use
+
+## 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 $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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|@''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_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \
+ -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \
+ -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 '/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)/wchar.in.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
+
+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 $(CXXDEFS_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \
+ -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \
+ -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/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 '/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
+
+## begin gnulib module xsize
+
+libgnu_a_SOURCES += xsize.h
+
+## end gnulib module xsize
+
+
+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/grub-core/gnulib/Makefile.in b/grub-core/gnulib/Makefile.in
new file mode 100644
index 0000000..0533f9d
--- /dev/null
+++ b/grub-core/gnulib/Makefile.in
@@ -0,0 +1,2107 @@
+# 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@
+
+# Copyright (C) 2002-2010 Free Software Foundation, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License. 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=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = grub-core/gnulib
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in alloca.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/asm-underscore.m4 $(top_srcdir)/m4/btowc.m4 \
+ $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/dirname.m4 \
+ $(top_srcdir)/m4/dos.m4 $(top_srcdir)/m4/double-slash-root.m4 \
+ $(top_srcdir)/m4/errno_h.m4 $(top_srcdir)/m4/error.m4 \
+ $(top_srcdir)/m4/extensions.m4 $(top_srcdir)/m4/fcntl-o.m4 \
+ $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/fnmatch.m4 \
+ $(top_srcdir)/m4/getdelim.m4 $(top_srcdir)/m4/getline.m4 \
+ $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/gnulib-common.m4 \
+ $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/include_next.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax_t.m4 \
+ $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/langinfo_h.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.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/malloc.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/memchr.m4 $(top_srcdir)/m4/mempcpy.m4 \
+ $(top_srcdir)/m4/mmap-anon.m4 $(top_srcdir)/m4/multiarch.m4 \
+ $(top_srcdir)/m4/nl_langinfo.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/printf.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/rawmemchr.m4 \
+ $(top_srcdir)/m4/realloc.m4 $(top_srcdir)/m4/regex.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/sleep.m4 \
+ $(top_srcdir)/m4/ssize_t.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/strcase.m4 \
+ $(top_srcdir)/m4/strchrnul.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/sys_wait_h.m4 $(top_srcdir)/m4/sysexits.m4 \
+ $(top_srcdir)/m4/unistd_h.m4 $(top_srcdir)/m4/vasnprintf.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/wint_t.m4 $(top_srcdir)/m4/xsize.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-util.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libgnu_a_AR = $(AR) $(ARFLAGS)
+am__DEPENDENCIES_1 =
+am_libgnu_a_OBJECTS = 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) \
+ localcharset.$(OBJEXT) progname.$(OBJEXT) strnlen1.$(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)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libgnu_a_SOURCES) $(EXTRA_libgnu_a_SOURCES)
+DIST_SOURCES = $(libgnu_a_SOURCES) $(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"
+ACLOCAL = @ACLOCAL@
+ADDR32 = @ADDR32@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+ASM_SYMBOL_PREFIX = @ASM_SYMBOL_PREFIX@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+BSS_START_SYMBOL = @BSS_START_SYMBOL@
+BUILD_CC = @BUILD_CC@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMP = @CMP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA32 = @DATA32@
+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@
+END_SYMBOL = @END_SYMBOL@
+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@
+FONT_SOURCE = @FONT_SOURCE@
+FREETYPE = @FREETYPE@
+GETOPT_H = @GETOPT_H@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_DPRINTF = @GNULIB_DPRINTF@
+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_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FCLOSE = @GNULIB_FCLOSE@
+GNULIB_FFLUSH = @GNULIB_FFLUSH@
+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_FREOPEN = @GNULIB_FREOPEN@
+GNULIB_FSEEK = @GNULIB_FSEEK@
+GNULIB_FSEEKO = @GNULIB_FSEEKO@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTELL = @GNULIB_FTELL@
+GNULIB_FTELLO = @GNULIB_FTELLO@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_FWRITE = @GNULIB_FWRITE@
+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_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+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_MEMCHR = @GNULIB_MEMCHR@
+GNULIB_MEMMEM = @GNULIB_MEMMEM@
+GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
+GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
+GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
+GNULIB_PERROR = @GNULIB_PERROR@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_POPEN = @GNULIB_POPEN@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PRINTF = @GNULIB_PRINTF@
+GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PUTC = @GNULIB_PUTC@
+GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
+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_RMDIR = @GNULIB_RMDIR@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
+GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
+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_STRNCAT = @GNULIB_STRNCAT@
+GNULIB_STRNDUP = @GNULIB_STRNDUP@
+GNULIB_STRNLEN = @GNULIB_STRNLEN@
+GNULIB_STRPBRK = @GNULIB_STRPBRK@
+GNULIB_STRSEP = @GNULIB_STRSEP@
+GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
+GNULIB_STRSTR = @GNULIB_STRSTR@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_TMPFILE = @GNULIB_TMPFILE@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
+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_VASPRINTF = @GNULIB_VASPRINTF@
+GNULIB_VDPRINTF = @GNULIB_VDPRINTF@
+GNULIB_VFPRINTF = @GNULIB_VFPRINTF@
+GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
+GNULIB_VPRINTF = @GNULIB_VPRINTF@
+GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
+GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
+GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+GRUB_BOOT_MACHINE_LINK_ADDR = @GRUB_BOOT_MACHINE_LINK_ADDR@
+HAVE_ASM_USCORE = @HAVE_ASM_USCORE@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+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_MEMMEM = @HAVE_DECL_MEMMEM@
+HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
+HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@
+HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
+HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@
+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_STRTOK_R = @HAVE_DECL_STRTOK_R@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+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_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FSEEKO = @HAVE_FSEEKO@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTELLO = @HAVE_FTELLO@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_GETDOMAINNAME = @HAVE_GETDOMAINNAME@
+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_GRANTPT = @HAVE_GRANTPT@
+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_LCHOWN = @HAVE_LCHOWN@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+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_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SETENV = @HAVE_SETENV@
+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_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_STRPBRK = @HAVE_STRPBRK@
+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_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_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_TTYNAME_R = @HAVE_TTYNAME_R@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSETENV = @HAVE_UNSETENV@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+HELP2MAN = @HELP2MAN@
+HOST_CC = @HOST_CC@
+HOST_CCASFLAGS = @HOST_CCASFLAGS@
+HOST_CFLAGS = @HOST_CFLAGS@
+HOST_CPPFLAGS = @HOST_CPPFLAGS@
+HOST_LDFLAGS = @HOST_LDFLAGS@
+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@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBCURSES = @LIBCURSES@
+LIBDEVMAPPER = @LIBDEVMAPPER@
+LIBGEOM = @LIBGEOM@
+LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@
+LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBLZMA = @LIBLZMA@
+LIBNVPAIR = @LIBNVPAIR@
+LIBOBJS = @LIBOBJS@
+LIBPCIACCESS = @LIBPCIACCESS@
+LIBS = @LIBS@
+LIBSDL = @LIBSDL@
+LIBUSB = @LIBUSB@
+LIBUTIL = @LIBUTIL@
+LIBZFS = @LIBZFS@
+LN_S = @LN_S@
+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@
+NEED_ENABLE_EXECUTE_STACK = @NEED_ENABLE_EXECUTE_STACK@
+NEED_REGISTER_FRAME_INFO = @NEED_REGISTER_FRAME_INFO@
+NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_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_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_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_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_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_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_GETOPT_H = @NEXT_GETOPT_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_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_WAIT_H = @NEXT_SYS_WAIT_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+NM = @NM@
+OBJCONV = @OBJCONV@
+OBJCOPY = @OBJCOPY@
+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_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+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_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+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_FTELL = @REPLACE_FTELL@
+REPLACE_FTELLO = @REPLACE_FTELLO@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+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_MEMCHR = @REPLACE_MEMCHR@
+REPLACE_MEMMEM = @REPLACE_MEMMEM@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+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_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@
+REPLACE_STPNCPY = @REPLACE_STPNCPY@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+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_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+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_WCTOB = @REPLACE_WCTOB@
+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@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+SYSEXITS_H = @SYSEXITS_H@
+TARGET_APPLE_CC = @TARGET_APPLE_CC@
+TARGET_CC = @TARGET_CC@
+TARGET_CCAS = @TARGET_CCAS@
+TARGET_CCASFLAGS = @TARGET_CCASFLAGS@
+TARGET_CFLAGS = @TARGET_CFLAGS@
+TARGET_CPP = @TARGET_CPP@
+TARGET_CPPFLAGS = @TARGET_CPPFLAGS@
+TARGET_IMG_BASE_LDOPT = @TARGET_IMG_BASE_LDOPT@
+TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@
+TARGET_IMG_LDFLAGS = @TARGET_IMG_LDFLAGS@
+TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@
+TARGET_LDFLAGS = @TARGET_LDFLAGS@
+TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@
+TARGET_OBJ2ELF = @TARGET_OBJ2ELF@
+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_APPLE_CC_FIXES = @USE_APPLE_CC_FIXES@
+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@
+ac_ct_TARGET_CC = @ac_ct_TARGET_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@
+bootdirname = @bootdirname@
+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@
+enable_efiemu = @enable_efiemu@
+enable_grub_emu_pci = @enable_grub_emu_pci@
+enable_grub_emu_sdl = @enable_grub_emu_sdl@
+enable_grub_emu_usb = @enable_grub_emu_usb@
+enable_grub_mkfont = @enable_grub_mkfont@
+exec_prefix = @exec_prefix@
+freetype_cflags = @freetype_cflags@
+freetype_libs = @freetype_libs@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+grubdirname = @grubdirname@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_kernel = @host_kernel@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkglibrootdir = @pkglibrootdir@
+platform = @platform@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = 1.5 gnits
+SUBDIRS =
+noinst_HEADERS =
+noinst_LIBRARIES = libgnu.a
+noinst_LTLIBRARIES =
+EXTRA_DIST = alloca.c alloca.in.h \
+ $(top_srcdir)/build-aux/arg-nonnull.h btowc.c \
+ $(top_srcdir)/build-aux/c++defs.h basename-lgpl.c \
+ dirname-lgpl.c dirname.h stripslash.c errno.in.h error.c \
+ error.h float.in.h fnmatch.c fnmatch.in.h fnmatch_loop.c \
+ getdelim.c getline.c getopt.c getopt.in.h getopt1.c \
+ getopt_int.h $(top_srcdir)/build-aux/config.rpath \
+ $(top_srcdir)/build-aux/config.rpath intprops.h langinfo.in.h \
+ config.charset ref-add.sin ref-del.sin malloc.c malloc.c \
+ mbrtowc.c mbsinit.c mbsrtowcs-state.c mbsrtowcs.c memchr.c \
+ memchr.valgrind mempcpy.c nl_langinfo.c rawmemchr.c \
+ rawmemchr.valgrind realloc.c regcomp.c regex.c regex.h \
+ regex_internal.c regex_internal.h regexec.c sleep.c \
+ stdbool.in.h stddef.in.h stdint.in.h stdio-write.c stdio.in.h \
+ stdlib.in.h strcasecmp.c strncasecmp.c strchrnul.c \
+ strchrnul.valgrind streq.h strerror.c string.in.h strings.in.h \
+ strndup.c strnlen.c sys_wait.in.h sysexits.in.h unistd.in.h \
+ asnprintf.c float+.h printf-args.c printf-args.h \
+ printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h \
+ vsnprintf.c $(top_srcdir)/build-aux/warn-on-use.h wchar.in.h \
+ wcrtomb.c wctype.in.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) arg-nonnull.h c++defs.h configmake.h \
+ $(ERRNO_H) $(FLOAT_H) $(FNMATCH_H) $(GETOPT_H) langinfo.h \
+ $(STDBOOL_H) $(STDDEF_H) $(STDINT_H) stdio.h stdlib.h string.h \
+ strings.h sys/wait.h $(SYSEXITS_H) unistd.h warn-on-use.h \
+ wchar.h wctype.h
+SUFFIXES = .sed .sin
+MOSTLYCLEANFILES = core *.stackdump alloca.h alloca.h-t arg-nonnull.h \
+ arg-nonnull.h-t c++defs.h c++defs.h-t errno.h errno.h-t \
+ float.h float.h-t fnmatch.h fnmatch.h-t getopt.h getopt.h-t \
+ langinfo.h langinfo.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/wait.h sys/wait.h-t sysexits.h sysexits.h-t unistd.h \
+ unistd.h-t warn-on-use.h warn-on-use.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 =
+
+# 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 = 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 \
+ gettext.h localcharset.h localcharset.c progname.h progname.c \
+ size_max.h strnlen1.h strnlen1.c verify.h xsize.h
+libgnu_a_LIBADD = $(gl_LIBOBJS) @ALLOCA@
+libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) @ALLOCA@
+EXTRA_libgnu_a_SOURCES = alloca.c btowc.c basename-lgpl.c \
+ dirname-lgpl.c stripslash.c error.c fnmatch.c fnmatch_loop.c \
+ getdelim.c getline.c getopt.c getopt1.c malloc.c malloc.c \
+ mbrtowc.c mbsinit.c mbsrtowcs-state.c mbsrtowcs.c memchr.c \
+ mempcpy.c nl_langinfo.c rawmemchr.c realloc.c regcomp.c \
+ regex.c regex_internal.c regexec.c sleep.c stdio-write.c \
+ strcasecmp.c strncasecmp.c strchrnul.c strerror.c strndup.c \
+ strnlen.c asnprintf.c printf-args.c printf-parse.c \
+ vasnprintf.c vsnprintf.c wcrtomb.c
+ARG_NONNULL_H = arg-nonnull.h
+CXXDEFS_H = c++defs.h
+charset_alias = $(DESTDIR)$(libdir)/charset.alias
+charset_tmp = $(DESTDIR)$(libdir)/charset.tmp
+WARN_ON_USE_H = warn-on-use.h
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .sed .sin .c .o .obj
+$(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 grub-core/gnulib/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnits grub-core/gnulib/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)
+libgnu.a: $(libgnu_a_OBJECTS) $(libgnu_a_DEPENDENCIES)
+ -rm -f libgnu.a
+ $(libgnu_a_AR) libgnu.a $(libgnu_a_OBJECTS) $(libgnu_a_LIBADD)
+ $(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)
+
+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)/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-xinl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asnprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basename-lgpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btowc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirname-lgpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.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)/getdelim.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)/localcharset.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbrtowc.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)/memchr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mempcpy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nl_langinfo.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)/progname.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rawmemchr.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)/sleep.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdio-write.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)/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)/vasnprintf.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@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@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 $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@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 `$(CYGPATH_W) '$<'`
+
+# 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)
+ -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."
+ -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)
+ -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)
+ -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.
+alloca.h: alloca.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ cat $(srcdir)/alloca.in.h; \
+ } > $@-t && \
+ mv -f $@-t $@
+# The arg-nonnull.h that gets inserted into generated .h files is the same as
+# build-aux/arg-nonnull.h, except that it has the copyright header cut off.
+arg-nonnull.h: $(top_srcdir)/build-aux/arg-nonnull.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/GL_ARG_NONNULL/,$$p' \
+ < $(top_srcdir)/build-aux/arg-nonnull.h \
+ > $@-t && \
+ mv $@-t $@
+# The c++defs.h that gets inserted into generated .h files is the same as
+# build-aux/c++defs.h, except that it has the copyright header cut off.
+c++defs.h: $(top_srcdir)/build-aux/c++defs.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/_GL_CXXDEFS/,$$p' \
+ < $(top_srcdir)/build-aux/c++defs.h \
+ > $@-t && \
+ mv $@-t $@
+
+# Retrieve values of the variables through 'configure' followed by
+# 'make', not directly through 'configure', so that a user who
+# sets some of these variables consistently on the 'make' command
+# line gets correct results.
+#
+# One advantage of this approach, compared to the classical
+# approach of adding -DLIBDIR=\"$(libdir)\" etc. to AM_CPPFLAGS,
+# is that it protects against the use of undefined variables.
+# If, say, $(libdir) is not set in the Makefile, LIBDIR is not
+# defined by this module, and code using LIBDIR gives a
+# compilation error.
+#
+# Another advantage is that 'make' output is shorter.
+#
+# Listed in the same order as the GNU makefile conventions.
+# 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 && \
+ if test -f $@ && cmp $@-t $@ > /dev/null; then \
+ rm -f $@-t; \
+ else \
+ rm -f $@; mv $@-t $@; \
+ fi
+
+# We need the following in order to create <errno.h> when the system
+# doesn't have one that is POSIX compliant.
+errno.h: errno.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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 $@
+
+# We need the following in order to create <float.h> when the system
+# doesn't have one that works with the given compiler.
+float.h: float.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \
+ < $(srcdir)/float.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+
+# We need the following in order to create <fnmatch.h> when the system
+# doesn't have one that supports the required API.
+fnmatch.h: fnmatch.in.h $(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 $@
+
+# 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 $(ARG_NONNULL_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''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 an empty placeholder for
+# <langinfo.h> when the system doesn't have one.
+langinfo.h: langinfo.in.h $(CXXDEFS_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''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-$@ $@
+
+# We need the following in order to create <stdbool.h> when the system
+# doesn't have one that works.
+stdbool.h: stdbool.in.h
+ $(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 $@
+
+# We need the following in order to create <stddef.h> when the system
+# doesn't have one that works with the given compiler.
+stddef.h: stddef.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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 $@
+
+# We need the following in order to create <stdint.h> when the system
+# doesn't have one that works with the given compiler.
+stdint.h: stdint.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''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_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 $@
+
+# 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 $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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_FFLUSH''@|$(GNULIB_FFLUSH)|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_FREOPEN''@|$(GNULIB_FREOPEN)|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_GETDELIM''@|$(GNULIB_GETDELIM)|g' \
+ -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \
+ -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \
+ -e 's|@''GNULIB_OBSTACK_PRINTF_POSIX''@|$(GNULIB_OBSTACK_PRINTF_POSIX)|g' \
+ -e 's|@''GNULIB_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_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \
+ -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|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_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_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_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_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_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 $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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_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_PTSNAME''@|$(GNULIB_PTSNAME)|g' \
+ -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|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_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \
+ -e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \
+ -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_PTSNAME''@|$(HAVE_PTSNAME)|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_SETENV''@|$(HAVE_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_UNSETENV''@|$(HAVE_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_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+ -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|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 '/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)/stdlib.in.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 $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|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_STRSIGNAL''@|$(GNULIB_STRSIGNAL)|g' \
+ -e 's|@''GNULIB_STRVERSCMP''@|$(GNULIB_STRVERSCMP)|g' \
+ < $(srcdir)/string.in.h | \
+ sed -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_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_STRDUP''@|$(REPLACE_STRDUP)|g' \
+ -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \
+ -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|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 $(WARN_ON_USE_H) $(ARG_NONNULL_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \
+ -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \
+ -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \
+ -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/wait.h> when the system
+# has one that is incomplete.
+sys/wait.h: sys_wait.in.h
+ $(AM_V_at)$(MKDIR_P) sys
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''NEXT_SYS_WAIT_H''@|$(NEXT_SYS_WAIT_H)|g' \
+ < $(srcdir)/sys_wait.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.
+sysexits.h: sysexits.in.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''NEXT_SYSEXITS_H''@|$(NEXT_SYSEXITS_H)|g' \
+ < $(srcdir)/sysexits.in.h; \
+ } > $@-t && \
+ mv -f $@-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 $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \
+ -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \
+ -e 's|@''GNULIB_CLOSE''@|$(GNULIB_CLOSE)|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_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_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_PIPE2''@|$(GNULIB_PIPE2)|g' \
+ -e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \
+ -e 's|@''GNULIB_PWRITE''@|$(GNULIB_PWRITE)|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_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''@|$(GNULIB_UNISTD_H_GETOPT)|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_FSYNC''@|$(HAVE_FSYNC)|g' \
+ -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \
+ -e 's|@''HAVE_GETDOMAINNAME''@|$(HAVE_GETDOMAINNAME)|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_LCHOWN''@|$(HAVE_LCHOWN)|g' \
+ -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \
+ -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|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_SLEEP''@|$(HAVE_SLEEP)|g' \
+ -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \
+ -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \
+ -e 's|@''HAVE_TTYNAME_R''@|$(HAVE_TTYNAME_R)|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_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_OS_H''@|$(HAVE_OS_H)|g' \
+ -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \
+ -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_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \
+ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|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_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 $@
+# The warn-on-use.h that gets inserted into generated .h files is the same as
+# build-aux/warn-on-use.h, except that it has the copyright header cut off.
+warn-on-use.h: $(top_srcdir)/build-aux/warn-on-use.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/^.ifndef/,$$p' \
+ < $(top_srcdir)/build-aux/warn-on-use.h \
+ > $@-t && \
+ mv $@-t $@
+
+# We need the following in order to create <wchar.h> when the system
+# version does not work standalone.
+wchar.h: wchar.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|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|@''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_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \
+ -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \
+ -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 '/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)/wchar.in.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 $(CXXDEFS_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -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|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \
+ -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \
+ -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/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 '/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/grub-core/gnulib/alloca.c b/grub-core/gnulib/alloca.c
new file mode 100644
index 0000000..75afdb9
--- /dev/null
+++ b/grub-core/gnulib/alloca.c
@@ -0,0 +1,489 @@
+/* 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 void
+find_stack_direction (void)
+{
+ static char *addr = NULL; /* Address of first `dummy', once known. */
+ auto char dummy; /* To get stack address. */
+
+ if (addr == NULL)
+ { /* Initial entry. */
+ addr = ADDRESS_FUNCTION (dummy);
+
+ find_stack_direction (); /* Recurse once. */
+ }
+ else
+ {
+ /* Second entry. */
+ if (ADDRESS_FUNCTION (dummy) > addr)
+ stack_dir = 1; /* Stack grew upward. */
+ else
+ stack_dir = -1; /* Stack grew downward. */
+ }
+}
+
+# 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. */
+ find_stack_direction ();
+# 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 version 3 */
diff --git a/grub-core/gnulib/alloca.in.h b/grub-core/gnulib/alloca.in.h
new file mode 100644
index 0000000..44f20b7
--- /dev/null
+++ b/grub-core/gnulib/alloca.in.h
@@ -0,0 +1,56 @@
+/* Memory allocation on the stack.
+
+ Copyright (C) 1995, 1999, 2001-2004, 2006-2010 Free Software Foundation,
+ Inc.
+
+ This program is free software; you can redistribute 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/grub-core/gnulib/argp-ba.c b/grub-core/gnulib/argp-ba.c
new file mode 100644
index 0000000..95feabb
--- /dev/null
+++ b/grub-core/gnulib/argp-ba.c
@@ -0,0 +1,34 @@
+/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
+ Copyright (C) 1996, 1997, 1999, 2009, 2010 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/grub-core/gnulib/argp-eexst.c b/grub-core/gnulib/argp-eexst.c
new file mode 100644
index 0000000..115a8cd
--- /dev/null
+++ b/grub-core/gnulib/argp-eexst.c
@@ -0,0 +1,30 @@
+/* Default definition for ARGP_ERR_EXIT_STATUS
+ Copyright (C) 1997, 2009, 2010 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/grub-core/gnulib/argp-fmtstream.c b/grub-core/gnulib/argp-fmtstream.c
new file mode 100644
index 0000000..70bbebc
--- /dev/null
+++ b/grub-core/gnulib/argp-fmtstream.c
@@ -0,0 +1,435 @@
+/* Word-wrapping and line-truncating streams
+ Copyright (C) 1997-1999, 2001-2003, 2005, 2009-2010 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/grub-core/gnulib/argp-fmtstream.h b/grub-core/gnulib/argp-fmtstream.h
new file mode 100644
index 0000000..b913d1b
--- /dev/null
+++ b/grub-core/gnulib/argp-fmtstream.h
@@ -0,0 +1,354 @@
+/* Word-wrapping and line-truncating streams.
+ Copyright (C) 1997, 2006-2010 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>
+
+#ifndef __attribute__
+/* 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 __attribute__ 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 __attribute__(Spec) /* empty */
+# endif
+#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, ...)
+ __attribute__ ((__format__ (printf, 2, 3)));
+extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
+ const char *__fmt, ...)
+ __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/grub-core/gnulib/argp-fs-xinl.c b/grub-core/gnulib/argp-fs-xinl.c
new file mode 100644
index 0000000..2c683f9
--- /dev/null
+++ b/grub-core/gnulib/argp-fs-xinl.c
@@ -0,0 +1,42 @@
+/* Real definitions for extern inline functions in argp-fmtstream.h
+ Copyright (C) 1997, 2003, 2004, 2009, 2010 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/grub-core/gnulib/argp-help.c b/grub-core/gnulib/argp-help.c
new file mode 100644
index 0000000..5b6d950
--- /dev/null
+++ b/grub-core/gnulib/argp-help.c
@@ -0,0 +1,1951 @@
+/* Hierarchial argument parsing help output
+ Copyright (C) 1995-2005, 2007, 2009-2010 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 an 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 a 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
+__attribute__ ((always_inline))
+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 a 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 - 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 a 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)
+ 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/grub-core/gnulib/argp-namefrob.h b/grub-core/gnulib/argp-namefrob.h
new file mode 100644
index 0000000..24581a6
--- /dev/null
+++ b/grub-core/gnulib/argp-namefrob.h
@@ -0,0 +1,157 @@
+/* Name frobnication for compiling argp outside of glibc
+ Copyright (C) 1997, 2003, 2007, 2009, 2010 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/grub-core/gnulib/argp-parse.c b/grub-core/gnulib/argp-parse.c
new file mode 100644
index 0000000..9c05465
--- /dev/null
+++ b/grub-core/gnulib/argp-parse.c
@@ -0,0 +1,952 @@
+/* Hierarchial argument parsing, layered over getopt
+ Copyright (C) 1995-2000, 2002-2004, 2009-2010 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 <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 alignof(type) offsetof (struct { char c; type x; }, x)
+#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, 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;
+ /* An 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 && state->pstate)
+ {
+ 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/grub-core/gnulib/argp-pin.c b/grub-core/gnulib/argp-pin.c
new file mode 100644
index 0000000..eda4d95
--- /dev/null
+++ b/grub-core/gnulib/argp-pin.c
@@ -0,0 +1,27 @@
+/* Full and short program names for argp module
+ Copyright (C) 2005, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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/grub-core/gnulib/argp-pv.c b/grub-core/gnulib/argp-pv.c
new file mode 100644
index 0000000..e3227d3
--- /dev/null
+++ b/grub-core/gnulib/argp-pv.c
@@ -0,0 +1,34 @@
+/* Default definition for ARGP_PROGRAM_VERSION.
+ Copyright (C) 1996, 1997, 1999, 2006, 2009, 2010 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/grub-core/gnulib/argp-pvh.c b/grub-core/gnulib/argp-pvh.c
new file mode 100644
index 0000000..fb98fc2
--- /dev/null
+++ b/grub-core/gnulib/argp-pvh.c
@@ -0,0 +1,31 @@
+/* Default definition for ARGP_PROGRAM_VERSION_HOOK.
+ Copyright (C) 1996, 1997, 1999, 2004, 2009, 2010 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/grub-core/gnulib/argp-xinl.c b/grub-core/gnulib/argp-xinl.c
new file mode 100644
index 0000000..6e7e20b
--- /dev/null
+++ b/grub-core/gnulib/argp-xinl.c
@@ -0,0 +1,42 @@
+/* Real definitions for extern inline functions in argp.h
+ Copyright (C) 1997, 1998, 2004, 2009, 2010 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/grub-core/gnulib/argp.h b/grub-core/gnulib/argp.h
new file mode 100644
index 0000000..3667224
--- /dev/null
+++ b/grub-core/gnulib/argp.h
@@ -0,0 +1,645 @@
+/* Hierarchial argument parsing, layered over getopt.
+ Copyright (C) 1995-1999, 2003-2010 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
+
+#ifndef __attribute__
+/* 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 __attribute__ 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 __attribute__(Spec) /* empty */
+# 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. */
+#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, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)));
+extern void __argp_error (const struct argp_state *__restrict __state,
+ const char *__restrict __fmt, ...)
+ __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, ...)
+ __attribute__ ((__format__ (__printf__, 4, 5)));
+extern void __argp_failure (const struct argp_state *__restrict __state,
+ int __status, int __errnum,
+ const char *__restrict __fmt, ...)
+ __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/grub-core/gnulib/asnprintf.c b/grub-core/gnulib/asnprintf.c
new file mode 100644
index 0000000..3bd2229
--- /dev/null
+++ b/grub-core/gnulib/asnprintf.c
@@ -0,0 +1,35 @@
+/* Formatted output to strings.
+ Copyright (C) 1999, 2002, 2006, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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/grub-core/gnulib/basename-lgpl.c b/grub-core/gnulib/basename-lgpl.c
new file mode 100644
index 0000000..a35ff01
--- /dev/null
+++ b/grub-core/gnulib/basename-lgpl.c
@@ -0,0 +1,75 @@
+/* basename.c -- return the last element in a file name
+
+ Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2010 Free Software
+ Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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/grub-core/gnulib/btowc.c b/grub-core/gnulib/btowc.c
new file mode 100644
index 0000000..8744602
--- /dev/null
+++ b/grub-core/gnulib/btowc.c
@@ -0,0 +1,39 @@
+/* Convert unibyte character to wide character.
+ Copyright (C) 2008, 2010 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/grub-core/gnulib/config.charset b/grub-core/gnulib/config.charset
new file mode 100644
index 0000000..aa7d00d
--- /dev/null
+++ b/grub-core/gnulib/config.charset
@@ -0,0 +1,683 @@
+#! /bin/sh
+# Output a system dependent table of character encoding aliases.
+#
+# Copyright (C) 2000-2004, 2006-2010 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute 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
+# 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/grub-core/gnulib/dirname-lgpl.c b/grub-core/gnulib/dirname-lgpl.c
new file mode 100644
index 0000000..d4506e0
--- /dev/null
+++ b/grub-core/gnulib/dirname-lgpl.c
@@ -0,0 +1,86 @@
+/* dirname.c -- return all but the last element in a file name
+
+ Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2010 Free Software
+ Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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/grub-core/gnulib/dirname.h b/grub-core/gnulib/dirname.h
new file mode 100644
index 0000000..fb19508
--- /dev/null
+++ b/grub-core/gnulib/dirname.h
@@ -0,0 +1,74 @@
+/* Take file names apart into directory and base names.
+
+ Copyright (C) 1998, 2001, 2003-2006, 2009-2010 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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>
+
+# ifndef DIRECTORY_SEPARATOR
+# define DIRECTORY_SEPARATOR '/'
+# endif
+
+# ifndef ISSLASH
+# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
+# endif
+
+# ifndef FILE_SYSTEM_PREFIX_LEN
+# if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+ /* 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)
+# else
+# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
+# endif
+# endif
+
+# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
+# endif
+
+# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
+# define DOUBLE_SLASH_IS_DISTINCT_ROOT 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]) || 0 < FILE_SYSTEM_PREFIX_LEN (F))
+# endif
+# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
+
+# 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);
+size_t dir_len (char const *file);
+char *last_component (char const *file);
+
+bool strip_trailing_slashes (char *file);
+
+#endif /* not DIRNAME_H_ */
diff --git a/grub-core/gnulib/errno.in.h b/grub-core/gnulib/errno.in.h
new file mode 100644
index 0000000..140e5d1
--- /dev/null
+++ b/grub-core/gnulib/errno.in.h
@@ -0,0 +1,160 @@
+/* A POSIX-like <errno.h>.
+
+ Copyright (C) 2008-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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_ERRNO_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_ERRNO_H@
+
+#ifndef _GL_ERRNO_H
+#define _GL_ERRNO_H
+
+
+/* On native Windows platforms, many macros are not defined. */
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+/* POSIX says that EAGAIN and EWOULDBLOCK may have the same value. */
+# define EWOULDBLOCK EAGAIN
+
+/* Values >= 100 seem safe to use. */
+# define ETXTBSY 100
+# define GNULIB_defined_ETXTBSY 1
+
+/* These are intentionally the same values as the WSA* error numbers, defined
+ in <winsock2.h>. */
+# define EINPROGRESS 10036
+# define EALREADY 10037
+# define ENOTSOCK 10038
+# define EDESTADDRREQ 10039
+# define EMSGSIZE 10040
+# define EPROTOTYPE 10041
+# define ENOPROTOOPT 10042
+# define EPROTONOSUPPORT 10043
+# define ESOCKTNOSUPPORT 10044 /* not required by POSIX */
+# define EOPNOTSUPP 10045
+# define EPFNOSUPPORT 10046 /* not required by POSIX */
+# define EAFNOSUPPORT 10047
+# define EADDRINUSE 10048
+# define EADDRNOTAVAIL 10049
+# define ENETDOWN 10050
+# define ENETUNREACH 10051
+# define ENETRESET 10052
+# define ECONNABORTED 10053
+# define ECONNRESET 10054
+# define ENOBUFS 10055
+# define EISCONN 10056
+# define ENOTCONN 10057
+# define ESHUTDOWN 10058 /* not required by POSIX */
+# define ETOOMANYREFS 10059 /* not required by POSIX */
+# define ETIMEDOUT 10060
+# define ECONNREFUSED 10061
+# define ELOOP 10062
+# define EHOSTDOWN 10064 /* not required by POSIX */
+# define EHOSTUNREACH 10065
+# 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_ESOCK 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.
+ 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 ESTALE
+# define ESTALE 2009
+# define GNULIB_defined_ESTALE 1
+# endif
+
+# ifndef ECANCELED
+# define ECANCELED 2008
+# define GNULIB_defined_ECANCELED 1
+# endif
+
+
+#endif /* _GL_ERRNO_H */
+#endif /* _GL_ERRNO_H */
diff --git a/grub-core/gnulib/error.c b/grub-core/gnulib/error.c
new file mode 100644
index 0000000..ed9dba0
--- /dev/null
+++ b/grub-core/gnulib/error.c
@@ -0,0 +1,394 @@
+/* Error handler for noninteractive utilities
+ Copyright (C) 1990-1998, 2000-2007, 2009-2010 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 Win32 API functions. */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# endif
+
+/* The gnulib override of fcntl is not needed in this file. */
+# undef fcntl
+
+# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
+# ifndef HAVE_DECL_STRERROR_R
+"this configure-time declaration test was not run"
+# endif
+char *strerror_r ();
+# 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 Win32: 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/grub-core/gnulib/error.h b/grub-core/gnulib/error.h
new file mode 100644
index 0000000..9deef02
--- /dev/null
+++ b/grub-core/gnulib/error.h
@@ -0,0 +1,65 @@
+/* Declaration for error-reporting function
+ Copyright (C) 1995, 1996, 1997, 2003, 2006, 2008, 2009, 2010 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
+
+#ifndef __attribute__
+/* 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 __attribute__ 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 __attribute__(Spec) /* empty */
+# endif
+#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, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+
+extern void error_at_line (int __status, int __errnum, const char *__fname,
+ unsigned int __lineno, const char *__format, ...)
+ __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/grub-core/gnulib/float+.h b/grub-core/gnulib/float+.h
new file mode 100644
index 0000000..b55e5e6
--- /dev/null
+++ b/grub-core/gnulib/float+.h
@@ -0,0 +1,148 @@
+/* Supplemental information about the floating-point formats.
+ Copyright (C) 2007, 2009, 2010 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[2 * (SIZEOF_FLT <= sizeof (float)) - 1];
+typedef int verify_sizeof_dbl[2 * (SIZEOF_DBL <= sizeof (double)) - 1];
+typedef int verify_sizeof_ldbl[2 * (SIZEOF_LDBL <= sizeof (long double)) - 1];
+
+#endif /* _FLOATPLUS_H */
diff --git a/grub-core/gnulib/float.in.h b/grub-core/gnulib/float.in.h
new file mode 100644
index 0000000..caf822f
--- /dev/null
+++ b/grub-core/gnulib/float.in.h
@@ -0,0 +1,62 @@
+/* A correct <float.h>.
+
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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_FLOAT_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_FLOAT_H@
+
+#ifndef _GL_FLOAT_H
+#define _GL_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
+
+#endif /* _GL_FLOAT_H */
+#endif /* _GL_FLOAT_H */
diff --git a/grub-core/gnulib/fnmatch.c b/grub-core/gnulib/fnmatch.c
new file mode 100644
index 0000000..d73e47d
--- /dev/null
+++ b/grub-core/gnulib/fnmatch.c
@@ -0,0 +1,354 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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)
+# define STRCOLL(S1, S2) strcoll (S1, S2)
+# 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 STRCOLL(S1, S2) wcscoll (S1, S2)
+# 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/grub-core/gnulib/fnmatch.in.h b/grub-core/gnulib/fnmatch.in.h
new file mode 100644
index 0000000..8caab19
--- /dev/null
+++ b/grub-core/gnulib/fnmatch.in.h
@@ -0,0 +1,68 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003,
+ 2005, 2007, 2009, 2010 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/grub-core/gnulib/fnmatch_loop.c b/grub-core/gnulib/fnmatch_loop.c
new file mode 100644
index 0000000..741c993
--- /dev/null
+++ b/grub-core/gnulib/fnmatch_loop.c
@@ -0,0 +1,1215 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004, 2005, 2006, 2009, 2010 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. */
+ 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) loses. */
+ return FNM_NOMATCH;
+ 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 STRCOLL
+#undef STRLEN
+#undef STRCAT
+#undef L_
+#undef BTOWC
diff --git a/grub-core/gnulib/getdelim.c b/grub-core/gnulib/getdelim.c
new file mode 100644
index 0000000..66d07b9
--- /dev/null
+++ b/grub-core/gnulib/getdelim.c
@@ -0,0 +1,137 @@
+/* getdelim.c --- Implementation of replacement getdelim function.
+ Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007, 2008,
+ 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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/grub-core/gnulib/getline.c b/grub-core/gnulib/getline.c
new file mode 100644
index 0000000..30c076e
--- /dev/null
+++ b/grub-core/gnulib/getline.c
@@ -0,0 +1,29 @@
+/* getline.c --- Implementation of replacement getline function.
+ Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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/grub-core/gnulib/getopt.c b/grub-core/gnulib/getopt.c
new file mode 100644
index 0000000..3791f12
--- /dev/null
+++ b/grub-core/gnulib/getopt.c
@@ -0,0 +1,1192 @@
+/* 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-2010 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;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = d->__nextchar; *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)
+ == (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. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ if (__asprintf (&buf, _("%s: option '%s' is ambiguous\n"),
+ argv[0], argv[d->optind]) >= 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' is ambiguous\n"),
+ argv[0], argv[d->optind]);
+#endif
+ }
+ d->__nextchar += strlen (d->__nextchar);
+ d->optind++;
+ d->optopt = 0;
+ return '?';
+ }
+
+ 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;
+
+ /* 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;
+ }
+ 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/grub-core/gnulib/getopt.in.h b/grub-core/gnulib/getopt.in.h
new file mode 100644
index 0000000..57a8e89
--- /dev/null
+++ b/grub-core/gnulib/getopt.in.h
@@ -0,0 +1,249 @@
+/* Declarations for getopt.
+ Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2007, 2009-2010 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 _GL_GETOPT_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+/* 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 _GL_GETOPT_H
+
+#ifndef __need_getopt
+# define _GL_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. */
+
+struct option
+{
+ const char *name;
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#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 /* getopt.h */
+#endif /* getopt.h */
diff --git a/grub-core/gnulib/getopt1.c b/grub-core/gnulib/getopt1.c
new file mode 100644
index 0000000..046d69f
--- /dev/null
+++ b/grub-core/gnulib/getopt1.c
@@ -0,0 +1,170 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997,
+ 1998, 2004, 2006, 2009, 2010 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/grub-core/gnulib/getopt_int.h b/grub-core/gnulib/getopt_int.h
new file mode 100644
index 0000000..980b750
--- /dev/null
+++ b/grub-core/gnulib/getopt_int.h
@@ -0,0 +1,135 @@
+/* Internal declarations for getopt.
+ Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2004, 2009-2010 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/grub-core/gnulib/gettext.h b/grub-core/gnulib/gettext.h
new file mode 100644
index 0000000..881ae33
--- /dev/null
+++ b/grub-core/gnulib/gettext.h
@@ -0,0 +1,280 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2010 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute 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) || _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
+
+/* 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) && !__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/grub-core/gnulib/intprops.h b/grub-core/gnulib/intprops.h
new file mode 100644
index 0000000..46f4d47
--- /dev/null
+++ b/grub-core/gnulib/intprops.h
@@ -0,0 +1,83 @@
+/* intprops.h -- properties of integer types
+
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009, 2010 Free Software
+ Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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>
+
+/* 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 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 \
+ : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
+# define TYPE_MAXIMUM(t) \
+ ((t) (! TYPE_SIGNED (t) \
+ ? (t) -1 \
+ : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
+
+/* Return zero if T can be determined to be an unsigned type.
+ Otherwise, return 1.
+ When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a
+ tighter bound. Otherwise, it overestimates the true bound by one byte
+ when applied to unsigned types of size 2, 4, 16, ... bytes.
+ The symbol signed_type_or_expr__ is private to this header file. */
+# if __GNUC__ >= 2
+# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t))
+# else
+# define signed_type_or_expr__(t) 1
+# endif
+
+/* Bound on length of the string representing an integer type or expression T.
+ Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485;
+ add 1 for integer division truncation; add 1 more for a minus sign
+ if needed. */
+# define INT_STRLEN_BOUND(t) \
+ ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \
+ + signed_type_or_expr__ (t) + 1)
+
+/* 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)
+
+#endif /* GL_INTPROPS_H */
diff --git a/grub-core/gnulib/langinfo.in.h b/grub-core/gnulib/langinfo.in.h
new file mode 100644
index 0000000..3a92647
--- /dev/null
+++ b/grub-core/gnulib/langinfo.in.h
@@ -0,0 +1,173 @@
+/* Substitute for and wrapper around <langinfo.h>.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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 _GL_LANGINFO_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+/* The include_next requires a split double-inclusion guard. */
+#if @HAVE_LANGINFO_H@
+# @INCLUDE_NEXT@ @NEXT_LANGINFO_H@
+#endif
+
+#ifndef _GL_LANGINFO_H
+#define _GL_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. */
+typedef int nl_item;
+
+/* 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 /* _GL_LANGINFO_H */
+#endif /* _GL_LANGINFO_H */
diff --git a/grub-core/gnulib/localcharset.c b/grub-core/gnulib/localcharset.c
new file mode 100644
index 0000000..fa2207f
--- /dev/null
+++ b/grub-core/gnulib/localcharset.c
@@ -0,0 +1,548 @@
+/* Determine a canonical name for the current locale's character encoding.
+
+ Copyright (C) 2000-2006, 2008-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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 WIN32_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 WIN32_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 WIN32_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__
+ /* Win32, 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 WIN32_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;
+ if (old_res_ptr != NULL)
+ 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 WIN32_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 WIN32_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;
+ }
+ }
+ }
+
+ /* Woe32 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 WIN32_NATIVE
+
+ static char buf[2 + 10 + 1];
+
+ /* Woe32 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/grub-core/gnulib/localcharset.h b/grub-core/gnulib/localcharset.h
new file mode 100644
index 0000000..899b3ba
--- /dev/null
+++ b/grub-core/gnulib/localcharset.h
@@ -0,0 +1,41 @@
+/* Determine a canonical name for the current locale's character encoding.
+ Copyright (C) 2000-2003, 2009-2010 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/grub-core/gnulib/malloc.c b/grub-core/gnulib/malloc.c
new file mode 100644
index 0000000..4fa38ee
--- /dev/null
+++ b/grub-core/gnulib/malloc.c
@@ -0,0 +1,60 @@
+/* malloc() function that is glibc compatible.
+
+ Copyright (C) 1997-1998, 2006-2007, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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 */
+
+#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
+
+/* Specification. */
+#include <stdlib.h>
+
+#include <errno.h>
+
+/* Call the system's malloc below. */
+#undef malloc
+
+/* 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/grub-core/gnulib/mbrtowc.c b/grub-core/gnulib/mbrtowc.c
new file mode 100644
index 0000000..5c2650e
--- /dev/null
+++ b/grub-core/gnulib/mbrtowc.c
@@ -0,0 +1,386 @@
+/* Convert multibyte character to wide character.
+ Copyright (C) 1999-2002, 2005-2010 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 (pstate == NULL)
+ pstate = internal_state;
+
+ if (s == NULL)
+ {
+ pwc = NULL;
+ s = "";
+ n = 1;
+ }
+
+ if (n == 0)
+ return (size_t)(-2);
+
+ /* Here n > 0. */
+ {
+ 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__
+ /* 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_ARG_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 can not 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
+ return mbrtowc (pwc, s, n, ps);
+# endif
+}
+
+#endif
diff --git a/grub-core/gnulib/mbsinit.c b/grub-core/gnulib/mbsinit.c
new file mode 100644
index 0000000..066ddfe
--- /dev/null
+++ b/grub-core/gnulib/mbsinit.c
@@ -0,0 +1,47 @@
+/* Test for initial conversion state.
+ Copyright (C) 2008, 2009, 2010 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"
+
+/* 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[0] == 0;
+}
diff --git a/grub-core/gnulib/mbsrtowcs-state.c b/grub-core/gnulib/mbsrtowcs-state.c
new file mode 100644
index 0000000..35045f6
--- /dev/null
+++ b/grub-core/gnulib/mbsrtowcs-state.c
@@ -0,0 +1,37 @@
+/* Convert string to wide string.
+ Copyright (C) 2008-2010 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/grub-core/gnulib/mbsrtowcs.c b/grub-core/gnulib/mbsrtowcs.c
new file mode 100644
index 0000000..c577f36
--- /dev/null
+++ b/grub-core/gnulib/mbsrtowcs.c
@@ -0,0 +1,136 @@
+/* Convert string to wide string.
+ Copyright (C) 2008, 2009, 2010 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;
+
+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/grub-core/gnulib/memchr.c b/grub-core/gnulib/memchr.c
new file mode 100644
index 0000000..6c2b2d6
--- /dev/null
+++ b/grub-core/gnulib/memchr.c
@@ -0,0 +1,172 @@
+/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2010
+ 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/grub-core/gnulib/memchr.valgrind b/grub-core/gnulib/memchr.valgrind
new file mode 100644
index 0000000..60f247e
--- /dev/null
+++ b/grub-core/gnulib/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/grub-core/gnulib/mempcpy.c b/grub-core/gnulib/mempcpy.c
new file mode 100644
index 0000000..b624d69
--- /dev/null
+++ b/grub-core/gnulib/mempcpy.c
@@ -0,0 +1,29 @@
+/* Copy memory area and return pointer after last written byte.
+ Copyright (C) 2003, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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/grub-core/gnulib/nl_langinfo.c b/grub-core/gnulib/nl_langinfo.c
new file mode 100644
index 0000000..a3d0d11
--- /dev/null
+++ b/grub-core/gnulib/nl_langinfo.c
@@ -0,0 +1,270 @@
+/* nl_langinfo() replacement: query locale dependent information.
+
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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
+ 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];
+
+ /* Woe32 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/grub-core/gnulib/printf-args.c b/grub-core/gnulib/printf-args.c
new file mode 100644
index 0000000..46c03a2
--- /dev/null
+++ b/grub-core/gnulib/printf-args.c
@@ -0,0 +1,188 @@
+/* Decomposed printf argument list.
+ Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2010 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute 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/grub-core/gnulib/printf-args.h b/grub-core/gnulib/printf-args.h
new file mode 100644
index 0000000..2536eba
--- /dev/null
+++ b/grub-core/gnulib/printf-args.h
@@ -0,0 +1,155 @@
+/* Decomposed printf argument list.
+ Copyright (C) 1999, 2002-2003, 2006-2007, 2009-2010 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute 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;
+
+typedef struct
+{
+ size_t count;
+ argument *arg;
+}
+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/grub-core/gnulib/printf-parse.c b/grub-core/gnulib/printf-parse.c
new file mode 100644
index 0000000..f612beb
--- /dev/null
+++ b/grub-core/gnulib/printf-parse.c
@@ -0,0 +1,627 @@
+/* Formatted output to strings.
+ Copyright (C) 1999-2000, 2002-2003, 2006-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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>
+
+/* 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 = 1;
+ d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
+ if (d->dir == NULL)
+ /* Out of memory. */
+ goto out_of_memory_1;
+
+ a->count = 0;
+ a_allocated = 0;
+ a->arg = NULL;
+
+#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 \
+ ? realloc (a->arg, memory_size) \
+ : malloc (memory_size)); \
+ if (memory == NULL) \
+ /* Out of memory. */ \
+ goto out_of_memory; \
+ 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++;
+ }
+ 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 Win32, 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 *) realloc (d->dir, memory_size);
+ if (memory == NULL)
+ /* Out of memory. */
+ goto out_of_memory;
+ 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)
+ free (a->arg);
+ if (d->dir)
+ free (d->dir);
+ errno = EINVAL;
+ return -1;
+
+out_of_memory:
+ if (a->arg)
+ free (a->arg);
+ if (d->dir)
+ free (d->dir);
+out_of_memory_1:
+ errno = ENOMEM;
+ return -1;
+}
+
+#undef PRINTF_PARSE
+#undef DIRECTIVES
+#undef DIRECTIVE
+#undef CHAR_T_ONLY_ASCII
+#undef CHAR_T
diff --git a/grub-core/gnulib/printf-parse.h b/grub-core/gnulib/printf-parse.h
new file mode 100644
index 0000000..0f2b708
--- /dev/null
+++ b/grub-core/gnulib/printf-parse.h
@@ -0,0 +1,180 @@
+/* Parse printf format string.
+ Copyright (C) 1999, 2002-2003, 2005, 2007, 2009-2010 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute 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. */
+
+#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
+
+/* 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. */
+
+/* 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_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_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_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_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/grub-core/gnulib/progname.c b/grub-core/gnulib/progname.c
new file mode 100644
index 0000000..1415e6a
--- /dev/null
+++ b/grub-core/gnulib/progname.c
@@ -0,0 +1,92 @@
+/* Program name management.
+ Copyright (C) 2001-2003, 2005-2010 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/grub-core/gnulib/progname.h b/grub-core/gnulib/progname.h
new file mode 100644
index 0000000..5ba303b
--- /dev/null
+++ b/grub-core/gnulib/progname.h
@@ -0,0 +1,62 @@
+/* Program name management.
+ Copyright (C) 2001-2004, 2006, 2009-2010 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/grub-core/gnulib/rawmemchr.c b/grub-core/gnulib/rawmemchr.c
new file mode 100644
index 0000000..0a88777
--- /dev/null
+++ b/grub-core/gnulib/rawmemchr.c
@@ -0,0 +1,136 @@
+/* Searching in a string.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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/grub-core/gnulib/rawmemchr.valgrind b/grub-core/gnulib/rawmemchr.valgrind
new file mode 100644
index 0000000..6363923
--- /dev/null
+++ b/grub-core/gnulib/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/grub-core/gnulib/realloc.c b/grub-core/gnulib/realloc.c
new file mode 100644
index 0000000..053208f
--- /dev/null
+++ b/grub-core/gnulib/realloc.c
@@ -0,0 +1,91 @@
+/* realloc() function that is glibc compatible.
+
+ Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2010 Free Software
+ Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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>
+
+/* 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
+
+/* Below we want to call the system's malloc and realloc.
+ Undefine the symbols here so that including <stdlib.h> provides a
+ declaration of malloc(), not of rpl_malloc(), and likewise for realloc. */
+#undef malloc
+#undef realloc
+
+/* Specification. */
+#include <stdlib.h>
+
+#include <errno.h>
+
+/* Below we want to call the system's malloc and realloc.
+ Undefine the symbols, if they were defined by gnulib's <stdlib.h>
+ replacement. */
+#undef malloc
+#undef realloc
+
+/* 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/grub-core/gnulib/ref-add.sin b/grub-core/gnulib/ref-add.sin
new file mode 100644
index 0000000..dbb61df
--- /dev/null
+++ b/grub-core/gnulib/ref-add.sin
@@ -0,0 +1,30 @@
+# Add this package to a list of references stored in a text file.
+#
+# Copyright (C) 2000, 2009, 2010 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute 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/grub-core/gnulib/ref-del.sin b/grub-core/gnulib/ref-del.sin
new file mode 100644
index 0000000..4c31a6e
--- /dev/null
+++ b/grub-core/gnulib/ref-del.sin
@@ -0,0 +1,25 @@
+# Remove this package from a list of references stored in a text file.
+#
+# Copyright (C) 2000, 2009, 2010 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute 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/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c
new file mode 100644
index 0000000..86ca02b
--- /dev/null
+++ b/grub-core/gnulib/regcomp.c
@@ -0,0 +1,3877 @@
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 (&regexp, 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 (&regexp);
+ 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 (&regexp, 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 (&regexp);
+
+ 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 (&current_token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+ tree = parse_reg_exp (regexp, preg, &current_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/grub-core/gnulib/regex.c b/grub-core/gnulib/regex.c
new file mode 100644
index 0000000..ba0eebe
--- /dev/null
+++ b/grub-core/gnulib/regex.c
@@ -0,0 +1,72 @@
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003, 2005, 2006, 2009, 2010 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 <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/grub-core/gnulib/regex.h b/grub-core/gnulib/regex.h
new file mode 100644
index 0000000..e8bd549
--- /dev/null
+++ b/grub-core/gnulib/regex.h
@@ -0,0 +1,676 @@
+/* Definitions for data structures and routines for the regular
+ expression library.
+ Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1998,
+ 2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010 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__)) \
+ && !__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/grub-core/gnulib/regex_internal.c b/grub-core/gnulib/regex_internal.c
new file mode 100644
index 0000000..98b8d5d
--- /dev/null
+++ b/grub-core/gnulib/regex_internal.c
@@ -0,0 +1,1742 @@
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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/grub-core/gnulib/regex_internal.h b/grub-core/gnulib/regex_internal.h
new file mode 100644
index 0000000..5aa5aa2
--- /dev/null
+++ b/grub-core/gnulib/regex_internal.h
@@ -0,0 +1,873 @@
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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
+#if defined HAVE_LOCALE_H || defined _LIBC
+# include <locale.h>
+#endif
+
+#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_LOCALE_H && 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 && !__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
+# if defined __i386__ && !defined __EMX__
+# define internal_function __attribute ((regparm (3), stdcall))
+# else
+# define internal_function
+# endif
+#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/grub-core/gnulib/regexec.c b/grub-core/gnulib/regexec.c
new file mode 100644
index 0000000..dc449ce
--- /dev/null
+++ b/grub-core/gnulib/regexec.c
@@ -0,0 +1,4416 @@
+/* Extended regular expression matching and search library.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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);
+ 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 && __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/grub-core/gnulib/size_max.h b/grub-core/gnulib/size_max.h
new file mode 100644
index 0000000..56d5a9b
--- /dev/null
+++ b/grub-core/gnulib/size_max.h
@@ -0,0 +1,31 @@
+/* size_max.h -- declare SIZE_MAX through system headers
+ Copyright (C) 2005-2006, 2009-2010 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/grub-core/gnulib/sleep.c b/grub-core/gnulib/sleep.c
new file mode 100644
index 0000000..213e5bd
--- /dev/null
+++ b/grub-core/gnulib/sleep.c
@@ -0,0 +1,75 @@
+/* Pausing execution of the current thread.
+ Copyright (C) 2007, 2009, 2010 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. */
+unsigned int
+rpl_sleep (unsigned int seconds)
+{
+ /* This requires int larger than 16 bits. */
+ verify (UINT_MAX / 49 / 24 / 60 / 60);
+ const unsigned int limit = 49 * 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/grub-core/gnulib/stdbool.in.h b/grub-core/gnulib/stdbool.in.h
new file mode 100644
index 0000000..574c281
--- /dev/null
+++ b/grub-core/gnulib/stdbool.in.h
@@ -0,0 +1,122 @@
+/* Copyright (C) 2001-2003, 2006-2010 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/grub-core/gnulib/stddef.in.h b/grub-core/gnulib/stddef.in.h
new file mode 100644
index 0000000..08778a2
--- /dev/null
+++ b/grub-core/gnulib/stddef.in.h
@@ -0,0 +1,86 @@
+/* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues.
+
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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
+
+#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 _GL_STDDEF_H && defined _GL_STDDEF_WINT_T)
+# ifdef __need_wint_t
+# undef _GL_STDDEF_H
+# define _GL_STDDEF_WINT_T
+# endif
+# @INCLUDE_NEXT@ @NEXT_STDDEF_H@
+# endif
+
+#else
+/* Normal invocation convention. */
+
+# ifndef _GL_STDDEF_H
+
+/* The include_next requires a split double-inclusion guard. */
+
+# @INCLUDE_NEXT@ @NEXT_STDDEF_H@
+
+# ifndef _GL_STDDEF_H
+# define _GL_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 /* _GL_STDDEF_H */
+# endif /* _GL_STDDEF_H */
+#endif /* __need_XXX */
diff --git a/grub-core/gnulib/stdint.in.h b/grub-core/gnulib/stdint.in.h
new file mode 100644
index 0000000..5da5f17
--- /dev/null
+++ b/grub-core/gnulib/stdint.in.h
@@ -0,0 +1,568 @@
+/* Copyright (C) 2001-2002, 2004-2010 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 _GL_STDINT_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+/* 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
+ /* 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
+ _GL_STDINT_H is defined.
+ The include_next requires a split double-inclusion guard. */
+# @INCLUDE_NEXT@ @NEXT_STDINT_H@
+#endif
+
+#if ! defined _GL_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H
+#define _GL_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 a 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)
+
+/* 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
+
+/* 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
+
+#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
+
+/* 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. */
+
+#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
+
+#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
+
+/* 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[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - 1];
+
+/* 7.18.2. Limits of specified-width integer types */
+
+#if ! defined __cplusplus || defined __STDC_LIMIT_MACROS
+
+/* 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
+
+#undef INT64_MIN
+#undef INT64_MAX
+#ifdef GL_INT64_T
+/* 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
+
+#undef UINT64_MAX
+#ifdef GL_UINT64_T
+# 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 */
+
+#undef INTMAX_MIN
+#undef INTMAX_MAX
+#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
+
+#undef UINTMAX_MAX
+#ifdef UINT64_MAX
+# define UINTMAX_MAX UINT64_MAX
+#else
+# define UINTMAX_MAX UINT32_MAX
+#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 ! (defined WCHAR_MIN && defined WCHAR_MAX)
+# 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@)
+
+#endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */
+
+/* 7.18.4. Macros for integer constants */
+
+#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS
+
+/* 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 */
+
+#undef 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
+
+#undef 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 /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */
+
+#endif /* _GL_STDINT_H */
+#endif /* !defined _GL_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */
diff --git a/grub-core/gnulib/stdio-write.c b/grub-core/gnulib/stdio-write.c
new file mode 100644
index 0000000..a6a0eb1
--- /dev/null
+++ b/grub-core/gnulib/stdio-write.c
@@ -0,0 +1,148 @@
+/* POSIX compatible FILE stream write function.
+ Copyright (C) 2008-2010 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 <stdio.h>
+
+/* Replace these functions only if module 'sigpipe' is requested. */
+#if GNULIB_SIGPIPE
+
+/* On native Windows platforms, SIGPIPE does not exist. When write() is
+ called on a pipe with no readers, WriteFile() fails with error
+ GetLastError() = ERROR_NO_DATA, and write() in consequence fails with
+ error EINVAL. This write() function is at the basis of the function
+ which flushes the buffer of a FILE stream. */
+
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+# include <errno.h>
+# include <signal.h>
+# include <io.h>
+
+# define WIN32_LEAN_AND_MEAN /* avoid including junk */
+# include <windows.h>
+
+# define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \
+ if (ferror (stream)) \
+ return (EXPRESSION); \
+ else \
+ { \
+ RETTYPE ret; \
+ SetLastError (0); \
+ ret = (EXPRESSION); \
+ if (FAILED && GetLastError () == ERROR_NO_DATA && ferror (stream)) \
+ { \
+ int fd = fileno (stream); \
+ if (fd >= 0 \
+ && GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_PIPE)\
+ { \
+ /* Try to raise signal SIGPIPE. */ \
+ raise (SIGPIPE); \
+ /* If it is currently blocked or ignored, change errno from \
+ EINVAL to EPIPE. */ \
+ errno = EPIPE; \
+ } \
+ } \
+ return ret; \
+ }
+
+# if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */
+int
+printf (const char *format, ...)
+{
+ int retval;
+ va_list args;
+
+ va_start (args, format);
+ retval = vfprintf (stdout, format, args);
+ va_end (args);
+
+ return retval;
+}
+# endif
+
+# if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */
+int
+fprintf (FILE *stream, const char *format, ...)
+{
+ int retval;
+ va_list args;
+
+ va_start (args, format);
+ retval = vfprintf (stream, format, args);
+ va_end (args);
+
+ return retval;
+}
+# endif
+
+# if !REPLACE_VPRINTF_POSIX /* avoid collision with vprintf.c */
+int
+vprintf (const char *format, va_list args)
+{
+ return vfprintf (stdout, format, args);
+}
+# endif
+
+# if !REPLACE_VFPRINTF_POSIX /* avoid collision with vfprintf.c */
+int
+vfprintf (FILE *stream, const char *format, va_list args)
+#undef vfprintf
+{
+ CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF)
+}
+# endif
+
+int
+putchar (int c)
+{
+ return fputc (c, stdout);
+}
+
+int
+fputc (int c, FILE *stream)
+#undef fputc
+{
+ CALL_WITH_SIGPIPE_EMULATION (int, fputc (c, stream), ret == EOF)
+}
+
+int
+fputs (const char *string, FILE *stream)
+#undef fputs
+{
+ CALL_WITH_SIGPIPE_EMULATION (int, fputs (string, stream), ret == EOF)
+}
+
+int
+puts (const char *string)
+#undef puts
+{
+ FILE *stream = stdout;
+ CALL_WITH_SIGPIPE_EMULATION (int, puts (string), ret == EOF)
+}
+
+size_t
+fwrite (const void *ptr, size_t s, size_t n, FILE *stream)
+#undef fwrite
+{
+ CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n)
+}
+
+# endif
+#endif
diff --git a/grub-core/gnulib/stdio.in.h b/grub-core/gnulib/stdio.in.h
new file mode 100644
index 0000000..80b9dbf
--- /dev/null
+++ b/grub-core/gnulib/stdio.in.h
@@ -0,0 +1,1071 @@
+/* A GNU-like <stdio.h>.
+
+ Copyright (C) 2004, 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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
+
+#if defined __need_FILE || defined __need___FILE
+/* Special invocation convention inside glibc header files. */
+
+#@INCLUDE_NEXT@ @NEXT_STDIO_H@
+
+#else
+/* Normal invocation convention. */
+
+#ifndef _GL_STDIO_H
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_STDIO_H@
+
+#ifndef _GL_STDIO_H
+#define _GL_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. */
+#include <sys/types.h>
+
+#ifndef __attribute__
+/* 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 __attribute__ 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 __attribute__(Spec) /* empty */
+# endif
+#endif
+
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+/* 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, ...)
+ __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, ...)
+ __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_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
+
+/* 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. */
+#undef gets
+_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
+
+#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 Win32 platforms is not POSIX compatible - "
+ "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_SIGPIPE@)
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define fprintf rpl_fprintf
+# endif
+# define GNULIB_overrides_fprintf 1
+_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)))
+ _GL_ARG_NONNULL ((1, 2)));
+_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_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_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_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 Win32 platforms is not POSIX compatible - "
+ "use gnulib module freopen for portability");
+#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_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);
+# if (@REPLACE_FSEEKO@ || !@HAVE_FSEEKO@) && !@GNULIB_FSEEK@
+ /* Provide an fseek function that is consistent with fseeko. */
+ /* In order to avoid that fseek gets defined as a macro here, the
+ developer can request the 'fseek' module. */
+# undef fseek
+# define fseek rpl_fseek
+static inline int _GL_ARG_NONNULL ((1))
+rpl_fseek (FILE *fp, long offset, int whence)
+{
+# if @REPLACE_FSEEKO@
+ return rpl_fseeko (fp, offset, whence);
+# else
+ return fseeko (fp, offset, whence);
+# endif
+}
+# endif
+#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_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);
+# if (@REPLACE_FTELLO@ || !@HAVE_FTELLO@) && !@GNULIB_FTELL@
+ /* Provide an ftell function that is consistent with ftello. */
+ /* In order to avoid that ftell gets defined as a macro here, the
+ developer can request the 'ftell' module. */
+# undef ftell
+# define ftell rpl_ftell
+static inline long _GL_ARG_NONNULL ((1))
+rpl_ftell (FILE *f)
+{
+# if @REPLACE_FTELLO@
+ return rpl_ftello (f);
+# else
+ return ftello (f);
+# endif
+}
+# endif
+#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_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));
+# endif
+_GL_CXXALIASWARN (fwrite);
+#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_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, ...)
+ __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, ...)
+ __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)
+ __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)
+ __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_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
+_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_SIGPIPE@)
+# if defined __GNUC__
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+/* Don't break __attribute__((format(printf,M,N))). */
+# define printf __printf__
+# endif
+_GL_FUNCDECL_RPL_1 (__printf__, int,
+ (const char *format, ...)
+ __asm__ (@ASM_SYMBOL_PREFIX@
+ _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf))
+ __attribute__ ((__format__ (__printf__, 1, 2)))
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...));
+# else
+_GL_FUNCDECL_RPL (printf, int,
+ (const char *format, ...)
+ __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_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_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_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_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, ...)
+ __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, ...)
+ __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, ...)
+ __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, ...)
+ __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, ...)
+ __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)
+ __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)
+ __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)
+ __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)
+ __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_SIGPIPE@)
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define vfprintf rpl_vfprintf
+# endif
+# define GNULIB_overrides_vfprintf 1
+_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args)
+ __attribute__ ((__format__ (__printf__, 2, 0)))
+ _GL_ARG_NONNULL ((1, 2)));
+_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_VPRINTF_POSIX@ || @GNULIB_VPRINTF@
+# if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \
+ || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@)
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define vprintf rpl_vprintf
+# endif
+# define GNULIB_overrides_vprintf 1
+_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args)
+ __attribute__ ((__format__ (__printf__, 1, 0)))
+ _GL_ARG_NONNULL ((1)));
+_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_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)
+ __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)
+ __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)
+ __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 /* _GL_STDIO_H */
+#endif /* _GL_STDIO_H */
+#endif
diff --git a/grub-core/gnulib/stdlib.in.h b/grub-core/gnulib/stdlib.in.h
new file mode 100644
index 0000000..f4309ed
--- /dev/null
+++ b/grub-core/gnulib/stdlib.in.h
@@ -0,0 +1,715 @@
+/* A GNU-like <stdlib.h>.
+
+ Copyright (C) 1995, 2001-2004, 2006-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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
+
+#if defined __need_malloc_and_calloc
+/* Special invocation convention inside glibc header files. */
+
+#@INCLUDE_NEXT@ @NEXT_STDLIB_H@
+
+#else
+/* Normal invocation convention. */
+
+#ifndef _GL_STDLIB_H
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_STDLIB_H@
+
+#ifndef _GL_STDLIB_H
+#define _GL_STDLIB_H
+
+/* NetBSD 5.0 mis-defines NULL. */
+#include <stddef.h>
+
+/* MirBSD 10 defines WEXITSTATUS in <sys/wait.h>, not in <stdlib.h>. */
+#ifndef 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
+
+/* OSF/1 5.1 declares 'struct random_data' in <random.h>, which is included
+ from <stdlib.h> if _REENTRANT is defined. Include it always. */
+#if @HAVE_RANDOM_H@
+# include <random.h>
+#endif
+
+#if !@HAVE_STRUCT_RANDOM_DATA@ || (@GNULIB_RANDOM_R@ && !@HAVE_RANDOM_R@) \
+ || defined GNULIB_POSIXCHECK
+# include <stdint.h>
+#endif
+
+#if !@HAVE_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. */
+};
+#endif
+
+#if (@GNULIB_MKSTEMP@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+/* On MacOS X 10.3, only <unistd.h> declares mkstemp. */
+/* On Cygwin 1.7.1, only <unistd.h> declares getsubopt. */
+/* But avoid namespace pollution on glibc systems and native Windows. */
+# include <unistd.h>
+#endif
+
+#ifndef __attribute__
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
+# define __attribute__(Spec) /* empty */
+# endif
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+
+/* 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, void, (int status) __attribute__ ((__noreturn__)));
+# 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 (ptsname, "grantpt is not portable - "
+ "use gnulib module grantpt for portability");
+# endif
+#endif
+
+#if @GNULIB_MALLOC_POSIX@
+# if @REPLACE_MALLOC@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# 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
+# 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
+
+#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_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_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_R@
+# 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));
+_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 !@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));
+_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 !@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));
+_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 !@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));
+_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)
+# 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
+# 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_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
+_GL_CXXALIASWARN (setenv);
+#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_UNSETENV@
+_GL_FUNCDECL_SYS (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (unsetenv, int, (const char *name));
+# endif
+_GL_CXXALIASWARN (unsetenv);
+#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
+
+
+#endif /* _GL_STDLIB_H */
+#endif /* _GL_STDLIB_H */
+#endif
diff --git a/grub-core/gnulib/strcasecmp.c b/grub-core/gnulib/strcasecmp.c
new file mode 100644
index 0000000..612c80f
--- /dev/null
+++ b/grub-core/gnulib/strcasecmp.c
@@ -0,0 +1,63 @@
+/* Case-insensitive string comparison function.
+ Copyright (C) 1998-1999, 2005-2007, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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/grub-core/gnulib/strchrnul.c b/grub-core/gnulib/strchrnul.c
new file mode 100644
index 0000000..f834d34
--- /dev/null
+++ b/grub-core/gnulib/strchrnul.c
@@ -0,0 +1,142 @@
+/* Searching in a string.
+ Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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/grub-core/gnulib/strchrnul.valgrind b/grub-core/gnulib/strchrnul.valgrind
new file mode 100644
index 0000000..b14fa13
--- /dev/null
+++ b/grub-core/gnulib/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/grub-core/gnulib/streq.h b/grub-core/gnulib/streq.h
new file mode 100644
index 0000000..aa65bb8
--- /dev/null
+++ b/grub-core/gnulib/streq.h
@@ -0,0 +1,176 @@
+/* Optimized string comparison.
+ Copyright (C) 2001-2002, 2007, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <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/grub-core/gnulib/strerror.c b/grub-core/gnulib/strerror.c
new file mode 100644
index 0000000..46153ab
--- /dev/null
+++ b/grub-core/gnulib/strerror.c
@@ -0,0 +1,350 @@
+/* strerror.c --- POSIX compatible system error routine
+
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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>
+
+#if REPLACE_STRERROR
+
+# include <errno.h>
+# include <stdio.h>
+
+# if GNULIB_defined_ESOCK /* native Windows platforms */
+# if HAVE_WINSOCK2_H
+# include <winsock2.h>
+# endif
+# endif
+
+# include "intprops.h"
+
+/* Use the system functions, not the gnulib overrides in this file. */
+# undef sprintf
+
+# undef strerror
+# if ! HAVE_DECL_STRERROR
+# define strerror(n) NULL
+# endif
+
+char *
+rpl_strerror (int n)
+{
+ char const *msg = NULL;
+ /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */
+ switch (n)
+ {
+# if GNULIB_defined_ETXTBSY
+ case ETXTBSY:
+ msg = "Text file busy";
+ break;
+# endif
+
+# if GNULIB_defined_ESOCK /* native Windows platforms */
+ /* EWOULDBLOCK is the same as EAGAIN. */
+ case EINPROGRESS:
+ msg = "Operation now in progress";
+ break;
+ case EALREADY:
+ msg = "Operation already in progress";
+ break;
+ case ENOTSOCK:
+ msg = "Socket operation on non-socket";
+ break;
+ case EDESTADDRREQ:
+ msg = "Destination address required";
+ break;
+ case EMSGSIZE:
+ msg = "Message too long";
+ break;
+ case EPROTOTYPE:
+ msg = "Protocol wrong type for socket";
+ break;
+ case ENOPROTOOPT:
+ msg = "Protocol not available";
+ break;
+ case EPROTONOSUPPORT:
+ msg = "Protocol not supported";
+ break;
+ case ESOCKTNOSUPPORT:
+ msg = "Socket type not supported";
+ break;
+ case EOPNOTSUPP:
+ msg = "Operation not supported";
+ break;
+ case EPFNOSUPPORT:
+ msg = "Protocol family not supported";
+ break;
+ case EAFNOSUPPORT:
+ msg = "Address family not supported by protocol";
+ break;
+ case EADDRINUSE:
+ msg = "Address already in use";
+ break;
+ case EADDRNOTAVAIL:
+ msg = "Cannot assign requested address";
+ break;
+ case ENETDOWN:
+ msg = "Network is down";
+ break;
+ case ENETUNREACH:
+ msg = "Network is unreachable";
+ break;
+ case ENETRESET:
+ msg = "Network dropped connection on reset";
+ break;
+ case ECONNABORTED:
+ msg = "Software caused connection abort";
+ break;
+ case ECONNRESET:
+ msg = "Connection reset by peer";
+ break;
+ case ENOBUFS:
+ msg = "No buffer space available";
+ break;
+ case EISCONN:
+ msg = "Transport endpoint is already connected";
+ break;
+ case ENOTCONN:
+ msg = "Transport endpoint is not connected";
+ break;
+ case ESHUTDOWN:
+ msg = "Cannot send after transport endpoint shutdown";
+ break;
+ case ETOOMANYREFS:
+ msg = "Too many references: cannot splice";
+ break;
+ case ETIMEDOUT:
+ msg = "Connection timed out";
+ break;
+ case ECONNREFUSED:
+ msg = "Connection refused";
+ break;
+ case ELOOP:
+ msg = "Too many levels of symbolic links";
+ break;
+ case EHOSTDOWN:
+ msg = "Host is down";
+ break;
+ case EHOSTUNREACH:
+ msg = "No route to host";
+ break;
+ case EPROCLIM:
+ msg = "Too many processes";
+ break;
+ case EUSERS:
+ msg = "Too many users";
+ break;
+ case EDQUOT:
+ msg = "Disk quota exceeded";
+ break;
+ case ESTALE:
+ msg = "Stale NFS file handle";
+ break;
+ case EREMOTE:
+ msg = "Object is remote";
+ break;
+# 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:
+ msg = "Overlapped operation aborted";
+ break;
+ case WSA_IO_INCOMPLETE:
+ msg = "Overlapped I/O event object not in signaled state";
+ break;
+ case WSA_IO_PENDING:
+ msg = "Overlapped operations will complete later";
+ break;
+ /* 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 is EINPROGRESS */
+ /* WSAEALREADY is EALREADY */
+ /* WSAENOTSOCK is ENOTSOCK */
+ /* WSAEDESTADDRREQ is EDESTADDRREQ */
+ /* WSAEMSGSIZE is EMSGSIZE */
+ /* WSAEPROTOTYPE is EPROTOTYPE */
+ /* WSAENOPROTOOPT is ENOPROTOOPT */
+ /* WSAEPROTONOSUPPORT is EPROTONOSUPPORT */
+ /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */
+ /* WSAEOPNOTSUPP is EOPNOTSUPP */
+ /* WSAEPFNOSUPPORT is EPFNOSUPPORT */
+ /* WSAEAFNOSUPPORT is EAFNOSUPPORT */
+ /* WSAEADDRINUSE is EADDRINUSE */
+ /* WSAEADDRNOTAVAIL is EADDRNOTAVAIL */
+ /* WSAENETDOWN is ENETDOWN */
+ /* WSAENETUNREACH is ENETUNREACH */
+ /* WSAENETRESET is ENETRESET */
+ /* WSAECONNABORTED is ECONNABORTED */
+ /* WSAECONNRESET is ECONNRESET */
+ /* WSAENOBUFS is ENOBUFS */
+ /* WSAEISCONN is EISCONN */
+ /* WSAENOTCONN is ENOTCONN */
+ /* WSAESHUTDOWN is ESHUTDOWN */
+ /* WSAETOOMANYREFS is ETOOMANYREFS */
+ /* WSAETIMEDOUT is ETIMEDOUT */
+ /* WSAECONNREFUSED is ECONNREFUSED */
+ /* WSAELOOP is ELOOP */
+ /* WSAENAMETOOLONG maps to ENAMETOOLONG */
+ /* WSAEHOSTDOWN is EHOSTDOWN */
+ /* WSAEHOSTUNREACH is EHOSTUNREACH */
+ /* WSAENOTEMPTY maps to ENOTEMPTY */
+ /* WSAEPROCLIM is EPROCLIM */
+ /* WSAEUSERS is EUSERS */
+ /* WSAEDQUOT is EDQUOT */
+ /* WSAESTALE is ESTALE */
+ /* WSAEREMOTE is EREMOTE */
+ case WSASYSNOTREADY:
+ msg = "Network subsystem is unavailable";
+ break;
+ case WSAVERNOTSUPPORTED:
+ msg = "Winsock.dll version out of range";
+ break;
+ case WSANOTINITIALISED:
+ msg = "Successful WSAStartup not yet performed";
+ break;
+ case WSAEDISCON:
+ msg = "Graceful shutdown in progress";
+ break;
+ case WSAENOMORE: case WSA_E_NO_MORE:
+ msg = "No more results";
+ break;
+ case WSAECANCELLED: case WSA_E_CANCELLED:
+ msg = "Call was canceled";
+ break;
+ case WSAEINVALIDPROCTABLE:
+ msg = "Procedure call table is invalid";
+ break;
+ case WSAEINVALIDPROVIDER:
+ msg = "Service provider is invalid";
+ break;
+ case WSAEPROVIDERFAILEDINIT:
+ msg = "Service provider failed to initialize";
+ break;
+ case WSASYSCALLFAILURE:
+ msg = "System call failure";
+ break;
+ case WSASERVICE_NOT_FOUND:
+ msg = "Service not found";
+ break;
+ case WSATYPE_NOT_FOUND:
+ msg = "Class type not found";
+ break;
+ case WSAEREFUSED:
+ msg = "Database query was refused";
+ break;
+ case WSAHOST_NOT_FOUND:
+ msg = "Host not found";
+ break;
+ case WSATRY_AGAIN:
+ msg = "Nonauthoritative host not found";
+ break;
+ case WSANO_RECOVERY:
+ msg = "Nonrecoverable error";
+ break;
+ case WSANO_DATA:
+ msg = "Valid name, no data record of requested type";
+ break;
+ /* WSA_QOS_* omitted */
+# endif
+# endif
+
+# if GNULIB_defined_ENOMSG
+ case ENOMSG:
+ msg = "No message of desired type";
+ break;
+# endif
+
+# if GNULIB_defined_EIDRM
+ case EIDRM:
+ msg = "Identifier removed";
+ break;
+# endif
+
+# if GNULIB_defined_ENOLINK
+ case ENOLINK:
+ msg = "Link has been severed";
+ break;
+# endif
+
+# if GNULIB_defined_EPROTO
+ case EPROTO:
+ msg = "Protocol error";
+ break;
+# endif
+
+# if GNULIB_defined_EMULTIHOP
+ case EMULTIHOP:
+ msg = "Multihop attempted";
+ break;
+# endif
+
+# if GNULIB_defined_EBADMSG
+ case EBADMSG:
+ msg = "Bad message";
+ break;
+# endif
+
+# if GNULIB_defined_EOVERFLOW
+ case EOVERFLOW:
+ msg = "Value too large for defined data type";
+ break;
+# endif
+
+# if GNULIB_defined_ENOTSUP
+ case ENOTSUP:
+ msg = "Not supported";
+ break;
+# endif
+
+# if GNULIB_defined_ESTALE
+ case ESTALE:
+ msg = "Stale NFS file handle";
+ break;
+# endif
+
+# if GNULIB_defined_ECANCELED
+ case ECANCELED:
+ msg = "Operation canceled";
+ break;
+# endif
+ }
+
+ if (msg)
+ return (char *) msg;
+
+ {
+ char *result = strerror (n);
+
+ if (result == NULL || result[0] == '\0')
+ {
+ static char const fmt[] = "Unknown error (%d)";
+ static char msg_buf[sizeof fmt + INT_STRLEN_BOUND (n)];
+ sprintf (msg_buf, fmt, n);
+ return msg_buf;
+ }
+
+ return result;
+ }
+}
+
+#endif
diff --git a/grub-core/gnulib/string.in.h b/grub-core/gnulib/string.in.h
new file mode 100644
index 0000000..49c711d
--- /dev/null
+++ b/grub-core/gnulib/string.in.h
@@ -0,0 +1,945 @@
+/* A GNU-like <string.h>.
+
+ Copyright (C) 1995-1996, 2001-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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_STRING_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_STRING_H@
+
+#ifndef _GL_STRING_H
+#define _GL_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
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+# define __attribute__(Spec) /* empty */
+# endif
+#endif
+/* 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 avoid namespace pollution on glibc systems. */
+#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) \
+ && ! 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. */
+
+
+/* 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 \
+ && (__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 \
+ && (__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 \
+ && (__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 ! @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));
+# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \
+ && (__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 \
+ && (__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 \
+ && (__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 \
+ && (__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
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define mbsrchr rpl_mbsrchr /* avoid collision with HP-UX 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
+
+#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 /* _GL_STRING_H */
+#endif /* _GL_STRING_H */
diff --git a/grub-core/gnulib/strings.in.h b/grub-core/gnulib/strings.in.h
new file mode 100644
index 0000000..c726a16
--- /dev/null
+++ b/grub-core/gnulib/strings.in.h
@@ -0,0 +1,93 @@
+/* A substitute <strings.h>.
+
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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_STRINGS_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_STRINGS_H@
+
+#ifndef _GL_STRINGS_H
+#define _GL_STRINGS_H
+
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+#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.
+ 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 /* _GL_STRING_H */
+#endif /* _GL_STRING_H */
diff --git a/grub-core/gnulib/stripslash.c b/grub-core/gnulib/stripslash.c
new file mode 100644
index 0000000..3a5996f
--- /dev/null
+++ b/grub-core/gnulib/stripslash.c
@@ -0,0 +1,45 @@
+/* stripslash.c -- remove redundant trailing slashes from a file name
+
+ Copyright (C) 1990, 2001, 2003-2006, 2009-2010 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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/grub-core/gnulib/strncasecmp.c b/grub-core/gnulib/strncasecmp.c
new file mode 100644
index 0000000..8c806a6
--- /dev/null
+++ b/grub-core/gnulib/strncasecmp.c
@@ -0,0 +1,63 @@
+/* strncasecmp.c -- case insensitive string comparator
+ Copyright (C) 1998-1999, 2005-2007, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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/grub-core/gnulib/strndup.c b/grub-core/gnulib/strndup.c
new file mode 100644
index 0000000..3de3dbc
--- /dev/null
+++ b/grub-core/gnulib/strndup.c
@@ -0,0 +1,37 @@
+/* A replacement function, for systems that lack strndup.
+
+ Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2005, 2006, 2007, 2009,
+ 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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/grub-core/gnulib/strnlen.c b/grub-core/gnulib/strnlen.c
new file mode 100644
index 0000000..f1ec356
--- /dev/null
+++ b/grub-core/gnulib/strnlen.c
@@ -0,0 +1,31 @@
+/* Find the length of STRING, but scan at most MAXLEN characters.
+ Copyright (C) 2005, 2006, 2007, 2009, 2010 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/grub-core/gnulib/strnlen1.c b/grub-core/gnulib/strnlen1.c
new file mode 100644
index 0000000..b8cd2bf
--- /dev/null
+++ b/grub-core/gnulib/strnlen1.c
@@ -0,0 +1,35 @@
+/* Find the length of STRING + 1, but scan at most MAXLEN bytes.
+ Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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/grub-core/gnulib/strnlen1.h b/grub-core/gnulib/strnlen1.h
new file mode 100644
index 0000000..dfaf62d
--- /dev/null
+++ b/grub-core/gnulib/strnlen1.h
@@ -0,0 +1,39 @@
+/* Find the length of STRING + 1, but scan at most MAXLEN bytes.
+ Copyright (C) 2005, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _STRNLEN1_H */
diff --git a/grub-core/gnulib/sys_wait.in.h b/grub-core/gnulib/sys_wait.in.h
new file mode 100644
index 0000000..009fa21
--- /dev/null
+++ b/grub-core/gnulib/sys_wait.in.h
@@ -0,0 +1,106 @@
+/* A POSIX-like <sys/wait.h>.
+ Copyright (C) 2001-2003, 2005-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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_SYS_WAIT_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+/* The include_next requires a split double-inclusion guard. */
+#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+# @INCLUDE_NEXT@ @NEXT_SYS_WAIT_H@
+#endif
+
+#ifndef _GL_SYS_WAIT_H
+#define _GL_SYS_WAIT_H
+
+#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+/* Unix API. */
+
+/* The following macros apply to an argument x, that is a status of a process,
+ as returned by waitpid().
+ On nearly all systems, including Linux/x86, WEXITSTATUS are bits 15..8 and
+ WTERMSIG are bits 7..0, while BeOS uses the opposite. Therefore programs
+ have to use the abstract macros. */
+
+/* For valid x, exactly one of WIFSIGNALED(x), WIFEXITED(x), WIFSTOPPED(x)
+ is true. */
+# ifndef WIFSIGNALED
+# define WIFSIGNALED(x) (WTERMSIG (x) != 0 && WTERMSIG(x) != 0x7f)
+# endif
+# ifndef WIFEXITED
+# define WIFEXITED(x) (WTERMSIG (x) == 0)
+# endif
+# ifndef WIFSTOPPED
+# define WIFSTOPPED(x) (WTERMSIG (x) == 0x7f)
+# endif
+
+/* The termination signal. Only to be accessed if WIFSIGNALED(x) is true. */
+# ifndef WTERMSIG
+# define WTERMSIG(x) ((x) & 0x7f)
+# endif
+
+/* The exit status. Only to be accessed if WIFEXITED(x) is true. */
+# ifndef WEXITSTATUS
+# define WEXITSTATUS(x) (((x) >> 8) & 0xff)
+# endif
+
+/* True if the process dumped core. Not standardized by POSIX. */
+# ifndef WCOREDUMP
+# define WCOREDUMP(x) ((x) & 0x80)
+# endif
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/* Declarations of functions. */
+
+# ifdef __cplusplus
+}
+# endif
+
+#else
+/* Native Windows API. */
+
+# include <process.h>
+
+# define waitpid(pid,statusp,options) _cwait (statusp, pid, WAIT_CHILD)
+
+/* The following macros apply to an argument x, that is a status of a process,
+ as returned by waitpid() or, equivalently, _cwait() or GetExitCodeProcess().
+ This value is simply an 'int', not composed of bit fields. */
+
+/* When an unhandled fatal signal terminates a process, the exit code is 3. */
+# define WIFSIGNALED(x) ((x) == 3)
+# define WIFEXITED(x) ((x) != 3)
+# define WIFSTOPPED(x) 0
+
+/* The signal that terminated a process is not known posthum. */
+# define WTERMSIG(x) SIGTERM
+
+# define WEXITSTATUS(x) (x)
+
+/* There are no core dumps. */
+# define WCOREDUMP(x) 0
+
+#endif
+
+#endif /* _GL_SYS_WAIT_H */
+#endif /* _GL_SYS_WAIT_H */
diff --git a/grub-core/gnulib/sysexits.in.h b/grub-core/gnulib/sysexits.in.h
new file mode 100644
index 0000000..45255df
--- /dev/null
+++ b/grub-core/gnulib/sysexits.in.h
@@ -0,0 +1,71 @@
+/* exit() exit codes for some BSD system programs.
+ Copyright (C) 2003, 2006-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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 _GL_SYSEXITS_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+#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 _GL_SYSEXITS_H
+#define _GL_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 /* _GL_SYSEXITS_H */
+#endif /* _GL_SYSEXITS_H */
diff --git a/grub-core/gnulib/unistd.in.h b/grub-core/gnulib/unistd.in.h
new file mode 100644
index 0000000..26a4cbd
--- /dev/null
+++ b/grub-core/gnulib/unistd.in.h
@@ -0,0 +1,1326 @@
+/* Substitute for and wrapper around <unistd.h>.
+ Copyright (C) 2003-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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
+
+/* 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 _GL_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 _GL_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H
+#define _GL_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 __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 __GLIBC__
+# include <fcntl.h>
+#endif
+
+/* mingw fails to declare _exit in <unistd.h>. */
+/* mingw, 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
+
+/* mingw declares getcwd in <io.h>, not in <unistd.h>. */
+#if ((@GNULIB_GETCWD@ || defined GNULIB_POSIXCHECK) \
+ && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
+# include <io.h>
+#endif
+
+#if (@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. */
+
+
+#if @GNULIB_GETHOSTNAME@
+/* Get all possible declarations of gethostname(). */
+# if @UNISTD_H_HAVE_WINSOCK2_H@
+# if !defined _GL_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 _GL_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
+
+
+/* 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_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:2001 specification
+ <http://www.opengroup.org/susv3xsh/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 @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);
+
+
+#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:2001 specification
+ <http://www.opengroup.org/susv3xsh/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:2001 specification
+ <http://www.opengroup.org/susv3xsh/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);
+
+# 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_FSYNC@
+/* Synchronize changes to a file.
+ Return 0 if successful, otherwise -1 and errno set.
+ See POSIX:2001 specification
+ <http://www.opengroup.org/susv3xsh/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:2001 specification
+ <http://www.opengroup.org/susv3xsh/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:2001 specification
+ <http://www.opengroup.org/susv3xsh/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 !@HAVE_GETDOMAINNAME@
+_GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len)
+ _GL_ARG_NONNULL ((1)));
+# endif
+/* Need to cast, because on MacOS X 10.5 systems, the second parameter is
+ int len. */
+_GL_CXXALIAS_SYS_CAST (getdomainname, int, (char *name, size_t len));
+_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 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 !@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));
+_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
+static inline int
+getpagesize ()
+{
+ return _gl_getpagesize ();
+}
+# 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_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:2001 specification
+ <http://www.opengroup.org/susv3xsh/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:2001 specification
+ <http://www.opengroup.org/susv3xsh/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:2001 specification
+ <http://www.opengroup.org/susv3xsh/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_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:2001
+ specification <http://www.opengroup.org/susv3xsh/pread.html>. */
+# if @REPLACE_PREAD@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# 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:2001 specification
+ <http://www.opengroup.org/susv3xsh/pwrite.html>. */
+# if @REPLACE_PWRITE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# 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_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:2001 specification
+ <http://www.opengroup.org/susv3xsh/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_SLEEP@
+/* Pause the execution of the current thread for N seconds.
+ Returns the number of seconds left to sleep.
+ See the POSIX:2001 specification
+ <http://www.opengroup.org/susv3xsh/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_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/sleep.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:2001 specification
+ <http://www.opengroup.org/susv3xsh/write.html>. */
+# if @REPLACE_WRITE@ && @GNULIB_UNISTD_H_SIGPIPE@
+# 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 /* _GL_UNISTD_H */
+#endif /* _GL_UNISTD_H */
diff --git a/grub-core/gnulib/vasnprintf.c b/grub-core/gnulib/vasnprintf.c
new file mode 100644
index 0000000..e618901
--- /dev/null
+++ b/grub-core/gnulib/vasnprintf.c
@@ -0,0 +1,5567 @@
+/* vsprintf with automatic memory allocation.
+ Copyright (C) 1999, 2002-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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"
+
+#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 __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
+typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1];
+
+typedef unsigned long long mp_twolimb_t;
+# define GMP_TWOLIMB_BITS 64
+typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1];
+
+/* 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 */
+ 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;
+ }
+ }
+ /* 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 * LDBL_MANT_BIT), and the
+ latter is an integer. */
+ /* Convert the mantissa (y * 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 * DBL_MANT_BIT), and the
+ latter is an integer. */
+ /* Convert the mantissa (y * 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() \
+ free (d.dir); \
+ if (a.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'. */
+ typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 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 });
+#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 (!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 _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 returns value conforms to
+ ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
+ 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 Win32 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 Win32 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
+
+ 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'. */
+ typedef int TCHAR_T_verify
+ [2 * (sizeof (TCHAR_T) == 1) - 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;
+ }
+#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/grub-core/gnulib/vasnprintf.h b/grub-core/gnulib/vasnprintf.h
new file mode 100644
index 0000000..a689bad
--- /dev/null
+++ b/grub-core/gnulib/vasnprintf.h
@@ -0,0 +1,80 @@
+/* vsprintf with automatic memory allocation.
+ Copyright (C) 2002-2004, 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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>
+
+#ifndef __attribute__
+/* 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 __attribute__ 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 __attribute__(Spec) /* empty */
+# endif
+#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, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
+ __attribute__ ((__format__ (__printf__, 3, 0)));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VASNPRINTF_H */
diff --git a/grub-core/gnulib/verify.h b/grub-core/gnulib/verify.h
new file mode 100644
index 0000000..4ad780c
--- /dev/null
+++ b/grub-core/gnulib/verify.h
@@ -0,0 +1,163 @@
+/* Compile-time assert-like macros.
+
+ Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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 VERIFY_H
+# define VERIFY_H 1
+
+/* 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.
+
+ Symbols ending in "__" are private to this header.
+
+ The code below uses several ideas.
+
+ * 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 verify_type__ { unsigned int verify_error_if_negative_size__: 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 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 verify_type__ {...})];
+ extern void dummy (int [sizeof (struct {...})]);
+ extern void dummy (int [sizeof (struct verify_type__ {...})]);
+ extern int (*dummy (void)) [sizeof (struct {...})];
+ extern int (*dummy (void)) [sizeof (struct 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 GCC does not warn about
+ the last declaration mentioned above. If a future version of GCC
+ introduces a warning for this, the problem could be worked around
+ by using code specialized to GCC, just as __COUNTER__ is already
+ being used if available.
+
+ #if 4 <= __GNUC__
+ # define verify(R) [another version to keep GCC happy]
+ #endif
+
+ * 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.
+ Return 1. */
+
+# ifdef __cplusplus
+template <int w>
+ struct verify_type__ { unsigned int verify_error_if_negative_size__: w; };
+# define verify_true(R) \
+ (!!sizeof (verify_type__<(R) ? 1 : -1>))
+# else
+# define verify_true(R) \
+ (!!sizeof \
+ (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; }))
+# endif
+
+/* Verify requirement R at compile-time, as a declaration without a
+ trailing ';'. */
+
+# define verify(R) \
+ extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)]
+
+#endif
diff --git a/grub-core/gnulib/vsnprintf.c b/grub-core/gnulib/vsnprintf.c
new file mode 100644
index 0000000..d447cc2
--- /dev/null
+++ b/grub-core/gnulib/vsnprintf.c
@@ -0,0 +1,71 @@
+/* Formatted output to strings.
+ Copyright (C) 2004, 2006-2010 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/grub-core/gnulib/wchar.in.h b/grub-core/gnulib/wchar.in.h
new file mode 100644
index 0000000..88d47db
--- /dev/null
+++ b/grub-core/gnulib/wchar.in.h
@@ -0,0 +1,428 @@
+/* A substitute for ISO C99 <wchar.h>, for platforms that have issues.
+
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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
+
+#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 _GL_WCHAR_H
+
+#define _GL_ALREADY_INCLUDING_WCHAR_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>.
+ But avoid namespace pollution on glibc systems. */
+#ifndef __GLIBC__
+# include <stddef.h>
+# 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 _GL_WCHAR_H
+#define _GL_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
+# 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@
+typedef int rpl_mbstate_t;
+# undef mbstate_t
+# define mbstate_t rpl_mbstate_t
+# define GNULIB_defined_mbstate_t 1
+#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
+
+
+#endif /* _GL_WCHAR_H */
+#endif /* _GL_WCHAR_H */
+#endif
diff --git a/grub-core/gnulib/wcrtomb.c b/grub-core/gnulib/wcrtomb.c
new file mode 100644
index 0000000..e7345f6
--- /dev/null
+++ b/grub-core/gnulib/wcrtomb.c
@@ -0,0 +1,53 @@
+/* Convert wide character to multibyte character.
+ Copyright (C) 2008, 2009, 2010 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/grub-core/gnulib/wctype.in.h b/grub-core/gnulib/wctype.in.h
new file mode 100644
index 0000000..12c8975
--- /dev/null
+++ b/grub-core/gnulib/wctype.in.h
@@ -0,0 +1,392 @@
+/* A substitute for ISO C99 <wctype.h>, for platforms that lack it.
+
+ Copyright (C) 2006-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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 _GL_WCTYPE_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+#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 _GL_WCTYPE_H
+#define _GL_WCTYPE_H
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+/* 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
+# ifndef WEOF
+# define WEOF ((wint_t) -1)
+# endif
+#endif
+
+
+/* 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
+# 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_ISWCNTRL@
+rpl_towlower
+# else
+towlower
+# endif
+ (wint_t wc)
+{
+ return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc);
+}
+
+static inline wint_t
+# if @REPLACE_ISWCNTRL@
+rpl_towupper
+# else
+towupper
+# endif
+ (wint_t wc)
+{
+ return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc);
+}
+
+#elif ! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@
+/* Only the iswblank function is missing. */
+
+# if @REPLACE_ISWBLANK@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define iswblank rpl_iswblank
+# endif
+# endif
+
+static inline int
+# if @REPLACE_ISWBLANK@
+rpl_iswblank
+# else
+iswblank
+# endif
+ (wint_t wc)
+{
+ return wc == ' ' || wc == '\t';
+}
+
+#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__ */
+
+#if @REPLACE_ISWCNTRL@
+_GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswblank, 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));
+# if @REPLACE_ISWBLANK@
+_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));
+# else
+_GL_CXXALIAS_SYS (iswblank, int, (wint_t wc));
+# endif
+_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 (iswblank);
+_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 @REPLACE_ISWCNTRL@ || 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);
+
+
+#endif /* _GL_WCTYPE_H */
+#endif /* _GL_WCTYPE_H */
diff --git a/grub-core/gnulib/xsize.h b/grub-core/gnulib/xsize.h
new file mode 100644
index 0000000..fbd6329
--- /dev/null
+++ b/grub-core/gnulib/xsize.h
@@ -0,0 +1,108 @@
+/* xsize.h -- Checked size_t computations.
+
+ Copyright (C) 2003, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute 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 */