summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2016-01-02 21:37:22 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-02-21 09:32:01 +0000
commit9c3d461c4d54d684b38ec4c038a1c3c2fb9923f0 (patch)
treed4974d75c8003d3b5bd2ee5093662b00ed682975
parent6eb64cdd5296c42a46f3485bca403814eec55b2c (diff)
downloadopenembedded-core-contrib-9c3d461c4d54d684b38ec4c038a1c3c2fb9923f0.tar.gz
openembedded-core-contrib-9c3d461c4d54d684b38ec4c038a1c3c2fb9923f0.tar.bz2
openembedded-core-contrib-9c3d461c4d54d684b38ec4c038a1c3c2fb9923f0.zip
glibc: Upgrade to 2.23
Drop kconfig and options-group support Forward port cross-localedef support Assume ssp support in libc when building gcc-initial Signed-off-by: Khem Raj <raj.khem@gmail.com>
-rw-r--r--meta/conf/distro/include/tcmode-default.inc4
-rw-r--r--meta/recipes-core/glibc/cross-localedef-native_2.23.bb (renamed from meta/recipes-core/glibc/cross-localedef-native_2.22.bb)23
-rw-r--r--meta/recipes-core/glibc/glibc-initial.inc1
-rw-r--r--meta/recipes-core/glibc/glibc-initial_2.23.bb (renamed from meta/recipes-core/glibc/glibc-initial_2.22.bb)2
-rw-r--r--meta/recipes-core/glibc/glibc-locale_2.23.bb (renamed from meta/recipes-core/glibc/glibc-locale_2.22.bb)0
-rw-r--r--meta/recipes-core/glibc/glibc-mtrace_2.23.bb (renamed from meta/recipes-core/glibc/glibc-mtrace_2.22.bb)0
-rw-r--r--meta/recipes-core/glibc/glibc-options.inc162
-rw-r--r--meta/recipes-core/glibc/glibc-scripts_2.23.bb (renamed from meta/recipes-core/glibc/glibc-scripts_2.22.bb)0
-rw-r--r--meta/recipes-core/glibc/glibc.inc17
-rw-r--r--meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch23
-rw-r--r--meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch10
-rw-r--r--meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch16
-rw-r--r--meta/recipes-core/glibc/glibc/0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch34
-rw-r--r--meta/recipes-core/glibc/glibc/0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch32
-rw-r--r--meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch8
-rw-r--r--meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch14
-rw-r--r--meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch8
-rw-r--r--meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch32
-rw-r--r--meta/recipes-core/glibc/glibc/0015-yes-within-the-path-sets-wrong-config-variables.patch (renamed from meta/recipes-core/glibc/glibc/0016-yes-within-the-path-sets-wrong-config-variables.patch)20
-rw-r--r--meta/recipes-core/glibc/glibc/0016-timezone-re-written-tzselect-as-posix-sh.patch (renamed from meta/recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch)10
-rw-r--r--meta/recipes-core/glibc/glibc/0017-Remove-bash-dependency-for-nscd-init-script.patch (renamed from meta/recipes-core/glibc/glibc/nscd-no-bash.patch)16
-rw-r--r--meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch1436
-rw-r--r--meta/recipes-core/glibc/glibc/0019-eglibc-Help-bootstrap-cross-toolchain.patch (renamed from meta/recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch)8
-rw-r--r--meta/recipes-core/glibc/glibc/0020-eglibc-cherry-picked-from.patch (renamed from meta/recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch)36
-rw-r--r--meta/recipes-core/glibc/glibc/0021-eglibc-Clear-cache-lines-on-ppc8xx.patch (renamed from meta/recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch)28
-rw-r--r--meta/recipes-core/glibc/glibc/0022-eglibc-Resolve-__fpscr_values-on-SH4.patch (renamed from meta/recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch)6
-rw-r--r--meta/recipes-core/glibc/glibc/0023-eglibc-Install-PIC-archives.patch (renamed from meta/recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch)20
-rw-r--r--meta/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch16842
-rw-r--r--meta/recipes-core/glibc/glibc/0025-eglibc-Forward-port-cross-locale-generation-support.patch566
-rw-r--r--meta/recipes-core/glibc/glibc/0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch48
-rw-r--r--meta/recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch556
-rw-r--r--meta/recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch145
-rw-r--r--meta/recipes-core/glibc/glibc/0028-Clear-ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA-for-prel.patch84
-rw-r--r--meta/recipes-core/glibc/glibc/0029-fix-getmntent-empty-lines.patch40
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2015-7547.patch642
-rw-r--r--meta/recipes-core/glibc/glibc/strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch323
-rw-r--r--meta/recipes-core/glibc/glibc/use_64bit_atomics.patch24
-rw-r--r--meta/recipes-core/glibc/glibc_2.23.bb (renamed from meta/recipes-core/glibc/glibc_2.22.bb)40
-rw-r--r--meta/recipes-devtools/gcc/gcc-5.3.inc2
47 files changed, 816 insertions, 20510 deletions
diff --git a/meta/conf/distro/include/tcmode-default.inc b/meta/conf/distro/include/tcmode-default.inc
index 5622f3ec16..c412420eaf 100644
--- a/meta/conf/distro/include/tcmode-default.inc
+++ b/meta/conf/distro/include/tcmode-default.inc
@@ -22,11 +22,11 @@ PREFERRED_PROVIDER_virtual/${TARGET_PREFIX}libc-initial = "${TCLIBC}-initial"
PREFERRED_PROVIDER_virtual/nativesdk-${SDK_PREFIX}libc-initial ?= "nativesdk-glibc-initial"
PREFERRED_PROVIDER_virtual/gettext ??= "gettext"
-GCCVERSION ?= "5.%"
+GCCVERSION ?= "5.3%"
SDKGCCVERSION ?= "${GCCVERSION}"
BINUVERSION ?= "2.26%"
GDBVERSION ?= "7.10%"
-GLIBCVERSION ?= "2.22"
+GLIBCVERSION ?= "2.23"
UCLIBCVERSION ?= "1.0%"
LINUXLIBCVERSION ?= "4.4"
diff --git a/meta/recipes-core/glibc/cross-localedef-native_2.22.bb b/meta/recipes-core/glibc/cross-localedef-native_2.23.bb
index efcdf4dc63..fa930fd480 100644
--- a/meta/recipes-core/glibc/cross-localedef-native_2.22.bb
+++ b/meta/recipes-core/glibc/cross-localedef-native_2.23.bb
@@ -24,22 +24,19 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
${EGLIBCPATCHES} \
"
EGLIBCPATCHES = "\
- file://0017-timezone-re-written-tzselect-as-posix-sh.patch \
+ file://0016-timezone-re-written-tzselect-as-posix-sh.patch \
+ file://0017-Remove-bash-dependency-for-nscd-init-script.patch \
file://0018-eglibc-Cross-building-and-testing-instructions.patch \
- file://0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch \
- file://0020-eglibc-Help-bootstrap-cross-toolchain.patch \
- file://0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch \
- file://0022-eglibc-Clear-cache-lines-on-ppc8xx.patch \
- file://0023-eglibc-Resolve-__fpscr_values-on-SH4.patch \
- file://0024-eglibc-Forward-port-eglibc-options-groups-support.patch \
- file://0025-eglibc-Install-PIC-archives.patch \
- file://0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch \
- file://0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch \
- file://strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch \
+ file://0019-eglibc-Help-bootstrap-cross-toolchain.patch \
+ file://0020-eglibc-cherry-picked-from.patch \
+ file://0021-eglibc-Clear-cache-lines-on-ppc8xx.patch \
+ file://0022-eglibc-Resolve-__fpscr_values-on-SH4.patch \
+ file://0023-eglibc-Install-PIC-archives.patch \
+ file://0025-eglibc-Forward-port-cross-locale-generation-support.patch \
"
-SRCREV_glibc ?= "a34d1c6afc86521d6ad17662a3b5362d8481514c"
-SRCREV_localedef ?= "c833367348d39dad7ba018990bfdaffaec8e9ed3"
+SRCREV_glibc ?= "e742928c1592b43db6809db4f39e67be151cdd27"
+SRCREV_localedef ?= "5a81ff9f06a7a808d4c3d37bbf34077a4c5902ed"
# Makes for a rather long rev (22 characters), but...
#
diff --git a/meta/recipes-core/glibc/glibc-initial.inc b/meta/recipes-core/glibc/glibc-initial.inc
index 7214f71404..5975fd26c7 100644
--- a/meta/recipes-core/glibc/glibc-initial.inc
+++ b/meta/recipes-core/glibc/glibc-initial.inc
@@ -16,7 +16,6 @@ do_configure () {
--prefix=/usr \
--without-cvs --disable-sanity-checks \
--with-headers=${STAGING_DIR_TARGET}${includedir} \
- --with-kconfig=${STAGING_BINDIR_NATIVE} \
--enable-hacker-mode --enable-addons
}
diff --git a/meta/recipes-core/glibc/glibc-initial_2.22.bb b/meta/recipes-core/glibc/glibc-initial_2.23.bb
index 8ab01dc79d..e86770e12d 100644
--- a/meta/recipes-core/glibc/glibc-initial_2.22.bb
+++ b/meta/recipes-core/glibc/glibc-initial_2.23.bb
@@ -1,8 +1,6 @@
require glibc_${PV}.bb
require glibc-initial.inc
-DEPENDS += "kconfig-frontends-native"
-
# main glibc recipes muck with TARGET_CPPFLAGS to point into
# final target sysroot but we
# are not there when building glibc-initial
diff --git a/meta/recipes-core/glibc/glibc-locale_2.22.bb b/meta/recipes-core/glibc/glibc-locale_2.23.bb
index f7702e0358..f7702e0358 100644
--- a/meta/recipes-core/glibc/glibc-locale_2.22.bb
+++ b/meta/recipes-core/glibc/glibc-locale_2.23.bb
diff --git a/meta/recipes-core/glibc/glibc-mtrace_2.22.bb b/meta/recipes-core/glibc/glibc-mtrace_2.23.bb
index 0b69bad46a..0b69bad46a 100644
--- a/meta/recipes-core/glibc/glibc-mtrace_2.22.bb
+++ b/meta/recipes-core/glibc/glibc-mtrace_2.23.bb
diff --git a/meta/recipes-core/glibc/glibc-options.inc b/meta/recipes-core/glibc/glibc-options.inc
deleted file mode 100644
index 9fd27f32f9..0000000000
--- a/meta/recipes-core/glibc/glibc-options.inc
+++ /dev/null
@@ -1,162 +0,0 @@
-def glibc_cfg(feature, tokens, cnf):
- if type(tokens) == type(""):
- tokens = [tokens]
- if feature:
- cnf.extend([token + '=y' for token in tokens])
- else:
- for token in tokens:
- cnf.extend([token + '=n'])
- if token == 'OPTION_EGLIBC_NSSWITCH':
- cnf.extend(["OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG=\"${S}/nss/nsswitch.conf\""])
- cnf.extend(["OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS=\"${S}/nss/fixed-nsswitch.functions\""])
-
-# Map distro features to glibc options settings
-def features_to_glibc_settings(d):
- cnf = ([])
-
- ipv4 = bb.utils.contains('DISTRO_FEATURES', 'ipv4', True, False, d)
- ipv6 = bb.utils.contains('DISTRO_FEATURES', 'ipv6', True, False, d)
- libc_backtrace = bb.utils.contains('DISTRO_FEATURES', 'libc-backtrace', True, False, d)
- libc_big_macros = bb.utils.contains('DISTRO_FEATURES', 'libc-big-macros', True, False, d)
- libc_bsd = bb.utils.contains('DISTRO_FEATURES', 'libc-bsd', True, False, d)
- libc_cxx_tests = bb.utils.contains('DISTRO_FEATURES', 'libc-cxx-tests', True, False, d)
- libc_catgets = bb.utils.contains('DISTRO_FEATURES', 'libc-catgets', True, False, d)
- libc_charsets = bb.utils.contains('DISTRO_FEATURES', 'libc-charsets', True, False, d)
- libc_crypt = bb.utils.contains('DISTRO_FEATURES', 'libc-crypt', True, False, d)
- libc_crypt_ufc = bb.utils.contains('DISTRO_FEATURES', 'libc-crypt-ufc', True, False, d)
- libc_db_aliases = bb.utils.contains('DISTRO_FEATURES', 'libc-db-aliases', True, False, d)
- libc_envz = bb.utils.contains('DISTRO_FEATURES', 'libc-envz', True, False, d)
- libc_fcvt = bb.utils.contains('DISTRO_FEATURES', 'libc-fcvt', True, False, d)
- libc_fmtmsg = bb.utils.contains('DISTRO_FEATURES', 'libc-fmtmsg', True, False, d)
- libc_fstab = bb.utils.contains('DISTRO_FEATURES', 'libc-fstab', True, False, d)
- libc_ftraverse = bb.utils.contains('DISTRO_FEATURES', 'libc-ftraverse', True, False, d)
- libc_getlogin = bb.utils.contains('DISTRO_FEATURES', 'libc-getlogin', True, False, d)
- libc_idn = bb.utils.contains('DISTRO_FEATURES', 'libc-idn', True, False, d)
- libc_inet_anl = bb.utils.contains('DISTRO_FEATURES', 'libc-inet-anl', True, False, d)
- libc_libm = bb.utils.contains('DISTRO_FEATURES', 'libc-libm', True, False, d)
- libc_locales = bb.utils.contains('DISTRO_FEATURES', 'libc-locales', True, False, d)
- libc_locale_code = bb.utils.contains('DISTRO_FEATURES', 'libc-locale-code', True, False, d)
- libc_memusage = bb.utils.contains('DISTRO_FEATURES', 'libc-memusage', True, False, d)
- libc_nis = bb.utils.contains('DISTRO_FEATURES', 'libc-nis', True, False, d)
- libc_nsswitch = bb.utils.contains('DISTRO_FEATURES', 'libc-nsswitch', True, False, d)
- libc_rcmd = bb.utils.contains('DISTRO_FEATURES', 'libc-rcmd', True, False, d)
- libc_rtld_debug = bb.utils.contains('DISTRO_FEATURES', 'libc-rtld-debug', True, False, d)
- libc_spawn = bb.utils.contains('DISTRO_FEATURES', 'libc-spawn', True, False, d)
- libc_streams = bb.utils.contains('DISTRO_FEATURES', 'libc-streams', True, False, d)
- libc_sunrpc = bb.utils.contains('DISTRO_FEATURES', 'libc-sunrpc', True, False, d)
- libc_utmp = bb.utils.contains('DISTRO_FEATURES', 'libc-utmp', True, False, d)
- libc_utmpx = bb.utils.contains('DISTRO_FEATURES', 'libc-utmpx', True, False, d)
- libc_wordexp = bb.utils.contains('DISTRO_FEATURES', 'libc-wordexp', True, False, d)
- libc_posix_clang_wchar = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-clang-wchar', True, False, d)
- libc_posix_regexp = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-regexp', True, False, d)
- libc_posix_regexp_glibc = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-regexp-glibc', True, False, d)
- libc_posix_wchar_io = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-wchar-io', True, False, d)
-
- # arrange the dependencies among glibc configuable options according to file option-groups.def from glibc source code
- new_dep = True
- while new_dep:
- new_dep = False
-
- if ipv6 and not ipv4:
- new_dep = True
- ipv4 = True
-
- if ipv4 and not libc_nsswitch:
- new_dep = True
- libc_nsswitch = True
-
- if libc_cxx_tests:
- if not libc_posix_wchar_io:
- new_dep = True
- libc_posix_wchar_io = True
- if not libc_libm:
- new_dep = True
- libc_libm = True
-
- if libc_catgets and not libc_locale_code:
- new_dep = True
- libc_locale_code = True
-
- if libc_crypt_ufc and not libc_crypt:
- new_dep = True
- libc_crypt = True
-
- if libc_getlogin and not libc_utmp:
- new_dep = True
- libc_utmp = True
-
- if libc_inet_anl and not ipv4:
- new_dep = True
- ipv4 = True
-
- if libc_locale_code and not libc_posix_clang_wchar:
- new_dep = True
- libc_posix_clang_wchar = True
-
- if libc_nis:
- if not ipv4:
- new_dep = True
- ipv4 = True
- if not libc_sunrpc:
- new_dep = True
- libc_sunrpc = True
-
- if libc_rcmd and not ipv4:
- new_dep = True
- ipv4 = True
-
- if libc_sunrpc and not ipv4:
- new_dep = True
- ipv4 = True
-
- if libc_utmpx and not libc_utmp:
- new_dep = True
- libc_utmp = True
-
- if libc_posix_regexp_glibc and not libc_posix_regexp:
- new_dep = True
- libc_posix_regexp = True
-
- if libc_posix_wchar_io and not libc_posix_clang_wchar:
- new_dep = True
- libc_posix_clang_wchar = True
-
- glibc_cfg(ipv6, 'OPTION_EGLIBC_ADVANCED_INET6', cnf)
- glibc_cfg(libc_backtrace, 'OPTION_EGLIBC_BACKTRACE', cnf)
- glibc_cfg(libc_big_macros, 'OPTION_EGLIBC_BIG_MACROS', cnf)
- glibc_cfg(libc_bsd, 'OPTION_EGLIBC_BSD', cnf)
- glibc_cfg(libc_cxx_tests, 'OPTION_EGLIBC_CXX_TESTS', cnf)
- glibc_cfg(libc_catgets, 'OPTION_EGLIBC_CATGETS', cnf)
- glibc_cfg(libc_charsets, 'OPTION_EGLIBC_CHARSETS', cnf)
- glibc_cfg(libc_crypt, 'OPTION_EGLIBC_CRYPT', cnf)
- glibc_cfg(libc_crypt_ufc, 'OPTION_EGLIBC_CRYPT_UFC', cnf)
- glibc_cfg(libc_db_aliases, 'OPTION_EGLIBC_DB_ALIASES', cnf)
- glibc_cfg(libc_envz, 'OPTION_EGLIBC_ENVZ', cnf)
- glibc_cfg(libc_fcvt, 'OPTION_EGLIBC_FCVT', cnf)
- glibc_cfg(libc_fmtmsg, 'OPTION_EGLIBC_FMTMSG', cnf)
- glibc_cfg(libc_fstab, 'OPTION_EGLIBC_FSTAB', cnf)
- glibc_cfg(libc_ftraverse, 'OPTION_EGLIBC_FTRAVERSE', cnf)
- glibc_cfg(libc_getlogin, 'OPTION_EGLIBC_GETLOGIN', cnf)
- glibc_cfg(libc_idn, 'OPTION_EGLIBC_IDN', cnf)
- glibc_cfg(ipv4, 'OPTION_EGLIBC_INET', cnf)
- glibc_cfg(libc_inet_anl, 'OPTION_EGLIBC_INET_ANL', cnf)
- glibc_cfg(libc_libm, 'OPTION_EGLIBC_LIBM', cnf)
- glibc_cfg(libc_locales, 'OPTION_EGLIBC_LOCALES', cnf)
- glibc_cfg(libc_locale_code, 'OPTION_EGLIBC_LOCALE_CODE', cnf)
- glibc_cfg(libc_memusage, 'OPTION_EGLIBC_MEMUSAGE', cnf)
- glibc_cfg(libc_nis, 'OPTION_EGLIBC_NIS', cnf)
- glibc_cfg(libc_nsswitch, 'OPTION_EGLIBC_NSSWITCH', cnf)
- glibc_cfg(libc_rcmd, 'OPTION_EGLIBC_RCMD', cnf)
- glibc_cfg(libc_rtld_debug, 'OPTION_EGLIBC_RTLD_DEBUG', cnf)
- glibc_cfg(libc_spawn, 'OPTION_EGLIBC_SPAWN', cnf)
- glibc_cfg(libc_streams, 'OPTION_EGLIBC_STREAMS', cnf)
- glibc_cfg(libc_sunrpc, 'OPTION_EGLIBC_SUNRPC', cnf)
- glibc_cfg(libc_utmp, 'OPTION_EGLIBC_UTMP', cnf)
- glibc_cfg(libc_utmpx, 'OPTION_EGLIBC_UTMPX', cnf)
- glibc_cfg(libc_wordexp, 'OPTION_EGLIBC_WORDEXP', cnf)
- glibc_cfg(libc_posix_clang_wchar, 'OPTION_POSIX_C_LANG_WIDE_CHAR', cnf)
- glibc_cfg(libc_posix_regexp, 'OPTION_POSIX_REGEXP', cnf)
- glibc_cfg(libc_posix_regexp_glibc, 'OPTION_POSIX_REGEXP_GLIBC', cnf)
- glibc_cfg(libc_posix_wchar_io, 'OPTION_POSIX_WIDE_CHAR_DEVICE_IO', cnf)
-
- return "\n".join(cnf)
diff --git a/meta/recipes-core/glibc/glibc-scripts_2.22.bb b/meta/recipes-core/glibc/glibc-scripts_2.23.bb
index 5a89bd8022..5a89bd8022 100644
--- a/meta/recipes-core/glibc/glibc-scripts_2.22.bb
+++ b/meta/recipes-core/glibc/glibc-scripts_2.23.bb
diff --git a/meta/recipes-core/glibc/glibc.inc b/meta/recipes-core/glibc/glibc.inc
index 7c4551a4aa..5711209c71 100644
--- a/meta/recipes-core/glibc/glibc.inc
+++ b/meta/recipes-core/glibc/glibc.inc
@@ -44,12 +44,6 @@ DEPENDS = "virtual/${TARGET_PREFIX}gcc-initial libgcc-initial linux-libc-headers
PROVIDES = "virtual/libc virtual/${TARGET_PREFIX}libc-for-gcc"
PROVIDES += "virtual/libintl virtual/libiconv"
inherit autotools texinfo distro_features_check systemd
-require glibc-options.inc
-
-# The main purpose of setting this variable is to prevent users from accidently
-# overriding DISTRO_FEATRUES, causing obscure build failures because of lack
-# of libc functions.
-REQUIRED_DISTRO_FEATURES = "${DISTRO_FEATURES_LIBC}"
LEAD_SONAME = "libc.so"
@@ -58,6 +52,7 @@ CACHED_CONFIGUREVARS += " \
libc_cv_slibdir=${base_libdir} \
libc_cv_rootsbindir=${base_sbindir} \
libc_cv_localedir=${localedir} \
+ libc_cv_ssp_strong=no \
libc_cv_ssp=no \
"
@@ -82,18 +77,8 @@ PARALLEL_MAKE = ""
# ensure make uses /bin/bash
EXTRA_OEMAKE += "SHELL=/bin/bash"
-OE_FEATURES = "${@features_to_glibc_settings(d)}"
do_configure_prepend() {
sed -e "s#@BASH@#/bin/sh#" -i ${S}/elf/ldd.bash.in
- echo '${OE_FEATURES}' > ${B}/option-groups.config
-}
-
-do_configure_append() {
- yes '' | oe_runmake config
-
- # Remove quotation marks from OPTION_EGLIBC_NSSWITCH_FIXED_*. This will
- # avoid install error.
- sed -i 's/^OPTION_EGLIBC_NSSWITCH_FIXED_\(.*\)="\(.*\)"$/OPTION_EGLIBC_NSSWITCH_FIXED_\1=\2/' option-groups.config
}
GLIBC_ADDONS ?= "nptl,libidn"
diff --git a/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch b/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch
index 3d66348133..97c280059f 100644
--- a/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch
+++ b/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch
@@ -1,7 +1,7 @@
-From 0876fea1b5b26da84f298714a2e23ba696607dba Mon Sep 17 00:00:00 2001
+From 66d04e2cd8badb0984050e4e9f2732f47151fbbf Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 01:48:24 +0000
-Subject: [PATCH 01/27] nativesdk-glibc: Look for host system ld.so.cache as
+Subject: [PATCH 01/24] nativesdk-glibc: Look for host system ld.so.cache as
well
Upstream-Status: Inappropriate [embedded specific]
@@ -27,18 +27,17 @@ RP 14/10/2010
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
- elf/dl-load.c | 17 ++++++++---------
- 1 file changed, 8 insertions(+), 9 deletions(-)
+ elf/dl-load.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/elf/dl-load.c b/elf/dl-load.c
-index 0c052e4..f45085a 100644
+index 6fb615e..ee3d1e6 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
-@@ -2040,7 +2040,14 @@ _dl_map_object (struct link_map *loader, const char *name,
- fd = open_path (name, namelen, mode,
- &loader->l_runpath_dirs, &realname, &fb, loader,
- LA_SER_RUNPATH, &found_other_class);
--
+@@ -2094,6 +2094,14 @@ _dl_map_object (struct link_map *loader, const char *name,
+ }
+ }
+
+ /* try the default path. */
+ if (fd == -1
+ && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
@@ -50,7 +49,7 @@ index 0c052e4..f45085a 100644
#ifdef USE_LDCONFIG
if (fd == -1
&& (__glibc_likely ((mode & __RTLD_SECURE) == 0)
-@@ -2099,14 +2106,6 @@ _dl_map_object (struct link_map *loader, const char *name,
+@@ -2152,14 +2160,6 @@ _dl_map_object (struct link_map *loader, const char *name,
}
#endif
@@ -66,5 +65,5 @@ index 0c052e4..f45085a 100644
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
_dl_debug_printf ("\n");
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch b/meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch
index b568fc6bdc..473b89449d 100644
--- a/meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch
+++ b/meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch
@@ -1,7 +1,7 @@
-From 086b65d9aacffc47fcd8df68818a476a5ae76fa1 Mon Sep 17 00:00:00 2001
+From 179dc5f1e13c3ff96d5f21a2a78c089cf120ceb8 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 01:50:00 +0000
-Subject: [PATCH 02/27] nativesdk-glibc: Fix buffer overrun with a relocated
+Subject: [PATCH 02/24] nativesdk-glibc: Fix buffer overrun with a relocated
SDK
When ld-linux-*.so.2 is relocated to a path that is longer than the
@@ -22,10 +22,10 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
1 file changed, 12 insertions(+)
diff --git a/elf/dl-load.c b/elf/dl-load.c
-index f45085a..f1eb5ed 100644
+index ee3d1e6..c4a42e9 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
-@@ -1765,7 +1765,19 @@ open_path (const char *name, size_t namelen, int mode,
+@@ -1793,7 +1793,19 @@ open_path (const char *name, size_t namelen, int mode,
given on the command line when rtld is run directly. */
return -1;
@@ -46,5 +46,5 @@ index f45085a..f1eb5ed 100644
{
struct r_search_path_elem *this_dir = *dirs;
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch b/meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch
index a681a64e85..dde94b450c 100644
--- a/meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch
+++ b/meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch
@@ -1,7 +1,7 @@
-From fd595a5ec885bcb4c14417daa21c2e61c5b72e42 Mon Sep 17 00:00:00 2001
+From e76048898ae9aa49dc70d6f9b1bbc22082e61fe3 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 01:51:38 +0000
-Subject: [PATCH 03/27] nativesdk-glibc: Raise the size of arrays containing dl
+Subject: [PATCH 03/24] nativesdk-glibc: Raise the size of arrays containing dl
paths
This patch puts the dynamic loader path in the binaries, SYSTEM_DIRS strings
@@ -40,10 +40,10 @@ index dec49bc..862f1d8 100644
internal_function
_dl_cache_libcmp (const char *p1, const char *p2)
diff --git a/elf/dl-load.c b/elf/dl-load.c
-index f1eb5ed..f664f50 100644
+index c4a42e9..acf6c03 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
-@@ -104,8 +104,8 @@ static size_t max_capstrlen attribute_relro;
+@@ -106,8 +106,8 @@ static size_t max_capstrlen attribute_relro;
/* Get the generated information about the trusted directories. */
#include "trusted-dirs.h"
@@ -80,7 +80,7 @@ index f54ec22..0e78a83 100644
a platform. */
static int
diff --git a/elf/rtld.c b/elf/rtld.c
-index 69873c2..6d3add7 100644
+index 52160df..80f0582 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -99,6 +99,7 @@ uintptr_t __pointer_chk_guard_local
@@ -91,7 +91,7 @@ index 69873c2..6d3add7 100644
/* List of auditing DSOs. */
static struct audit_list
-@@ -877,12 +878,12 @@ of this helper program; chances are you did not intend to run this program.\n\
+@@ -873,12 +874,12 @@ of this helper program; chances are you did not intend to run this program.\n\
--list list all dependencies and how they are resolved\n\
--verify verify that given object really is a dynamically linked\n\
object we can handle\n\
@@ -107,7 +107,7 @@ index 69873c2..6d3add7 100644
++_dl_skip_args;
--_dl_argc;
diff --git a/sysdeps/generic/dl-cache.h b/sysdeps/generic/dl-cache.h
-index 4b49869..1800d03 100644
+index 70d4aeb..5c726d0 100644
--- a/sysdeps/generic/dl-cache.h
+++ b/sysdeps/generic/dl-cache.h
@@ -27,10 +27,6 @@
@@ -122,5 +122,5 @@ index 4b49869..1800d03 100644
# define add_system_dir(dir) add_dir (dir)
#endif
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch b/meta/recipes-core/glibc/glibc/0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch
deleted file mode 100644
index 748750304f..0000000000
--- a/meta/recipes-core/glibc/glibc/0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 2560b564b5674bf2990e5607f6342c1647a5dc4f Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Sun, 8 Mar 2015 04:01:01 +0000
-Subject: [PATCH 04/27] Backport
- https://sourceware.org/ml/libc-ports/2007-12/msg00000.html
-
-Upstream-Status: Pending
-
-2007-12-03 Kristian Van Der Vliet <vanders@liqwyd.com>
-
- * bits/stdio-lock.h (_IO_acquire_lock_clear_flags2): Define
-
-Signed-off-by: Kristian Van Der Vliet <vanders@liqwyd.com>
-Signed-off-by: Khem Raj <raj.khem@gmail.com>
----
- bits/stdio-lock.h | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/bits/stdio-lock.h b/bits/stdio-lock.h
-index 0c5bb65..66304a6 100644
---- a/bits/stdio-lock.h
-+++ b/bits/stdio-lock.h
-@@ -49,6 +49,8 @@ __libc_lock_define_recursive (typedef, _IO_lock_t)
- _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, (_fp)); \
- _IO_flockfile (_fp)
-
-+# define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp)
-+
- # define _IO_release_lock(_fp) \
- _IO_funlockfile (_fp); \
- _IO_cleanup_region_end (0)
---
-2.1.4
-
diff --git a/meta/recipes-core/glibc/glibc/0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch b/meta/recipes-core/glibc/glibc/0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch
new file mode 100644
index 0000000000..21f04a1321
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch
@@ -0,0 +1,32 @@
+From 2e1638115f0f924ee8235eee9265047054c15cfd Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Thu, 31 Dec 2015 14:35:35 -0800
+Subject: [PATCH 04/24] nativesdk-glibc: Allow 64 bit atomics for x86
+
+The fix consist of allowing 64bit atomic ops for x86.
+This should be safe for i586 and newer CPUs.
+It also makes the synchronization more efficient.
+
+Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
+Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ sysdeps/i386/atomic-machine.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sysdeps/i386/atomic-machine.h b/sysdeps/i386/atomic-machine.h
+index 59f3d34..6f6b7ff 100644
+--- a/sysdeps/i386/atomic-machine.h
++++ b/sysdeps/i386/atomic-machine.h
+@@ -54,7 +54,7 @@ typedef uintmax_t uatomic_max_t;
+ # endif
+ #endif
+
+-#define __HAVE_64B_ATOMICS 0
++#define __HAVE_64B_ATOMICS 1
+ #define USE_ATOMIC_COMPILER_BUILTINS 0
+
+
+--
+2.6.4
+
diff --git a/meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch b/meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch
index 8d3f859555..ba8c92e112 100644
--- a/meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch
+++ b/meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch
@@ -1,7 +1,7 @@
-From aa0cd82892f32e58602143c697ef0524696a6428 Mon Sep 17 00:00:00 2001
+From 7ff57edfe24b4243373fcb896ee0b613938c1ec9 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:01:50 +0000
-Subject: [PATCH 05/27] fsl e500/e5500/e6500/603e fsqrt implementation
+Subject: [PATCH 05/24] fsl e500/e5500/e6500/603e fsqrt implementation
Upstream-Status: Pending
Signed-off-by: Edmar Wienskoski <edmar@freescale.com>
@@ -1580,5 +1580,5 @@ index 0000000..04ff8cc
@@ -0,0 +1 @@
+powerpc/powerpc64/e6500/fpu
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch b/meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch
index 65c227ff20..086a73dd26 100644
--- a/meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch
+++ b/meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch
@@ -1,7 +1,7 @@
-From 5ec1bc5172851278231ce940b68b35ce9cbf8500 Mon Sep 17 00:00:00 2001
+From 61129ef3ee735b300604f75d50e01cb29f4387f4 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:11:22 +0000
-Subject: [PATCH 06/27] readlib: Add OECORE_KNOWN_INTERPRETER_NAMES to known
+Subject: [PATCH 06/24] readlib: Add OECORE_KNOWN_INTERPRETER_NAMES to known
names
This bolts in a hook for OE to pass its own version of interpreter
@@ -29,5 +29,5 @@ index 7fd5b8a..2f5da9f 100644
static struct known_names known_libs[] =
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch b/meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch
index aec8fbeb9a..952784b1cc 100644
--- a/meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch
+++ b/meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch
@@ -1,7 +1,7 @@
-From ea98b1a12b5f779fd79478ff930a79ef60387851 Mon Sep 17 00:00:00 2001
+From f936548decac99501f9a4c522a3211d16542fa49 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:15:07 +0000
-Subject: [PATCH 07/27] ppc/sqrt: Fix undefined reference to `__sqrt_finite'
+Subject: [PATCH 07/24] ppc/sqrt: Fix undefined reference to `__sqrt_finite'
on ppc fixes the errors like below
| ./.libs/libpulsecore-1.1.so: undefined reference to `__sqrt_finite'
@@ -204,5 +204,5 @@ index 26fa067..9d17512 100644
}
+strong_alias (__ieee754_sqrtf, __sqrtf_finite)
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch b/meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
index b3fa931c6c..8d513ab42a 100644
--- a/meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
+++ b/meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
@@ -1,7 +1,7 @@
-From 2456ea44aeeedae87edb522f77a7969d636399b0 Mon Sep 17 00:00:00 2001
+From d02704895fdce917e337619a4414042f63edd88b Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:16:38 +0000
-Subject: [PATCH 08/27] __ieee754_sqrt{,f} are now inline functions and call
+Subject: [PATCH 08/24] __ieee754_sqrt{,f} are now inline functions and call
out __slow versions
Upstream-Status: Pending
@@ -383,5 +383,5 @@ index 9d17512..10de1f0 100644
+
strong_alias (__ieee754_sqrtf, __sqrtf_finite)
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch b/meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch
index 1f5475912c..12f24fb685 100644
--- a/meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch
+++ b/meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch
@@ -1,7 +1,7 @@
-From acf7a028817e71eb99d785037659abd4d120ffe2 Mon Sep 17 00:00:00 2001
+From 502f061d846e58aac7aca67e4e0d6ba9e0763b17 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:20:09 +0000
-Subject: [PATCH 09/27] Quote from bug 1443 which explains what the patch does
+Subject: [PATCH 09/24] Quote from bug 1443 which explains what the patch does
:
We build some random program and link it with -lust. When we run it,
@@ -58,5 +58,5 @@ index 6fb20bd..8805537 100644
case R_ARM_TLS_TPOFF32:
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch b/meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch
index df3c1ef21f..77bd7d1324 100644
--- a/meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch
+++ b/meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch
@@ -1,7 +1,7 @@
-From 017322ee28c1579ce6c81904842aaada9c82403c Mon Sep 17 00:00:00 2001
+From 69a3e30b49d28a7386d18725528652931510cbfc Mon Sep 17 00:00:00 2001
From: Ting Liu <b28495@freescale.com>
Date: Wed, 19 Dec 2012 04:39:57 -0600
-Subject: [PATCH 10/27] eglibc: run libm-err-tab.pl with specific dirs in ${S}
+Subject: [PATCH 10/24] eglibc: run libm-err-tab.pl with specific dirs in ${S}
libm-err-tab.pl will parse all the files named "libm-test-ulps"
in the given dir recursively. To avoid parsing the one in
@@ -18,7 +18,7 @@ Signed-off-by: Ting Liu <b28495@freescale.com>
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/manual/Makefile b/manual/Makefile
-index 5382208..6b701b0 100644
+index cdb6763..0b32a0a 100644
--- a/manual/Makefile
+++ b/manual/Makefile
@@ -105,7 +105,8 @@ $(objpfx)libm-err.texi: $(objpfx)stamp-libm-err
@@ -32,5 +32,5 @@ index 5382208..6b701b0 100644
touch $@
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch b/meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
index 07a112b218..251e5f5af3 100644
--- a/meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
+++ b/meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
@@ -1,7 +1,7 @@
-From 1be45f870ebbb0259bea5250a6d2c2fbcb33409d Mon Sep 17 00:00:00 2001
+From 4cf52971a841304aec30b2e975f81d7ad9d42ef0 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:24:46 +0000
-Subject: [PATCH 11/27] __ieee754_sqrt{,f} are now inline functions and call
+Subject: [PATCH 11/24] __ieee754_sqrt{,f} are now inline functions and call
out __slow versions
Upstream-Status: Pending
@@ -57,5 +57,5 @@ index 8126535..10de1f0 100644
#endif
{
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch b/meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch
index 267791393e..3208a0c89b 100644
--- a/meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch
+++ b/meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch
@@ -1,7 +1,7 @@
-From 49471ab1f90e392da9520eea831ce8731be9fc8b Mon Sep 17 00:00:00 2001
+From b356816d6e005ecda7adbed9627a4315ad39de39 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:25:45 +0000
-Subject: [PATCH 12/27] Make ld --version output matching grok gold's output
+Subject: [PATCH 12/24] Make ld --version output matching grok gold's output
adapted from from upstream branch roland/gold-vs-libc
@@ -14,10 +14,10 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
-index 45cc7cb..7d7299a 100755
+index aa05d49..6dabd11 100755
--- a/configure
+++ b/configure
-@@ -4709,7 +4709,7 @@ else
+@@ -4486,7 +4486,7 @@ else
# Found it, now check the version.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5
$as_echo_n "checking version of $LD... " >&6; }
@@ -27,10 +27,10 @@ index 45cc7cb..7d7299a 100755
'') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*)
diff --git a/configure.ac b/configure.ac
-index 7e9383a..a467a69 100644
+index ee7a3f1..b4b95b9 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -941,7 +941,7 @@ AC_CHECK_PROG_VER(AS, $AS, --version,
+@@ -948,7 +948,7 @@ AC_CHECK_PROG_VER(AS, $AS, --version,
[2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*],
AS=: critic_missing="$critic_missing as")
AC_CHECK_PROG_VER(LD, $LD, --version,
@@ -40,5 +40,5 @@ index 7e9383a..a467a69 100644
LD=: critic_missing="$critic_missing ld")
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch b/meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch
index c1fda9d433..82fa100442 100644
--- a/meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch
+++ b/meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch
@@ -1,7 +1,7 @@
-From b55e49b199c46a278ab66b6b1e3eab483b913197 Mon Sep 17 00:00:00 2001
+From 10003d48f83f7a4f7fa562ed89af904a544b6323 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:27:10 +0000
-Subject: [PATCH 13/27] sysdeps/gnu/configure.ac: handle correctly
+Subject: [PATCH 13/24] sysdeps/gnu/configure.ac: handle correctly
$libc_cv_rootsbindir
Upstream-Status:Pending
@@ -14,7 +14,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sysdeps/gnu/configure b/sysdeps/gnu/configure
-index 9239297..c5ed3ca 100644
+index 71243ad..f578187 100644
--- a/sysdeps/gnu/configure
+++ b/sysdeps/gnu/configure
@@ -32,6 +32,6 @@ case "$prefix" in
@@ -38,5 +38,5 @@ index 634fe4d..3db1697 100644
;;
esac
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch b/meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch
index 0ba5d2fbad..ea3e1670f8 100644
--- a/meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch
+++ b/meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch
@@ -1,7 +1,7 @@
-From 0229d6c9c0e7721773118d5ae1d172c269bc9826 Mon Sep 17 00:00:00 2001
+From cafa8a7ef830e02cdbf928471e06d11054946940 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:28:41 +0000
-Subject: [PATCH 14/27] Add unused attribute
+Subject: [PATCH 14/24] Add unused attribute
Helps in avoiding gcc warning when header is is included in
a source file which does not use both functions
@@ -30,5 +30,5 @@ index 80290bc..7890a8e 100644
{
int slash_count = 0;
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch b/meta/recipes-core/glibc/glibc/0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch
deleted file mode 100644
index 4b261ca1ef..0000000000
--- a/meta/recipes-core/glibc/glibc/0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From f058c884dd26d10c94550ca5252ed6576614d659 Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Thu, 19 Feb 2015 03:23:45 +0000
-Subject: [PATCH 15/27] When disabling SSE also make sure that fpmath is not
- set to use SSE as well
-
-This fixes errors when we inject sse options through CFLAGS and now
-that we have -Werror turned on by default this warning turns to become
-error on x86
-
-Signed-off-by: Khem Raj <raj.khem@gmail.com>
-
-Upstream-Status: Pending
----
- sysdeps/x86/Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
-index 19f5eca..827ea71 100644
---- a/sysdeps/x86/Makefile
-+++ b/sysdeps/x86/Makefile
-@@ -1,6 +1,6 @@
- ifeq ($(subdir),elf)
- CFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\
-- -mno-sse -mno-mmx)
-+ -mno-sse -mno-mmx -mfpmath=387)
-
- tests-special += $(objpfx)tst-ld-sse-use.out
- $(objpfx)tst-ld-sse-use.out: ../sysdeps/x86/tst-ld-sse-use.sh $(objpfx)ld.so
---
-2.1.4
-
diff --git a/meta/recipes-core/glibc/glibc/0016-yes-within-the-path-sets-wrong-config-variables.patch b/meta/recipes-core/glibc/glibc/0015-yes-within-the-path-sets-wrong-config-variables.patch
index 089e8b1b0b..90e12b8835 100644
--- a/meta/recipes-core/glibc/glibc/0016-yes-within-the-path-sets-wrong-config-variables.patch
+++ b/meta/recipes-core/glibc/glibc/0015-yes-within-the-path-sets-wrong-config-variables.patch
@@ -1,7 +1,7 @@
-From 70199fe59c38b621ab4121d7a55719b2b29b36de Mon Sep 17 00:00:00 2001
+From 4d6bead19874e519752ceeb2a15897ff2ffbe5e8 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:31:06 +0000
-Subject: [PATCH 16/27] 'yes' within the path sets wrong config variables
+Subject: [PATCH 15/24] 'yes' within the path sets wrong config variables
It seems that the 'AC_EGREP_CPP(yes...' example is quite popular
but being such a short word to grep it is likely to produce
@@ -63,7 +63,7 @@ index 7851dd4..6e92381 100644
], libc_cv_aarch64_be=yes, libc_cv_aarch64_be=no)])
if test $libc_cv_aarch64_be = yes; then
diff --git a/sysdeps/arm/configure b/sysdeps/arm/configure
-index 158116b..5eaf54e 100644
+index 431e843..e152461 100644
--- a/sysdeps/arm/configure
+++ b/sysdeps/arm/configure
@@ -151,12 +151,12 @@ else
@@ -82,7 +82,7 @@ index 158116b..5eaf54e 100644
else
libc_cv_arm_pcs_vfp=no
diff --git a/sysdeps/arm/configure.ac b/sysdeps/arm/configure.ac
-index 859c92a..2f4a6e2 100644
+index 90cdd69..05a262b 100644
--- a/sysdeps/arm/configure.ac
+++ b/sysdeps/arm/configure.ac
@@ -15,8 +15,8 @@ AC_DEFINE(PI_STATIC_AND_HIDDEN)
@@ -165,10 +165,10 @@ index f05f438..dc86399 100644
], libc_cv_nios2_be=yes, libc_cv_nios2_be=no)])
if test $libc_cv_nios2_be = yes; then
diff --git a/sysdeps/unix/sysv/linux/mips/configure b/sysdeps/unix/sysv/linux/mips/configure
-index 83f8b13..2b6cbee 100644
+index dee56aa..f2049ed 100644
--- a/sysdeps/unix/sysv/linux/mips/configure
+++ b/sysdeps/unix/sysv/linux/mips/configure
-@@ -387,11 +387,11 @@ else
+@@ -414,11 +414,11 @@ else
/* end confdefs.h. */
dnl
#ifdef __mips_nan2008
@@ -183,10 +183,10 @@ index 83f8b13..2b6cbee 100644
else
libc_cv_mips_nan2008=no
diff --git a/sysdeps/unix/sysv/linux/mips/configure.ac b/sysdeps/unix/sysv/linux/mips/configure.ac
-index 5039ec9..1035f76 100644
+index 45147c5..4224af1 100644
--- a/sysdeps/unix/sysv/linux/mips/configure.ac
+++ b/sysdeps/unix/sysv/linux/mips/configure.ac
-@@ -98,9 +98,9 @@ AC_COMPILE_IFELSE(
+@@ -105,9 +105,9 @@ AC_COMPILE_IFELSE(
LIBC_CONFIG_VAR([mips-mode-switch],[${libc_mips_mode_switch}])
AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
@@ -199,7 +199,7 @@ index 5039ec9..1035f76 100644
libc_mips_nan=
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure b/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure
-index 70bb18a..ffd9e3e 100644
+index af06970..27b8c1b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure
@@ -155,12 +155,12 @@ else
@@ -259,5 +259,5 @@ index 0822915..9a32fdd 100644
], libc_cv_ppc64_def_call_elf=yes, libc_cv_ppc64_def_call_elf=no)])
if test $libc_cv_ppc64_def_call_elf = no; then
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch b/meta/recipes-core/glibc/glibc/0016-timezone-re-written-tzselect-as-posix-sh.patch
index 0ce823087d..e51b611f37 100644
--- a/meta/recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch
+++ b/meta/recipes-core/glibc/glibc/0016-timezone-re-written-tzselect-as-posix-sh.patch
@@ -1,7 +1,7 @@
-From c90306107fbbe2979012917e87747ce78c82ab88 Mon Sep 17 00:00:00 2001
+From 3e8586eb3509e2f0d6dfb74be8f89a30b06b56e9 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:33:03 +0000
-Subject: [PATCH 17/27] timezone: re-written tzselect as posix sh
+Subject: [PATCH 16/24] timezone: re-written tzselect as posix sh
To avoid the bash dependency.
@@ -15,10 +15,10 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/timezone/Makefile b/timezone/Makefile
-index 24c93c6..886b06e 100644
+index 99566cb..b6e757e 100644
--- a/timezone/Makefile
+++ b/timezone/Makefile
-@@ -126,7 +126,7 @@ $(testdata)/XT%: testdata/XT%
+@@ -122,7 +122,7 @@ $(testdata)/XT%: testdata/XT%
cp $< $@
$(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
@@ -41,5 +41,5 @@ index 9d70691..25f45a8 100755
# Check for awk Posix compliance.
($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/nscd-no-bash.patch b/meta/recipes-core/glibc/glibc/0017-Remove-bash-dependency-for-nscd-init-script.patch
index c306ce6afe..0c9ae6c139 100644
--- a/meta/recipes-core/glibc/glibc/nscd-no-bash.patch
+++ b/meta/recipes-core/glibc/glibc/0017-Remove-bash-dependency-for-nscd-init-script.patch
@@ -1,7 +1,16 @@
-Don't use bashisms (except for echo -n, which busybox supports) to avoid needing bash to start nscd.
+From cd9d9fe7316f4ce4ca9d8e67e22f5718879535e4 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Thu, 31 Dec 2015 14:33:02 -0800
+Subject: [PATCH 17/24] Remove bash dependency for nscd init script
+
+The nscd init script uses #! /bin/bash but only really uses one bashism
+(translated strings), so remove them and switch the shell to #!/bin/sh.
-Upstream-Status: Pending
Signed-off-by: Ross Burton <ross.burton@intel.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ nscd/nscd.init | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/nscd/nscd.init b/nscd/nscd.init
index a882da7..b02986e 100644
@@ -59,3 +68,6 @@ index a882da7..b02986e 100644
RETVAL=1
;;
esac
+--
+2.6.4
+
diff --git a/meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch b/meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch
index 8eacbc059f..e282e60ebd 100644
--- a/meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch
+++ b/meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch
@@ -1,7 +1,7 @@
-From eff048074ac7b5258bb615e5a5b221daa19b18ae Mon Sep 17 00:00:00 2001
+From 8f554f4a1beb39182aad9cd9b5e1da69464dff7e Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:42:58 +0000
-Subject: [PATCH 18/27] eglibc: Cross building and testing instructions
+Subject: [PATCH 18/24] eglibc: Cross building and testing instructions
Ported from eglibc
Upstream-Status: Pending
@@ -615,5 +615,5 @@ index 0000000..b67b468
+ simply place copies of these libraries in the top GLIBC build
+ directory.
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch b/meta/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch
deleted file mode 100644
index dcb80f9c80..0000000000
--- a/meta/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch
+++ /dev/null
@@ -1,1436 +0,0 @@
-From aa7c5fe86d04584a9aed4dc40ba856c65a1ef9c4 Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Wed, 18 Mar 2015 00:45:18 +0000
-Subject: [PATCH 19/27] eglibc: Bring Eglibc option group infrastructure to
- glibc
-
-Upstream-Status: Pending
-
-Signed-off-by: Khem Raj <raj.khem@gmail.com>
----
- EGLIBC.option-groups | 122 ++++++
- Makefile | 1 +
- config.make.in | 2 +
- configure | 13 +
- configure.ac | 10 +
- option-groups.def | 868 ++++++++++++++++++++++++++++++++++++++
- option-groups.defaults | 47 +++
- option-groups.mak | 41 ++
- options-config/Makefile | 55 +++
- options-config/config-postproc.pl | 58 +++
- options-config/config-preproc.pl | 8 +
- scripts/option-groups.awk | 63 +++
- 12 files changed, 1288 insertions(+)
- create mode 100644 EGLIBC.option-groups
- create mode 100644 option-groups.def
- create mode 100644 option-groups.defaults
- create mode 100644 option-groups.mak
- create mode 100644 options-config/Makefile
- create mode 100644 options-config/config-postproc.pl
- create mode 100644 options-config/config-preproc.pl
- create mode 100644 scripts/option-groups.awk
-
-diff --git a/EGLIBC.option-groups b/EGLIBC.option-groups
-new file mode 100644
-index 0000000..6a50b8d
---- /dev/null
-+++ b/EGLIBC.option-groups
-@@ -0,0 +1,122 @@
-+ -*- mode: text -*-
-+
-+ The EGLIBC Component Configuration System
-+ Jim Blandy <jimb@codesourcery.com>
-+
-+Introduction
-+
-+The GNU C library (GLIBC) provides a broad range of functionality,
-+ranging from internationalization support to transcendental
-+mathematical functions. Its website boasts that "nearly all known and
-+useful functions from any other C library are available." This
-+exhaustive approach has been one of GLIBC's strengths on desktop and
-+server systems, but it has also given GLIBC a large footprint, both in
-+memory and on disk, making it a challenge to use in embedded systems
-+with limited resources.
-+
-+The Embedded GNU C library (EGLIBC) is a variant of the GNU C library
-+designed to work well on embedded systems. In particular, EGLIBC's
-+component configuration system allows embedded developers to build
-+customized versions of the library that include only the features
-+their application uses, reducing its space requirements.
-+
-+EGLIBC's component configuration system categorizes the library's
-+functions into "option groups", and allows you to include or exclude
-+option groups individually. Some option groups depend on others;
-+EGLIBC tracks these relationships, and ensures that the selected
-+configuration yields a functioning library.
-+
-+
-+Consistent and Predictable Behavior
-+
-+A flexible configuration system is a mixed blessing: if the options
-+offered are poorly designed, it can be hard to see which choices will
-+have the desired effects, and choices with obscure consequences can
-+make debugging difficult. EGLIBC's configuration follows some general
-+principles to reduce these risks:
-+
-+- EGLIBC has a single default configuration for each target
-+ architecture.
-+
-+- In the default configuration, all option groups are enabled, and
-+ EGLIBC is upwardly API- and ABI-compatible with GLIBC.
-+
-+- As much as possible, configurations only affect what functions are
-+ present, not how they behave. If the system works with an option
-+ group disabled, it will still work with it enabled.
-+
-+- As much as possible, configurations only select option groups ---
-+ they do not describe characteristics of the target architecture.
-+
-+These rules mean that you have a simple debugging strategy available
-+if you suspect that your EGLIBC configuration might be the source of a
-+problem: fall back to the default configuration, re-test, and then
-+disable option groups one by one, until the problem reappears.
-+
-+
-+The Option Groups
-+
-+To see the current full list of implemented option groups, refer to the
-+file 'option-groups.def' at the top of the source tree, or run
-+'make menuconfig' from the top-level build directory.
-+
-+The POSIX.1-2001 specification includes a suggested partition of all
-+the functions in the POSIX C API into option groups: math functions
-+like 'sin' and 'cos'; networking functions like 'socket' and
-+'connect'; and so on. EGLIBC could use this partitioning as the basis
-+for future option groups.
-+
-+
-+Implementation
-+
-+The EGLIBC component configuration system resembles the approach used
-+by the Linux kernel to select device drivers, network protocols, and
-+other features. A file named 'option-groups.config' in the top-level
-+build directory contains assignments to Make variables, each of which
-+enables or disables a particular option group. If the variable's
-+value is set to 'y', then the option group is enabled; if it set to
-+anything else, the option group is omitted. The file
-+'option-groups.defaults', at the top of the source tree, establishes
-+default values for all variables; all option groups are enabled by
-+default.
-+
-+For example, the following 'option-groups.config' would omit locale
-+data, but include mathematical functions, and everything else:
-+
-+ OPTION_EGLIBC_LOCALES = n
-+ OPTION_EGLIBC_LIBM = y
-+
-+Like the Linux kernel, EGLIBC supports a similar set of '*config' make
-+targets to make it easier to create 'option-groups.config', with all
-+dependencies between option groups automatically satisfied. Run
-+'make help' to see the list of supported make config targets. For
-+example, 'make menuconfig' will update the current config utilising a
-+menu based program.
-+
-+The option group names and their type (boolean, int, hex, string), help
-+description, and dependencies with other option groups, are described by
-+'option-groups.def' at the top of the source tree, analogous to the
-+'Kconfig' files in the Linux kernel.
-+
-+In general, each option group variable controls whether a given set of
-+object files in EGLIBC is compiled and included in the final
-+libraries, or omitted from the build.
-+
-+Each subdirectory's Makefile categorizes its routines, libraries, and
-+executables by option group. For example, EGLIBC's 'math/Makefile'
-+places the 'libm' library in the OPTION_EGLIBC_LIBM group as follows:
-+
-+ extra-libs-$(OPTION_EGLIBC_LIBM) := libm
-+
-+Finally, common code in 'Makerules' cites the value of the variable
-+'extra-libs-y', selecting only those libraries that belong to enabled
-+option groups to be built.
-+
-+
-+Current Status and Future Directions
-+
-+The EGLIBC component configuration system described here is still
-+under development.
-+
-+We have used the system to subset some portions of EGLIBC's
-+Index: libc/configure.ac
-diff --git a/Makefile b/Makefile
-index 658ccfa..f906391 100644
---- a/Makefile
-+++ b/Makefile
-@@ -24,6 +24,7 @@ endif
-
- include Makeconfig
-
-+include options-config/Makefile
-
- # This is the default target; it makes everything except the tests.
- .PHONY: all
-diff --git a/config.make.in b/config.make.in
-index a9f5696..294f8d1 100644
---- a/config.make.in
-+++ b/config.make.in
-@@ -47,6 +47,8 @@ c++-sysincludes = @CXX_SYSINCLUDES@
- all-warnings = @all_warnings@
- enable-werror = @enable_werror@
-
-+kconfig_tools = @KCONFIG_TOOLS@
-+
- have-z-combreloc = @libc_cv_z_combreloc@
- have-z-execstack = @libc_cv_z_execstack@
- have-Bgroup = @libc_cv_Bgroup@
-diff --git a/configure b/configure
-index 7d7299a..4116404 100755
---- a/configure
-+++ b/configure
-@@ -641,6 +641,7 @@ INSTALL_INFO
- PERL
- BASH_SHELL
- libc_cv_gcc_static_libgcc
-+KCONFIG_TOOLS
- CXX_SYSINCLUDES
- SYSINCLUDES
- AUTOCONF
-@@ -755,6 +756,7 @@ with_fp
- with_binutils
- with_selinux
- with_headers
-+with_kconfig
- with_default_link
- enable_sanity_checks
- enable_shared
-@@ -1459,6 +1461,9 @@ Optional Packages:
- --with-selinux if building with SELinux support
- --with-headers=PATH location of system headers to use (for example
- /usr/src/linux/include) [default=compiler default]
-+ --with-kconfig=PATH location of kconfig tools to use (from Linux kernel
-+ builds) to re-use for configuring EGLIBC option
-+ groups
- --with-default-link do not use explicit linker scripts
- --with-cpu=CPU select code for CPU variant
-
-@@ -3517,6 +3522,14 @@ fi
-
-
-
-+# Check whether --with-kconfig was given.
-+if test "${with_kconfig+set}" = set; then
-+ withval=$with_kconfig; KCONFIG_TOOLS=$withval
-+else
-+ KCONFIG_TOOLS=''
-+fi
-+
-+
-
- # Check whether --with-default-link was given.
- if test "${with_default_link+set}" = set; then :
-diff --git a/configure.ac b/configure.ac
-index a467a69..fc0ed4d 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -136,6 +136,16 @@ AC_ARG_WITH([headers],
- [sysheaders=''])
- AC_SUBST(sysheaders)
-
-+AC_ARG_WITH([kconfig],
-+ AC_HELP_STRING([--with-kconfig=PATH],
-+ [location of kconfig tools to use (from Linux
-+ kernel builds) to re-use for configuring EGLIBC
-+ option groups]),
-+ [KCONFIG_TOOLS=$withval],
-+ [KCONFIG_TOOLS=''])
-+AC_SUBST(KCONFIG_TOOLS)
-+
-+
- AC_SUBST(use_default_link)
- AC_ARG_WITH([default-link],
- AC_HELP_STRING([--with-default-link],
-diff --git a/option-groups.def b/option-groups.def
-new file mode 100644
-index 0000000..6aebd94
---- /dev/null
-+++ b/option-groups.def
-@@ -0,0 +1,868 @@
-+# This file documents the option groups EGLIBC currently supports, in
-+# a format akin to the Linux Kconfig system's. The syntax may change
-+# over time.
-+#
-+# An entry of the form:
-+#
-+# config GROUP_NAME
-+# bool "one-line explanation of what this option group controls"
-+# help
-+# Multi-line help explaining the option group's meaning in
-+# some detail, terminated by indentation level.
-+#
-+# defines an option group whose variable is GROUP_NAME, with
-+# meaningful values 'y' (enabled) and 'n' (disabled). The
-+# documentation is formatted to be consumed by some sort of
-+# interactive configuration interface, but EGLIBC doesn't have such an
-+# interface yet.
-+#
-+# An option may have a 'depends on' line, indicating which other options
-+# must also be enabled if this option is. At present, EGLIBC doesn't
-+# check that these dependencies are satisfied.
-+#
-+# Option group variables get their default values from the file
-+# 'option-groups.defaults', in the top directory of the EGLIBC source
-+# tree. By default, all EGLIBC option groups are enabled --- their
-+# variables are set to 'y'.
-+#
-+# After including 'option-groups.defaults', the EGLIBC make machinery
-+# includes the file 'option-groups.config' from the top of the build
-+# tree, if it is present. Developers can place assignments to option
-+# group variables in that file to override the defaults. For example,
-+# to disable an option group, place a line of the form:
-+#
-+# OPTION_GROUP_NAME = n
-+#
-+# in 'option-groups.config' at the top of your build tree. To
-+# explicitly enable an option group, you may also write:
-+#
-+# OPTION_GROUP_NAME = y
-+#
-+# although this simply reestablishes the value already set by
-+# 'option-groups.defaults'.
-+
-+config EGLIBC_ADVANCED_INET6
-+ bool "IPv6 Advanced Sockets API support (RFC3542)"
-+ depends on EGLIBC_INET
-+ help
-+ This option group includes the functions specified by RFC 3542,
-+ "Advanced Sockets Application Program Interface (API) for
-+ IPv6".
-+
-+ This option group includes the following functions:
-+
-+ inet6_opt_append
-+ inet6_opt_find
-+ inet6_opt_finish
-+ inet6_opt_get_val
-+ inet6_opt_init
-+ inet6_option_alloc
-+ inet6_option_append
-+ inet6_option_find
-+ inet6_option_init
-+ inet6_option_next
-+ inet6_option_space
-+ inet6_opt_next
-+ inet6_opt_set_val
-+ inet6_rth_add
-+ inet6_rth_getaddr
-+ inet6_rth_init
-+ inet6_rth_reverse
-+ inet6_rth_segments
-+ inet6_rth_space
-+
-+config EGLIBC_BACKTRACE
-+ bool "Functions for producing backtraces"
-+ help
-+ This option group includes functions for producing a list of
-+ the function calls that are currently active in a thread, from
-+ within the thread itself. These functions are often used
-+ within signal handlers, to produce diagnostic output.
-+
-+ This option group includes the following functions:
-+
-+ backtrace
-+ backtrace_symbols
-+ backtrace_symbols_fd
-+
-+config EGLIBC_BIG_MACROS
-+ bool "Use extensive inline code"
-+ help
-+ This option group specifies whether certain pieces of code
-+ should be inlined to achieve maximum speed. If this option
-+ group is not selected, function calls will be used instead,
-+ hence reducing the library footprint.
-+
-+config EGLIBC_BSD
-+ bool "BSD-specific functions, and their compatibility stubs"
-+ help
-+ This option group includes functions specific to BSD kernels.
-+ A number of these functions have stub versions that are also
-+ included in libraries built for non-BSD systems for
-+ compatibility.
-+
-+ This option group includes the following functions:
-+
-+ chflags
-+ fchflags
-+ lchmod
-+ revoke
-+ setlogin
-+
-+config EGLIBC_CXX_TESTS
-+ bool "Tests that link against the standard C++ library."
-+ depends on POSIX_WIDE_CHAR_DEVICE_IO && EGLIBC_LIBM
-+ help
-+ This option group does not include any C library functions;
-+ instead, it controls which EGLIBC tests an ordinary 'make
-+ tests' runs. With this group disabled, tests that would
-+ normally link against the standard C++ library are not
-+ run.
-+
-+ The standard C++ library depends on the math library 'libm' and
-+ the wide character I/O functions included in EGLIBC. So those
-+ option groups must be enabled if this test is enabled.
-+
-+config EGLIBC_CATGETS
-+ bool "Functions for accessing message catalogs"
-+ depends on EGLIBC_LOCALE_CODE
-+ help
-+ This option group includes functions for accessing message
-+ catalogs: catopen, catclose, and catgets.
-+
-+ This option group depends on the EGLIBC_LOCALE_CODE
-+ option group.
-+
-+config EGLIBC_CHARSETS
-+ bool "iconv/gconv character set conversion libraries"
-+ help
-+ This option group includes support for character sets other
-+ than ASCII (ANSI_X3.4-1968) and Unicode and ISO-10646 in their
-+ various encodings. This affects both the character sets
-+ supported by the wide and multibyte character functions, and
-+ those supported by the 'iconv' functions.
-+
-+ With this option group disabled, EGLIBC supports only the
-+ following character sets:
-+
-+ ANSI_X3.4 - ASCII
-+ ANSI_X3.4-1968
-+ ANSI_X3.4-1986
-+ ASCII
-+ CP367
-+ CSASCII
-+ IBM367
-+ ISO-IR-6
-+ ISO646-US
-+ ISO_646.IRV:1991
-+ OSF00010020
-+ US
-+ US-ASCII
-+
-+ 10646-1:1993 - ISO 10646, in big-endian UCS4 form
-+ 10646-1:1993/UCS4
-+ CSUCS4
-+ ISO-10646
-+ ISO-10646/UCS4
-+ OSF00010104
-+ OSF00010105
-+ OSF00010106
-+ UCS-4
-+ UCS-4BE
-+ UCS4
-+
-+ UCS-4LE - ISO 10646, in little-endian UCS4 form
-+
-+ ISO-10646/UTF-8 - ISO 10646, in UTF-8 form
-+ ISO-10646/UTF8
-+ ISO-IR-193
-+ OSF05010001
-+ UTF-8
-+ UTF8
-+
-+ ISO-10646/UCS2 - ISO 10646, in target-endian UCS2 form
-+ OSF00010100
-+ OSF00010101
-+ OSF00010102
-+ UCS-2
-+ UCS2
-+
-+ UCS-2BE - ISO 10646, in big-endian UCS2 form
-+ UNICODEBIG
-+
-+ UCS-2LE - ISO 10646, in little-endian UCS2 form
-+ UNICODELITTLE
-+
-+ WCHAR_T - EGLIBC's internal form (target-endian,
-+ 32-bit ISO 10646)
-+
-+config EGLIBC_CRYPT
-+ bool "Encryption library"
-+ help
-+ This option group includes the `libcrypt' library which
-+ provides functions for one-way encryption. Supported
-+ encryption algorithms include MD5, SHA-256, SHA-512 and DES.
-+
-+config EGLIBC_CRYPT_UFC
-+ bool "Ultra fast `crypt' implementation"
-+ depends on EGLIBC_CRYPT
-+ help
-+ This option group provides ultra fast DES-based implementation of
-+ the `crypt' function. When this option group is disabled,
-+ (a) the library will not provide the setkey[_r] and encrypt[_r]
-+ functions and (b) the crypt[_r] function will return NULL and set the
-+ errno to ENOSYS if /salt/ passed does not correspond to either MD5,
-+ SHA-256 or SHA-512 algorithm.
-+
-+config EGLIBC_DB_ALIASES
-+ bool "Functions for accessing the mail aliases database"
-+ help
-+ This option group includues functions for looking up mail
-+ aliases in '/etc/aliases' or using nsswitch. It includes the
-+ following functions:
-+
-+ endaliasent
-+ getaliasbyname
-+ getaliasbyname_r
-+ getaliasent
-+ getaliasent_r
-+ setaliasent
-+
-+ When this option group is disabled, the NSS service libraries
-+ also lack support for querying their mail alias tables.
-+
-+config EGLIBC_ENVZ
-+ bool "Functions for handling envz-style environment vectors."
-+ help
-+ This option group contains functions for creating and operating
-+ on envz vectors. An "envz vector" is a vector of strings in a
-+ contiguous block of memory, where each element is a name-value
-+ pair, and elements are separated from their neighbors by null
-+ characters.
-+
-+ This option group includes the following functions:
-+
-+ envz_add envz_merge
-+ envz_entry envz_remove
-+ envz_get envz_strip
-+
-+config EGLIBC_FCVT
-+ bool "Functions for converting floating-point numbers to strings"
-+ help
-+ This option group includes functions for converting
-+ floating-point numbers to strings.
-+
-+ This option group includes the following functions:
-+
-+ ecvt qecvt
-+ ecvt_r qecvt_r
-+ fcvt qfcvt
-+ fcvt_r qfcvt_r
-+ gcvt qgcvt
-+
-+config EGLIBC_FMTMSG
-+ bool "Functions for formatting messages"
-+ help
-+ This option group includes the following functions:
-+
-+ addseverity fmtmsg
-+
-+config EGLIBC_FSTAB
-+ bool "Access functions for 'fstab'"
-+ help
-+ This option group includes functions for reading the mount
-+ point specification table, '/etc/fstab'. These functions are
-+ not included in the POSIX standard, which provides the
-+ 'getmntent' family of functions instead.
-+
-+ This option group includes the following functions:
-+
-+ endfsent getfsspec
-+ getfsent setfsent
-+ getfsfile
-+
-+config EGLIBC_FTRAVERSE
-+ bool "Functions for traversing file hierarchies"
-+ help
-+ This option group includes functions for traversing file
-+ UNIX file hierachies.
-+
-+ This option group includes the following functions:
-+
-+ fts_open ftw
-+ fts_read nftw
-+ fts_children ftw64
-+ fts_set nftw64
-+ fts_close
-+
-+config EGLIBC_GETLOGIN
-+ bool "The getlogin function"
-+ depends on EGLIBC_UTMP
-+ help
-+ This function group includes the 'getlogin' and 'getlogin_r'
-+ functions, which return the user name associated by the login
-+ activity with the current process's controlling terminal.
-+
-+ With this option group disabled, the 'glob' function will not
-+ fall back on 'getlogin' to find the user's login name for tilde
-+ expansion when the 'HOME' environment variable is not set.
-+
-+config EGLIBC_IDN
-+ bool "International domain names support"
-+ help
-+ This option group includes the `libcidn' library which
-+ provides support for international domain names.
-+
-+config EGLIBC_INET
-+ bool "Networking support"
-+ help
-+ This option group includes networking-specific functions and
-+ data. With EGLIBC_INET disabled, the EGLIBC
-+ installation and API changes as follows:
-+
-+ - The following libraries are not installed:
-+
-+ libnsl
-+ libnss_compat
-+ libnss_dns
-+ libnss_hesiod
-+ libnss_nis
-+ libnss_nisplus
-+ libresolv
-+
-+ - The following functions and variables are omitted from libc:
-+
-+ authdes_create hstrerror svc_fdset
-+ authdes_getucred htonl svc_getreq
-+ authdes_pk_create htons svc_getreq_common
-+ authnone_create if_freenameindex svc_getreq_poll
-+ authunix_create if_indextoname svc_getreqset
-+ authunix_create_default if_nameindex svc_max_pollfd
-+ bindresvport if_nametoindex svc_pollfd
-+ callrpc in6addr_any svcraw_create
-+ cbc_crypt in6addr_loopback svc_register
-+ clnt_broadcast inet6_opt_append svc_run
-+ clnt_create inet6_opt_find svc_sendreply
-+ clnt_pcreateerror inet6_opt_finish svctcp_create
-+ clnt_perrno inet6_opt_get_val svcudp_bufcreate
-+ clnt_perror inet6_opt_init svcudp_create
-+ clntraw_create inet6_option_alloc svcudp_enablecache
-+ clnt_spcreateerror inet6_option_append svcunix_create
-+ clnt_sperrno inet6_option_find svcunixfd_create
-+ clnt_sperror inet6_option_init svc_unregister
-+ clnttcp_create inet6_option_next user2netname
-+ clntudp_bufcreate inet6_option_space xdecrypt
-+ clntudp_create inet6_opt_next xdr_accepted_reply
-+ clntunix_create inet6_opt_set_val xdr_array
-+ des_setparity inet6_rth_add xdr_authdes_cred
-+ ecb_crypt inet6_rth_getaddr xdr_authdes_verf
-+ endaliasent inet6_rth_init xdr_authunix_parms
-+ endhostent inet6_rth_reverse xdr_bool
-+ endnetent inet6_rth_segments xdr_bytes
-+ endnetgrent inet6_rth_space xdr_callhdr
-+ endprotoent inet_addr xdr_callmsg
-+ endrpcent inet_aton xdr_char
-+ endservent inet_lnaof xdr_cryptkeyarg
-+ ether_aton inet_makeaddr xdr_cryptkeyarg2
-+ ether_aton_r inet_netof xdr_cryptkeyres
-+ ether_hostton inet_network xdr_des_block
-+ ether_line inet_nsap_addr xdr_double
-+ ether_ntoa inet_nsap_ntoa xdr_enum
-+ ether_ntoa_r inet_ntoa xdr_float
-+ ether_ntohost inet_ntop xdr_free
-+ freeaddrinfo inet_pton xdr_getcredres
-+ freeifaddrs innetgr xdr_hyper
-+ gai_strerror iruserok xdr_int
-+ getaddrinfo iruserok_af xdr_int16_t
-+ getaliasbyname key_decryptsession xdr_int32_t
-+ getaliasbyname_r key_decryptsession_pk xdr_int64_t
-+ getaliasent key_encryptsession xdr_int8_t
-+ getaliasent_r key_encryptsession_pk xdr_keybuf
-+ gethostbyaddr key_gendes xdr_key_netstarg
-+ gethostbyaddr_r key_get_conv xdr_key_netstres
-+ gethostbyname key_secretkey_is_set xdr_keystatus
-+ gethostbyname2 key_setnet xdr_long
-+ gethostbyname2_r key_setsecret xdr_longlong_t
-+ gethostbyname_r netname2host xdrmem_create
-+ gethostent netname2user xdr_netnamestr
-+ gethostent_r ntohl xdr_netobj
-+ getifaddrs ntohs xdr_opaque
-+ getipv4sourcefilter passwd2des xdr_opaque_auth
-+ get_myaddress pmap_getmaps xdr_pmap
-+ getnameinfo pmap_getport xdr_pmaplist
-+ getnetbyaddr pmap_rmtcall xdr_pointer
-+ getnetbyaddr_r pmap_set xdr_quad_t
-+ getnetbyname pmap_unset xdrrec_create
-+ getnetbyname_r rcmd xdrrec_endofrecord
-+ getnetent rcmd_af xdrrec_eof
-+ getnetent_r registerrpc xdrrec_skiprecord
-+ getnetgrent res_init xdr_reference
-+ getnetgrent_r rexec xdr_rejected_reply
-+ getnetname rexec_af xdr_replymsg
-+ getprotobyname rexecoptions xdr_rmtcall_args
-+ getprotobyname_r rpc_createerr xdr_rmtcallres
-+ getprotobynumber rresvport xdr_short
-+ getprotobynumber_r rresvport_af xdr_sizeof
-+ getprotoent rtime xdrstdio_create
-+ getprotoent_r ruserok xdr_string
-+ getpublickey ruserok_af xdr_u_char
-+ getrpcbyname ruserpass xdr_u_hyper
-+ getrpcbyname_r setaliasent xdr_u_int
-+ getrpcbynumber sethostent xdr_uint16_t
-+ getrpcbynumber_r setipv4sourcefilter xdr_uint32_t
-+ getrpcent setnetent xdr_uint64_t
-+ getrpcent_r setnetgrent xdr_uint8_t
-+ getrpcport setprotoent xdr_u_long
-+ getsecretkey setrpcent xdr_u_longlong_t
-+ getservbyname setservent xdr_union
-+ getservbyname_r setsourcefilter xdr_unixcred
-+ getservbyport svcauthdes_stats xdr_u_quad_t
-+ getservbyport_r svcerr_auth xdr_u_short
-+ getservent svcerr_decode xdr_vector
-+ getservent_r svcerr_noproc xdr_void
-+ getsourcefilter svcerr_noprog xdr_wrapstring
-+ h_errlist svcerr_progvers xencrypt
-+ h_errno svcerr_systemerr xprt_register
-+ herror svcerr_weakauth xprt_unregister
-+ h_nerr svc_exit
-+ host2netname svcfd_create
-+
-+ - The rpcgen, nscd, and rpcinfo commands are not installed.
-+
-+ - The 'rpc' file (a text file listing RPC services) is not installed.
-+
-+ Socket-related system calls do not fall in this option group,
-+ because many are also used for other inter-process
-+ communication mechanisms. For example, the 'syslog' routines
-+ use Unix-domain sockets to communicate with the syslog daemon;
-+ syslog is valuable in non-networked contexts.
-+
-+config EGLIBC_INET_ANL
-+ bool "Asynchronous name lookup"
-+ depends on EGLIBC_INET
-+ help
-+ This option group includes the `libanl' library which
-+ provides support for asynchronous name lookup.
-+
-+config EGLIBC_LIBM
-+ bool "libm (math library)"
-+ help
-+ This option group includes the 'libm' library, containing
-+ mathematical functions. If this option group is omitted, then
-+ an EGLIBC installation does not include shared or unshared versions
-+ of the math library.
-+
-+ Note that this does not remove all floating-point related
-+ functionality from EGLIBC; for example, 'printf' and 'scanf'
-+ can still print and read floating-point values with this option
-+ group disabled.
-+
-+ Note that the ISO Standard C++ library 'libstdc++' depends on
-+ EGLIBC's math library 'libm'. If you disable this option
-+ group, you will not be able to build 'libstdc++' against the
-+ resulting EGLIBC installation.
-+
-+config EGLIBC_LOCALES
-+ bool "Locale definitions"
-+ help
-+ This option group includes all locale definitions other than
-+ that for the "C" locale. If this option group is omitted, then
-+ only the "C" locale is supported.
-+
-+
-+config EGLIBC_LOCALE_CODE
-+ bool "Locale functions"
-+ depends on POSIX_C_LANG_WIDE_CHAR
-+ help
-+ This option group includes locale support functions, programs,
-+ and libraries. With EGLIBC_LOCALE_CODE disabled,
-+ EGLIBC supports only the 'C' locale (also known as 'POSIX'),
-+ and ignores the settings of the 'LANG' and 'LC_*' environment
-+ variables.
-+
-+ With EGLIBC_LOCALE_CODE disabled, the following
-+ functions are omitted from libc:
-+
-+ duplocale localeconv nl_langinfo rpmatch strfmon_l
-+ freelocale newlocale nl_langinfo_l strfmon uselocale
-+
-+ Furthermore, only the LC_CTYPE and LC_TIME categories of the
-+ standard "C" locale are available.
-+
-+ The EGLIBC_CATGETS option group depends on this option group.
-+
-+
-+config EGLIBC_MEMUSAGE
-+ bool "Memory profiling library"
-+ help
-+ This option group includes the `libmemusage' library and
-+ the `memusage' and `memusagestat' utilities.
-+ These components provide memory profiling functions.
-+
-+config EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
-+ int "Memory profiling library buffer size"
-+ depends on EGLIBC_MEMUSAGE
-+ default "32768"
-+ help
-+ Libmemusage library buffers the profiling data in memory
-+ before writing it out to disk. By default, the library
-+ allocates 1.5M buffer, which can be substantial for some
-+ systems. EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE option
-+ allows to change the default buffer size. It specifies
-+ the number of entries the buffer should have.
-+ On most architectures one buffer entry amounts to 48 bytes,
-+ so setting this option to the value of 512 will reduce the size of
-+ the memory buffer to 24K.
-+
-+config EGLIBC_NIS
-+ bool "Support for NIS, NIS+, and the special 'compat' services."
-+ depends on EGLIBC_INET && EGLIBC_SUNRPC
-+ help
-+ This option group includes the NIS, NIS+, and 'compat' Name
-+ Service Switch service libraries. When it is disabled, those
-+ services libraries are not installed; you should remove any
-+ references to them from your 'nsswitch.conf' file.
-+
-+ This option group depends on the EGLIBC_INET option
-+ group; you must enable that to enable this option group.
-+
-+config EGLIBC_NSSWITCH
-+ bool "Name service switch (nsswitch) support"
-+ help
-+ This option group includes support for the 'nsswitch' facility.
-+ With this option group enabled, all EGLIBC functions for
-+ accessing various system databases (passwords and groups;
-+ networking; aliases; public keys; and so on) consult the
-+ '/etc/nsswitch.conf' configuration file to decide how to handle
-+ queries.
-+
-+ With this option group disabled, EGLIBC uses a fixed list of
-+ services to satisfy queries on each database, as requested by
-+ configuration files specified when EGLIBC is built. Your
-+ 'option-groups.config' file must set the following two
-+ variables:
-+
-+config EGLIBC_NSSWITCH_FIXED_CONFIG
-+ string "Nsswitch fixed config filename"
-+ depends on !EGLIBC_NSSWITCH
-+ default ""
-+ help
-+ Set this to the name of a file whose contents observe the
-+ same syntax as an ordinary '/etc/nsswitch.conf' file. The
-+ EGLIBC build process parses this file just as EGLIBC would
-+ at run time if EGLIBC_NSSWITCH were enabled, and
-+ produces a C library that uses the nsswitch service
-+ libraries to search for database entries as this file
-+ specifies, instead of consulting '/etc/nsswitch.conf' at run
-+ time.
-+
-+ This should be an absolute filename. The EGLIBC build
-+ process may use it from several different working
-+ directories. It may include references to Makefile
-+ variables like 'common-objpfx' (the top of the build tree,
-+ with a trailing slash), or '..' (the top of the source tree,
-+ with a trailing slash).
-+
-+ The EGLIBC source tree includes a sample configuration file
-+ named 'nss/fixed-nsswitch.conf'; for simple configurations,
-+ you will probably want to delete references to databases not
-+ needed on your system.
-+
-+config EGLIBC_NSSWITCH_FIXED_FUNCTIONS
-+ string "Nsswitch fixed functions filename"
-+ depends on !EGLIBC_NSSWITCH
-+ default ""
-+ help
-+ The EGLIBC build process uses this file to decide which
-+ functions to make available from which service libraries.
-+ The file 'nss/fixed-nsswitch.functions' serves as a sample
-+ configuration file for this setting, and explains its syntax
-+ and meaning in more detail.
-+
-+ This should be an absolute file name. The EGLIBC build
-+ process may use it from several different working
-+ directories. It may include references to Makefile
-+ variables like 'common-objpfx' (the top of the build tree,
-+ with a trailing slash), or '..' (the top of the source tree,
-+ with a trailing slash).
-+
-+ Be sure to mention each function in each service you wish to
-+ use. If you do not mention a service's function here, the
-+ EGLIBC database access functions will not find it, even if
-+ it is listed in the EGLIBC_NSSWITCH_FIXED_CONFIG
-+ file.
-+
-+ In this arrangement, EGLIBC will not use the 'dlopen' and
-+ 'dlsym' functions to find database access functions. Instead,
-+ libc hard-codes references to the service libraries' database
-+ access functions. You must explicitly link your program
-+ against the name service libraries (those whose names start
-+ with 'libnss_', in the sysroot's '/lib' directory) whose
-+ functions you intend to use. This arrangement helps
-+ system-wide static analysis tools decide which functions a
-+ system actually uses.
-+
-+ Note that some nsswitch service libraries require other option
-+ groups to be enabled; for example, the EGLIBC_INET
-+ option group must be enabled to use the 'libnss_dns.so.2'
-+ service library, which uses the Domain Name System network
-+ protocol to answer queries.
-+
-+config EGLIBC_RCMD
-+ bool "Support for 'rcmd' and related library functions"
-+ depends on EGLIBC_INET
-+ help
-+ This option group includes functions for running commands on
-+ remote machines via the 'rsh' protocol, and doing authentication
-+ related to those functions. This also includes functions that
-+ use the 'rexec' protocol.
-+
-+ This option group includes the following functions:
-+
-+ rcmd ruserok
-+ rcmd_af ruserok_af
-+ rexec iruserok
-+ rexec_af iruserok_af
-+ rresvport ruserpass
-+ rresvport_af
-+
-+config EGLIBC_RTLD_DEBUG
-+ bool "Runtime linker debug print outs"
-+ help
-+ This option group enables debug output of the runtime linker
-+ which is activated via LD_DEBUG and LD_TRACE_PRELINKING
-+ environment variables. Disabling this option group yields
-+ a smaller runtime linker binary.
-+ BEWARE: Disabling this option group is likely to break
-+ the `ldd' utility which may also be used by the prelinker.
-+ In particular, the `--unused' ldd option will not work correctly.
-+
-+config EGLIBC_SPAWN
-+ bool "Support for POSIX posix_spawn functions"
-+ help
-+ This option group includes the POSIX functions for executing
-+ programs in child processes without using 'fork' or 'vfork'.
-+
-+ This option group includes the following functions:
-+
-+ posix_spawn
-+ posix_spawnattr_destroy
-+ posix_spawnattr_getflags
-+ posix_spawnattr_getpgroup
-+ posix_spawnattr_getschedparam
-+ posix_spawnattr_getschedpolicy
-+ posix_spawnattr_getsigdefault
-+ posix_spawnattr_getsigmask
-+ posix_spawnattr_init
-+ posix_spawnattr_setflags
-+ posix_spawnattr_setpgroup
-+ posix_spawnattr_setschedparam
-+ posix_spawnattr_setschedpolicy
-+ posix_spawnattr_setsigdefault
-+ posix_spawnattr_setsigmask
-+ posix_spawn_file_actions_addclose
-+ posix_spawn_file_actions_adddup2
-+ posix_spawn_file_actions_addopen
-+ posix_spawn_file_actions_destroy
-+ posix_spawn_file_actions_init
-+ posix_spawnp
-+
-+ This option group also provides the ability for the iconv,
-+ localedef, and locale programs to operate transparently on
-+ compressed charset definitions. When this option group is
-+ disabled, those programs will only operate on uncompressed
-+ charmap files.
-+
-+config EGLIBC_STREAMS
-+ bool "Support for accessing STREAMS."
-+ help
-+ This option group includes functions for reading and writing
-+ messages to and from STREAMS. The STREAMS interface provides a
-+ uniform mechanism for implementing networking services and other
-+ character-based I/O. (STREAMS are not to be confused with
-+ <stdio.h> FILE objects, also called 'streams'.)
-+
-+ This option group includes the following functions:
-+
-+ getmsg putpmsg
-+ getpmsg fattach
-+ isastream fdetach
-+ putmsg
-+
-+config EGLIBC_SUNRPC
-+ bool "Support for the Sun 'RPC' protocol."
-+ depends on EGLIBC_INET
-+ help
-+ This option group includes support for the Sun RPC protocols,
-+ including the 'rpcgen' and 'rpcinfo' programs.
-+
-+config EGLIBC_UTMP
-+ bool "Older access functions for 'utmp' login records"
-+ help
-+ This option group includes the older 'utent' family of
-+ functions for accessing user login records in the 'utmp' file.
-+ POSIX omits these functions in favor of the 'utxent' family,
-+ and they are obsolete on systems other than Linux.
-+
-+ This option group includes the following functions:
-+
-+ endutent
-+ getutent
-+ getutent_r
-+ getutid
-+ getutid_r
-+ getutline
-+ getutline_r
-+ logwtmp
-+ pututline
-+ setutent
-+ updwtmp
-+ utmpname
-+
-+ This option group includes the following libraries:
-+
-+ libutil.so (and libutil.a)
-+
-+config EGLIBC_UTMPX
-+ bool "POSIX access functions for 'utmp' login records"
-+ depends on EGLIBC_UTMP
-+ help
-+ This option group includes the POSIX functions for reading and
-+ writing user login records in the 'utmp' file (usually
-+ '/var/run/utmp'). The POSIX functions operate on 'struct
-+ utmpx' structures, as opposed to the family of older 'utent'
-+ functions, which operate on 'struct utmp' structures.
-+
-+ This option group includes the following functions:
-+
-+ endutxent
-+ getutmp
-+ getutmpx
-+ getutxent
-+ getutxid
-+ getutxline
-+ pututxline
-+ setutxent
-+ updwtmpx
-+ utmpxname
-+
-+config EGLIBC_WORDEXP
-+ bool "Shell-style word expansion"
-+ help
-+ This option group includes the 'wordexp' function for
-+ performing word expansion in the manner of the shell, and the
-+ accompanying 'wordfree' function.
-+
-+config POSIX_C_LANG_WIDE_CHAR
-+ bool "ISO C library wide character functions, excluding I/O"
-+ help
-+ This option group includes the functions defined by the ISO C
-+ standard for working with wide and multibyte characters in
-+ memory. Functions for reading and writing wide and multibyte
-+ characters from and to files call in the
-+ POSIX_WIDE_CHAR_DEVICE_IO option group.
-+
-+ This option group includes the following functions:
-+
-+ btowc mbsinit wcscspn wcstoll
-+ iswalnum mbsrtowcs wcsftime wcstombs
-+ iswalpha mbstowcs wcslen wcstoul
-+ iswblank mbtowc wcsncat wcstoull
-+ iswcntrl swprintf wcsncmp wcstoumax
-+ iswctype swscanf wcsncpy wcsxfrm
-+ iswdigit towctrans wcspbrk wctob
-+ iswgraph towlower wcsrchr wctomb
-+ iswlower towupper wcsrtombs wctrans
-+ iswprint vswprintf wcsspn wctype
-+ iswpunct vswscanf wcsstr wmemchr
-+ iswspace wcrtomb wcstod wmemcmp
-+ iswupper wcscat wcstof wmemcpy
-+ iswxdigit wcschr wcstoimax wmemmove
-+ mblen wcscmp wcstok wmemset
-+ mbrlen wcscoll wcstol
-+ mbrtowc wcscpy wcstold
-+
-+config POSIX_REGEXP
-+ bool "Regular expressions"
-+ help
-+ This option group includes the POSIX regular expression
-+ functions, and the associated non-POSIX extensions and
-+ compatibility functions.
-+
-+ With POSIX_REGEXP disabled, the following functions are
-+ omitted from libc:
-+
-+ re_comp re_max_failures regcomp
-+ re_compile_fastmap re_search regerror
-+ re_compile_pattern re_search_2 regexec
-+ re_exec re_set_registers regfree
-+ re_match re_set_syntax rpmatch
-+ re_match_2 re_syntax_options
-+
-+ Furthermore, the compatibility regexp interface defined in the
-+ <regexp.h> header file, 'compile', 'step', and 'advance', is
-+ omitted.
-+
-+config POSIX_REGEXP_GLIBC
-+ bool "Regular expressions from GLIBC"
-+ depends on POSIX_REGEXP
-+ help
-+ This option group specifies which regular expression
-+ library to use. The choice is between regex
-+ implementation from GLIBC and regex implementation from
-+ libiberty. The GLIBC variant is fully POSIX conformant and
-+ optimized for speed; regex from libiberty is more than twice
-+ as small while still is enough for most practical purposes.
-+
-+config POSIX_WIDE_CHAR_DEVICE_IO
-+ bool "Input and output functions for wide characters"
-+ depends on POSIX_C_LANG_WIDE_CHAR
-+ help
-+ This option group includes functions for reading and writing
-+ wide characters to and from <stdio.h> streams.
-+
-+ This option group includes the following functions:
-+
-+ fgetwc fwprintf putwchar vwscanf
-+ fgetws fwscanf ungetwc wprintf
-+ fputwc getwc vfwprintf wscanf
-+ fputws getwchar vfwscanf
-+ fwide putwc vwprintf
-+
-+ This option group further includes the following unlocked
-+ variants of the above functions:
-+
-+ fgetwc_unlocked getwc_unlocked
-+ fgetws_unlocked getwchar_unlocked
-+ fputwc_unlocked putwc_unlocked
-+ fputws_unlocked putwchar_unlocked
-+
-+ Note that the GNU standard C++ library, 'libstdc++.so', uses
-+ some of these functions; you will not be able to link or run
-+ C++ programs if you disable this option group.
-+
-+ This option group also affects the behavior of the following
-+ functions:
-+
-+ fdopen
-+ fopen
-+ fopen64
-+ freopen
-+ freopen64
-+
-+ These functions all take an OPENTYPE parameter which may
-+ contain a string of the form ",ccs=CHARSET", indicating that
-+ the underlying file uses the character set named CHARSET.
-+ This produces a wide-oriented stream, which is only useful
-+ when the functions included in this option group are present.
-+ If the user attempts to open a file specifying a character set
-+ in the OPENTYPE parameter, and EGLIBC was built with this
-+ option group disabled, the function returns NULL, and sets
-+ errno to EINVAL.
-+
-+
-+# This helps Emacs users browse this file using the page motion commands
-+# and commands like 'pages-directory'.
-+# Local Variables:
-+# page-delimiter: "^config\\s-"
-+# End:
-diff --git a/option-groups.defaults b/option-groups.defaults
-new file mode 100644
-index 0000000..8141201
---- /dev/null
-+++ b/option-groups.defaults
-@@ -0,0 +1,47 @@
-+# This file sets default values for all option group variables
-+# mentioned in option-groups.def; see that file for a description of
-+# each option group.
-+#
-+# Subdirectory makefiles include this file before including the user's
-+# settings from option-groups.config at the top of the build tree;
-+# that file need only refer to those options whose default settings
-+# are to be changed.
-+#
-+# By default, all option groups are enabled.
-+OPTION_EGLIBC_ADVANCED_INET6 = y
-+OPTION_EGLIBC_BACKTRACE = y
-+OPTION_EGLIBC_BIG_MACROS = y
-+OPTION_EGLIBC_BSD = y
-+OPTION_EGLIBC_CXX_TESTS = y
-+OPTION_EGLIBC_CATGETS = y
-+OPTION_EGLIBC_CHARSETS = y
-+OPTION_EGLIBC_CRYPT = y
-+OPTION_EGLIBC_CRYPT_UFC = y
-+OPTION_EGLIBC_DB_ALIASES = y
-+OPTION_EGLIBC_ENVZ = y
-+OPTION_EGLIBC_FCVT = y
-+OPTION_EGLIBC_FMTMSG = y
-+OPTION_EGLIBC_FSTAB = y
-+OPTION_EGLIBC_FTRAVERSE = y
-+OPTION_EGLIBC_GETLOGIN = y
-+OPTION_EGLIBC_IDN = y
-+OPTION_EGLIBC_INET = y
-+OPTION_EGLIBC_INET_ANL = y
-+OPTION_EGLIBC_LIBM = y
-+OPTION_EGLIBC_LOCALES = y
-+OPTION_EGLIBC_LOCALE_CODE = y
-+OPTION_EGLIBC_MEMUSAGE = y
-+OPTION_EGLIBC_NIS = y
-+OPTION_EGLIBC_NSSWITCH = y
-+OPTION_EGLIBC_RCMD = y
-+OPTION_EGLIBC_RTLD_DEBUG = y
-+OPTION_EGLIBC_SPAWN = y
-+OPTION_EGLIBC_STREAMS = y
-+OPTION_EGLIBC_SUNRPC = y
-+OPTION_EGLIBC_UTMP = y
-+OPTION_EGLIBC_UTMPX = y
-+OPTION_EGLIBC_WORDEXP = y
-+OPTION_POSIX_C_LANG_WIDE_CHAR = y
-+OPTION_POSIX_REGEXP = y
-+OPTION_POSIX_REGEXP_GLIBC = y
-+OPTION_POSIX_WIDE_CHAR_DEVICE_IO = y
-diff --git a/option-groups.mak b/option-groups.mak
-new file mode 100644
-index 0000000..f83e0c1
---- /dev/null
-+++ b/option-groups.mak
-@@ -0,0 +1,41 @@
-+# Setup file for subdirectory Makefiles that define EGLIBC option groups.
-+
-+# EGLIBC shouldn't need to override this. However, the
-+# cross-build-friendly localedef includes this makefile to get option
-+# group variable definitions; it uses a single build tree for all the
-+# multilibs, and needs to be able to specify a different option group
-+# configuration file for each multilib.
-+option_group_config_file ?= $(objdir)/option-groups.config
-+
-+# Read the default settings for all options.
-+# We're included before ../Rules, so we can't assume $(..) is set.
-+include $(firstword $(..) ../)option-groups.defaults
-+
-+# Read the developer's option group selections, overriding the
-+# defaults from option-groups.defaults.
-+-include $(option_group_config_file)
-+
-+# $(call option-disabled, VAR) is 'y' if VAR is not 'y', or 'n' otherwise.
-+# VAR should be a variable name, not a variable reference; this is
-+# less general, but more terse for the intended use.
-+# You can use it to add a file to a list if an option group is
-+# disabled, like this:
-+# routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) += ...
-+define option-disabled
-+$(firstword $(subst y,n,$(filter y,$($(strip $(1))))) y)
-+endef
-+
-+# Establish 'routines-y', etc. as simply-expanded variables.
-+aux-y :=
-+extra-libs-others-y :=
-+extra-libs-y :=
-+extra-objs-y :=
-+install-bin-y :=
-+install-others-y :=
-+install-sbin-y :=
-+others-y :=
-+others-pie-y :=
-+routines-y :=
-+test-srcs-y :=
-+tests-y :=
-+xtests-y :=
-diff --git a/options-config/Makefile b/options-config/Makefile
-new file mode 100644
-index 0000000..db00708
---- /dev/null
-+++ b/options-config/Makefile
-@@ -0,0 +1,55 @@
-+# ===========================================================================
-+# EGLIBC option-groups configuration targets
-+# These targets are included from top-level makefile
-+
-+ifneq ($(kconfig_tools),)
-+ifneq (no,$(PERL))
-+
-+ocdir := options-config
-+
-+OconfigDefaults := option-groups.defaults
-+OconfigDefaults_tmp := $(common-objpfx).tmp.defconfig
-+OconfigDef := option-groups.def
-+Oconfig := $(common-objpfx)option-groups.config
-+Oconfig_tmp := $(common-objpfx).tmp.config
-+
-+conf := $(kconfig_tools)/conf
-+mconf := $(kconfig_tools)/mconf
-+
-+preproc := $(PERL) $(ocdir)/config-preproc.pl
-+postproc := $(PERL) $(ocdir)/config-postproc.pl
-+
-+PHONY += defconfig config menuconfig
-+
-+defconfig: $(conf) $(OconfigDefaults) $(OconfigDef)
-+ rm -f $(OconfigDefaults_tmp)
-+ rm -f $(Oconfig_tmp)
-+ $(preproc) $(OconfigDefaults) > $(OconfigDefaults_tmp)
-+ KCONFIG_CONFIG=$(Oconfig_tmp) $< --defconfig=$(OconfigDefaults_tmp) \
-+ $(OconfigDef)
-+ $(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
-+ rm $(Oconfig_tmp)
-+ rm $(OconfigDefaults_tmp)
-+
-+config: $(conf) $(OconfigDefaults) $(OconfigDef)
-+ rm -f $(Oconfig_tmp)
-+ $(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
-+ KCONFIG_CONFIG=$(Oconfig_tmp) $< --oldaskconfig $(OconfigDef)
-+ $(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
-+ rm $(Oconfig_tmp)
-+
-+menuconfig: $(mconf) $(OconfigDefaults) $(OconfigDef)
-+ rm -f $(Oconfig_tmp)
-+ $(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
-+ KCONFIG_CONFIG=$(Oconfig_tmp) $< $(OconfigDef)
-+ $(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
-+ rm $(Oconfig_tmp)
-+
-+# Help text used by make help
-+help:
-+ @echo ' defconfig - New config with default from default config'
-+ @echo ' config - Update current config utilising a line-oriented program'
-+ @echo ' menuconfig - Update current config utilising a menu based program'
-+
-+endif
-+endif
-diff --git a/options-config/config-postproc.pl b/options-config/config-postproc.pl
-new file mode 100644
-index 0000000..4dd1c63
---- /dev/null
-+++ b/options-config/config-postproc.pl
-@@ -0,0 +1,58 @@
-+#!/usr/bin/perl
-+
-+$usage = "usage: $0 <default config file> <config file>\n";
-+
-+die "$usage" unless @ARGV;
-+$defaults = shift @ARGV;
-+die "$usage" unless @ARGV;
-+die "Could not open $ARGV[0]" unless -T $ARGV[0];
-+
-+sub yank {
-+ @option = grep(!($_ =~ /$_[0]\s*=/), @option);
-+}
-+
-+open(DEFAULTS, $defaults) || die "Could not open $defaults\n";
-+
-+# get the full list of available options using the default config file
-+$i = 0;
-+while (<DEFAULTS>) {
-+ if (/^\s*OPTION_(\w+\s*=.*$)/) {
-+ $option[$i++] = $1;
-+ }
-+}
-+
-+# now go through the config file, making the necessary changes
-+while (<>) {
-+ if (/Linux Kernel Configuration/) {
-+ # change title
-+ s/Linux Kernel/Option Groups/;
-+ print;
-+ } elsif (/^\s*CONFIG_(\w+)\s*=/) {
-+ # this is an explicit option set line, change CONFIG_ to OPTION_
-+ # before printing and remove this option from option list
-+ $opt = $1;
-+ yank($opt);
-+ s/CONFIG_/OPTION_/g;
-+ print;
-+ } elsif (/^\s*#\s+CONFIG_(\w+) is not set/) {
-+ # this is a comment line for an unset boolean option, change CONFIG_
-+ # to OPTION_, remove this option from option list, and convert to
-+ # explicit OPTION_FOO=n
-+ $opt = $1;
-+ yank($opt);
-+ s/CONFIG_/OPTION_/g;
-+ print "OPTION_$opt=n\n";
-+ } else {
-+ print;
-+ }
-+}
-+
-+# any boolean options left in @options, are options that were not mentioned in
-+# the config file, and implicitly that means the option must be set =n,
-+# so do that here.
-+foreach $opt (@option) {
-+ if ($opt =~ /=\s*[yn]/) {
-+ $opt =~ s/=\s*[yn]/=n/;
-+ print "OPTION_$opt\n";
-+ }
-+}
-diff --git a/options-config/config-preproc.pl b/options-config/config-preproc.pl
-new file mode 100644
-index 0000000..b83bb85
---- /dev/null
-+++ b/options-config/config-preproc.pl
-@@ -0,0 +1,8 @@
-+#!/usr/bin/perl
-+
-+if (@ARGV) {
-+ while (<>) {
-+ s/OPTION_/CONFIG_/g;
-+ print;
-+ }
-+}
-diff --git a/scripts/option-groups.awk b/scripts/option-groups.awk
-new file mode 100644
-index 0000000..533af0c
---- /dev/null
-+++ b/scripts/option-groups.awk
-@@ -0,0 +1,63 @@
-+# option-groups.awk --- generate option group header file
-+# Given input files containing makefile-style assignments to variables,
-+# print out a header file that #defines an appropriate preprocessor
-+# symbol for each variable left set to 'y'.
-+
-+BEGIN { FS="=" }
-+
-+# Trim spaces.
-+{ gsub (/[[:blank:]]/, "") }
-+
-+# Skip comments.
-+/^#/ { next }
-+
-+# Process assignments.
-+NF == 2 {
-+ vars[$1] = $2
-+}
-+
-+# Print final values.
-+END {
-+ print "/* This file is automatically generated by scripts/option-groups.awk"
-+ print " in the EGLIBC source tree."
-+ print ""
-+ print " It defines macros that indicate which EGLIBC option groups were"
-+ print " configured in 'option-groups.config' when this C library was"
-+ print " built. For each option group named OPTION_foo, it #defines"
-+ print " __OPTION_foo to be 1 if the group is enabled, or #defines that"
-+ print " symbol to be 0 if the group is disabled. */"
-+ print ""
-+ print "#ifndef __GNU_OPTION_GROUPS_H"
-+ print "#define __GNU_OPTION_GROUPS_H"
-+ print ""
-+
-+ # Produce a sorted list of variable names.
-+ i=0
-+ for (var in vars)
-+ names[i++] = var
-+ n = asort (names)
-+
-+ for (i = 1; i <= n; i++)
-+ {
-+ var = names[i]
-+ if (var ~ /^OPTION_/)
-+ {
-+ if (vars[var] == "y")
-+ print "#define __" var " 1"
-+ else if (vars[var] == "n")
-+ print "#define __" var " 0"
-+ else if (vars[var] ~ /^[0-9]+/ ||
-+ vars[var] ~ /^0x[0-9aAbBcCdDeEfF]+/ ||
-+ vars[var] ~ /^\"/)
-+ print "#define __" var " " vars[var]
-+ else
-+ print "/* #undef __" var " */"
-+ # Ignore variables that don't have boolean, int, hex, or
-+ # string values. Ideally, this would be driven by the types
-+ # given in option-groups.def.
-+ }
-+ }
-+
-+ print ""
-+ print "#endif /* __GNU_OPTION_GROUPS_H */"
-+}
---
-2.1.4
-
diff --git a/meta/recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch b/meta/recipes-core/glibc/glibc/0019-eglibc-Help-bootstrap-cross-toolchain.patch
index df93094543..c04e0a11d4 100644
--- a/meta/recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch
+++ b/meta/recipes-core/glibc/glibc/0019-eglibc-Help-bootstrap-cross-toolchain.patch
@@ -1,7 +1,7 @@
-From 8fe0d29488b376011cdaaa462d557ffc0b31fb63 Mon Sep 17 00:00:00 2001
+From c2d49eab20db4ab02b6de62092fedc623d757146 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:49:28 +0000
-Subject: [PATCH 20/27] eglibc: Help bootstrap cross toolchain
+Subject: [PATCH 19/24] eglibc: Help bootstrap cross toolchain
Taken from EGLIBC, r1484 + r1525
@@ -29,7 +29,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
create mode 100644 include/stubs-bootstrap.h
diff --git a/Makefile b/Makefile
-index f906391..e4e149e 100644
+index 9a01c93..a6ae003 100644
--- a/Makefile
+++ b/Makefile
@@ -69,9 +69,18 @@ subdir-dirs = include
@@ -96,5 +96,5 @@ index 0000000..1d2b669
+ EGLIBC subdir 'stubs' make targets, on every .o file in EGLIBC, but
+ an empty stubs.h like this will do fine for GCC. */
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch b/meta/recipes-core/glibc/glibc/0020-eglibc-cherry-picked-from.patch
index 38bb8a15e3..4362efae77 100644
--- a/meta/recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch
+++ b/meta/recipes-core/glibc/glibc/0020-eglibc-cherry-picked-from.patch
@@ -1,30 +1,32 @@
-From fe2ae4f877928dd6bff5bac3f15bce4b50d2bd12 Mon Sep 17 00:00:00 2001
+From 588d936b9aa65e7cc8b1eb2cad1d209087db43a9 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
-Date: Wed, 18 Mar 2015 00:51:16 +0000
-Subject: [PATCH 21/27] eglibc: cherry-picked from
- http://www.eglibc.org/archives/patches/msg00772.html
+Date: Thu, 31 Dec 2015 15:10:33 -0800
+Subject: [PATCH 20/24] eglibc: cherry-picked from
-It hasn't yet been merged into glibc
+http://www.eglibc.org/archives/patches/msg00772.html
+
+Not yet merged into glibc
Upstream-Status: Pending
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
- resolv/res_libc.c | 15 +++++++++++++--
- 1 file changed, 13 insertions(+), 2 deletions(-)
+ resolv/res_libc.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/resolv/res_libc.c b/resolv/res_libc.c
-index ee3fa21..29e2340 100644
+index a8394e0..981ac7c 100644
--- a/resolv/res_libc.c
+++ b/resolv/res_libc.c
-@@ -22,12 +22,13 @@
+@@ -18,6 +18,7 @@
+ #include <atomic.h>
+ #include <limits.h>
+ #include <sys/types.h>
++#include <sys/stat.h>
+ #include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
- #include <bits/libc-lock.h>
--
-+#include <sys/stat.h>
-
- /* The following bit is copied from res_data.c (where it is #ifdef'ed
+@@ -28,6 +29,7 @@
out) since res_init() should go into libc.so but the rest of that
file should not. */
@@ -32,7 +34,7 @@ index ee3fa21..29e2340 100644
extern unsigned long long int __res_initstamp attribute_hidden;
/* We have atomic increment operations on 64-bit platforms. */
#if __WORDSIZE == 64
-@@ -35,7 +36,6 @@ extern unsigned long long int __res_initstamp attribute_hidden;
+@@ -35,7 +37,6 @@ extern unsigned long long int __res_initstamp attribute_hidden;
# define atomicincunlock(lock) (void) 0
# define atomicinc(var) catomic_increment (&(var))
#else
@@ -40,7 +42,7 @@ index ee3fa21..29e2340 100644
# define atomicinclock(lock) __libc_lock_lock (lock)
# define atomicincunlock(lock) __libc_lock_unlock (lock)
# define atomicinc(var) ++var
-@@ -94,7 +94,18 @@ res_init(void) {
+@@ -94,7 +95,18 @@ res_init(void) {
int
__res_maybe_init (res_state resp, int preinit)
{
@@ -60,5 +62,5 @@ index ee3fa21..29e2340 100644
if (resp->nscount > 0)
__res_iclose (resp, true);
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch b/meta/recipes-core/glibc/glibc/0021-eglibc-Clear-cache-lines-on-ppc8xx.patch
index 8a4c9c3e89..225f22f013 100644
--- a/meta/recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch
+++ b/meta/recipes-core/glibc/glibc/0021-eglibc-Clear-cache-lines-on-ppc8xx.patch
@@ -1,7 +1,7 @@
-From be7273225698074347a71de58006977bb304d7f7 Mon Sep 17 00:00:00 2001
+From b74e34e6f53816ad57b13ba6fd70a97db1bc1eae Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
-Date: Wed, 18 Mar 2015 00:53:47 +0000
-Subject: [PATCH 22/27] eglibc: Clear cache lines on ppc8xx
+Date: Thu, 31 Dec 2015 15:15:09 -0800
+Subject: [PATCH 21/24] eglibc: Clear cache lines on ppc8xx
2007-06-13 Nathan Sidwell <nathan@codesourcery.com>
Mark Shinwell <shinwell@codesourcery.com>
@@ -13,11 +13,12 @@ Subject: [PATCH 22/27] eglibc: Clear cache lines on ppc8xx
(DL_PLATFORM_AUXV): Likewise.
Upstream-Status: Pending
+
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c | 14 +++++++++++++-
- sysdeps/unix/sysv/linux/powerpc/libc-start.c | 15 ++++++++++++++-
- 2 files changed, 27 insertions(+), 2 deletions(-)
+ sysdeps/unix/sysv/linux/powerpc/libc-start.c | 16 +++++++++++++++-
+ 2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
index c2504ff..d50f1cb 100644
@@ -47,15 +48,16 @@ index c2504ff..d50f1cb 100644
break;
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
-index a9364c7..a3ed1d4 100644
+index 209a16d..5d8572d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
-@@ -68,11 +68,24 @@ __libc_start_main (int argc, char **argv,
- rtld_fini = NULL;
- }
+@@ -73,11 +73,25 @@ __libc_start_main (int argc, char **argv,
-- /* Initialize the __cache_line_size variable from the aux vector. */
-+ /* Initialize the __cache_line_size variable from the aux vector.
+ /* Initialize the __cache_line_size variable from the aux vector. For the
+ static case, we also need _dl_hwcap, _dl_hwcap2 and _dl_platform, so we
+- can call __tcb_parse_hwcap_and_convert_at_platform (). */
++ can call __tcb_parse_hwcap_and_convert_at_platform ().
++
+ This is used by memset to optimize setting to zero. We have to
+ detect 8xx processors, which have buggy dcbz implementations that
+ cannot report page faults correctly. That requires reading SPR,
@@ -75,7 +77,7 @@ index a9364c7..a3ed1d4 100644
+ }
__cache_line_size = av->a_un.a_val;
break;
- }
+ #ifndef SHARED
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch b/meta/recipes-core/glibc/glibc/0022-eglibc-Resolve-__fpscr_values-on-SH4.patch
index 9f3d753d70..88b20f67ad 100644
--- a/meta/recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch
+++ b/meta/recipes-core/glibc/glibc/0022-eglibc-Resolve-__fpscr_values-on-SH4.patch
@@ -1,7 +1,7 @@
-From 718e7e5db1c8b073adb9a79ec6f167238c2d8bda Mon Sep 17 00:00:00 2001
+From 8f483cb1f21ab6431ff99e8d30d56b91607ae918 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 00:55:53 +0000
-Subject: [PATCH 23/27] eglibc: Resolve __fpscr_values on SH4
+Subject: [PATCH 22/24] eglibc: Resolve __fpscr_values on SH4
2010-09-29 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Andrew Stubbs <ams@codesourcery.com>
@@ -52,5 +52,5 @@ index a02b7e2..b9be326 100644
+weak_alias (___fpscr_values, __fpscr_values)
+
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch b/meta/recipes-core/glibc/glibc/0023-eglibc-Install-PIC-archives.patch
index c359cce9c5..d95ea3ba3d 100644
--- a/meta/recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch
+++ b/meta/recipes-core/glibc/glibc/0023-eglibc-Install-PIC-archives.patch
@@ -1,7 +1,7 @@
-From 5773417fa91a18cd39fb35c9907d72af0ed9ea33 Mon Sep 17 00:00:00 2001
+From 58d424884eed7efde6c90af0cd7c6c37cf9b444a Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 18 Mar 2015 01:57:01 +0000
-Subject: [PATCH 25/27] eglibc: Install PIC archives
+Subject: [PATCH 23/24] eglibc: Install PIC archives
Forward port from eglibc
@@ -29,10 +29,10 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
1 file changed, 40 insertions(+), 2 deletions(-)
diff --git a/Makerules b/Makerules
-index 1dd41aa..41778e1 100644
+index fa24030..1ff4634 100644
--- a/Makerules
+++ b/Makerules
-@@ -713,6 +713,9 @@ ifeq ($(build-shared),yes)
+@@ -694,6 +694,9 @@ ifeq ($(build-shared),yes)
$(common-objpfx)libc.so: $(common-objpfx)libc.map
endif
common-generated += libc.so libc_pic.os
@@ -42,7 +42,7 @@ index 1dd41aa..41778e1 100644
ifdef libc.so-version
$(common-objpfx)libc.so$(libc.so-version): $(common-objpfx)libc.so
$(make-link)
-@@ -955,6 +958,7 @@ endif
+@@ -936,6 +939,7 @@ endif
install: check-install-supported
@@ -50,7 +50,7 @@ index 1dd41aa..41778e1 100644
install: $(installed-libcs)
$(installed-libcs): $(inst_libdir)/lib$(libprefix)%: lib $(+force)
$(make-target-directory)
-@@ -983,6 +987,22 @@ versioned := $(strip $(foreach so,$(install-lib.so),\
+@@ -964,6 +968,22 @@ versioned := $(strip $(foreach so,$(install-lib.so),\
install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
@@ -73,7 +73,7 @@ index 1dd41aa..41778e1 100644
# For versioned libraries, we install three files:
# $(inst_libdir)/libfoo.so -- for linking, symlink or ld script
# $(inst_slibdir)/libfoo.so.NN -- for loading by SONAME, symlink
-@@ -1225,9 +1245,22 @@ $(addprefix $(inst_includedir)/,$(headers-nonh)): $(inst_includedir)/%: \
+@@ -1206,9 +1226,22 @@ $(addprefix $(inst_includedir)/,$(headers-nonh)): $(inst_includedir)/%: \
endif # headers-nonh
endif # headers
@@ -97,7 +97,7 @@ index 1dd41aa..41778e1 100644
install-bin-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin))
install-bin-script-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin-script))
install-rootsbin-nosubdir: \
-@@ -1240,6 +1273,10 @@ install-data-nosubdir: $(addprefix $(inst_datadir)/,$(install-data))
+@@ -1221,6 +1254,10 @@ install-data-nosubdir: $(addprefix $(inst_datadir)/,$(install-data))
install-headers-nosubdir: $(addprefix $(inst_includedir)/,$(headers))
install-others-nosubdir: $(install-others)
install-others-programs-nosubdir: $(install-others-programs)
@@ -108,7 +108,7 @@ index 1dd41aa..41778e1 100644
# We need all the `-nosubdir' targets so that `install' in the parent
# doesn't depend on several things which each iterate over the subdirs.
-@@ -1249,7 +1286,8 @@ install-%:: install-%-nosubdir ;
+@@ -1230,7 +1267,8 @@ install-%:: install-%-nosubdir ;
.PHONY: install install-no-libc.a-nosubdir
install-no-libc.a-nosubdir: install-headers-nosubdir install-data-nosubdir \
@@ -119,5 +119,5 @@ index 1dd41aa..41778e1 100644
install-no-libc.a-nosubdir: install-bin-nosubdir install-bin-script-nosubdir \
install-rootsbin-nosubdir install-sbin-nosubdir \
--
-2.1.4
+2.6.4
diff --git a/meta/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch b/meta/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch
deleted file mode 100644
index 0514e282e6..0000000000
--- a/meta/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch
+++ /dev/null
@@ -1,16842 +0,0 @@
-From 2a5d7bcf0ff791c95ee1388772408a1bf4454694 Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Wed, 18 Mar 2015 01:33:49 +0000
-Subject: [PATCH 24/27] eglibc: Forward port eglibc options groups support
-
-Upstream-Status: Pending
-
-Signed-off-by: Khem Raj <raj.khem@gmail.com>
----
- Makeconfig | 20 +-
- Makerules | 19 +
- argp/Makefile | 2 +
- argp/argp-fmtstream.c | 25 +-
- argp/argp-help.c | 13 +-
- argp/argp-namefrob.h | 2 +
- catgets/Makefile | 17 +-
- crypt/Makefile | 20 +-
- crypt/crypt-entry.c | 13 +
- crypt/crypt_common.c | 42 +
- crypt/crypt_util.c | 18 -
- csu/Makefile | 2 +
- debug/Makefile | 41 +-
- debug/segfault.c | 11 +-
- debug/tst-chk1.c | 7 +
- dlfcn/Makefile | 7 +-
- elf/dl-support.c | 3 +
- elf/rtld.c | 17 +-
- extra-lib.mk | 6 +-
- grp/Makefile | 5 +
- hesiod/Makefile | 6 +-
- iconv/Makefile | 7 +
- iconv/gconv_db.c | 3 +
- iconv/gconv_trans.c | 7 +
- iconv/iconv_prog.c | 8 +
- iconvdata/Makefile | 27 +-
- include/netdb.h | 4 +
- inet/Makefile | 22 +-
- intl/Makefile | 3 +-
- intl/dcigettext.c | 39 +-
- io/Makefile | 18 +-
- libidn/Makefile | 5 +-
- libidn/toutf8.c | 11 +-
- libio/Makefile | 66 +-
- libio/__fpurge.c | 2 +-
- libio/fileops.c | 10 +-
- libio/iofwide.c | 26 +
- libio/ioseekoff.c | 2 +-
- libio/ioseekpos.c | 2 +-
- libio/iosetbuffer.c | 4 +
- libio/libioP.h | 18 +-
- libio/wdummyfileops.c | 161 +
- locale/C-ctype.c | 20 +
- locale/Makefile | 41 +-
- locale/catnames.c | 48 +
- locale/dummy-setlocale.c | 33 +
- locale/localeinfo.h | 2 +-
- locale/programs/charmap-dir.c | 6 +
- locale/programs/ld-collate.c | 17 +-
- locale/programs/ld-ctype.c | 27 +-
- locale/programs/ld-messages.c | 5 +
- locale/programs/ld-time.c | 31 +-
- locale/programs/linereader.c | 2 +-
- locale/programs/localedef.c | 8 +
- locale/programs/locfile.c | 5 +-
- locale/programs/locfile.h | 59 +-
- locale/setlocale.c | 30 -
- locale/xlocale.c | 37 +
- localedata/Makefile | 35 +-
- login/Makefile | 17 +-
- malloc/Makefile | 10 +-
- malloc/memusage.c | 7 +-
- malloc/memusage.sh | 2 +-
- math/Makefile | 6 +-
- misc/Makefile | 25 +-
- misc/err.c | 11 +
- misc/error.c | 5 +
- misc/tst-efgcvt.c | 2 +-
- nis/Makefile | 31 +-
- nptl/Makefile | 28 +-
- nptl/pthread_create.c | 5 +
- nscd/Makefile | 33 +-
- nscd/nis_hash.c | 3 +
- nss/Makefile | 67 +-
- nss/fixed-nsswitch.conf | 22 +
- nss/fixed-nsswitch.functions | 121 +
- nss/gen-fixed-nsswitch.c | 803 +++
- nss/getent.c | 46 +-
- nss/getnssent_r.c | 9 +-
- nss/nsswitch.c | 109 +-
- nss/nsswitch.h | 18 +-
- posix/Makefile | 94 +-
- posix/bug-regex1.c | 3 +
- posix/bug-regex6.c | 8 +-
- posix/fnmatch.c | 6 +-
- posix/fnmatch_loop.c | 23 +-
- posix/glob.c | 15 +-
- posix/regcomp.c | 98 +-
- posix/regex.h | 11 +
- posix/regex_internal.c | 45 +-
- posix/regex_internal.h | 23 +-
- posix/regexec-compat.c | 39 +
- posix/regexec.c | 71 +-
- posix/xregex.c | 8215 +++++++++++++++++++++++++++++++
- pwd/Makefile | 2 +
- resolv/Makefile | 21 +-
- stdio-common/Makefile | 35 +-
- stdio-common/_i18n_number.h | 13 +
- stdio-common/fxprintf.c | 5 +
- stdio-common/printf_fp.c | 22 +
- stdio-common/printf_fphex.c | 13 +
- stdio-common/printf_size.c | 8 +
- stdio-common/scanf14.c | 3 +
- stdio-common/tst-popen.c | 3 +
- stdio-common/tst-sprintf.c | 4 +-
- stdio-common/tstdiomisc.c | 5 +
- stdio-common/vfprintf.c | 31 +-
- stdio-common/vfscanf.c | 53 +-
- stdlib/Makefile | 34 +-
- stdlib/strtod_l.c | 13 +
- stdlib/tst-strtod.c | 5 +
- streams/Makefile | 5 +-
- string/Makefile | 14 +-
- string/strcoll_l.c | 5 +
- string/strerror_l.c | 5 +
- string/strxfrm_l.c | 5 +
- string/test-strcmp.c | 28 -
- string/tst-strxfrm.c | 3 +
- string/tst-strxfrm2.c | 3 +
- sunrpc/Makefile | 44 +-
- sysdeps/arm/Makefile | 5 +-
- sysdeps/generic/ldsodefs.h | 8 +
- sysdeps/gnu/Makefile | 3 +-
- sysdeps/ieee754/ldbl-opt/Makefile | 27 +-
- sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 40 +-
- sysdeps/ieee754/ldbl-opt/nldbl-compat.h | 24 +-
- sysdeps/nptl/Makefile | 3 +
- sysdeps/nptl/bits/libc-lock.h | 45 +
- sysdeps/nptl/bits/libc-lockP.h | 50 +-
- sysdeps/nptl/small-macros-fns.c | 72 +
- sysdeps/unix/sysv/linux/gethostid.c | 6 +
- sysdeps/unix/sysv/linux/libc_fatal.c | 3 +
- time/Makefile | 18 +-
- time/strftime_l.c | 12 +-
- time/strptime_l.c | 14 +-
- timezone/Makefile | 2 +-
- wcsmbs/Makefile | 27 +-
- wcsmbs/wcsmbsload.c | 13 +
- wctype/Makefile | 14 +-
- 139 files changed, 11363 insertions(+), 583 deletions(-)
- create mode 100644 crypt/crypt_common.c
- create mode 100644 libio/wdummyfileops.c
- create mode 100644 locale/catnames.c
- create mode 100644 locale/dummy-setlocale.c
- create mode 100644 nscd/nis_hash.c
- create mode 100644 nss/fixed-nsswitch.conf
- create mode 100644 nss/fixed-nsswitch.functions
- create mode 100644 nss/gen-fixed-nsswitch.c
- create mode 100644 posix/regexec-compat.c
- create mode 100644 posix/xregex.c
- create mode 100644 sysdeps/nptl/small-macros-fns.c
-
-diff --git a/Makeconfig b/Makeconfig
-index f136b88..52dae8f 100644
---- a/Makeconfig
-+++ b/Makeconfig
-@@ -609,7 +609,7 @@ elf-objpfx = $(common-objpfx)elf/
- # and run on the build system, causes that program with those
- # arguments to be run on the host for which the library is built.
- ifndef test-wrapper
--test-wrapper =
-+test-wrapper = $(cross-test-wrapper)
- endif
- # Likewise, but the name of the program is preceded by
- # <variable>=<value> assignments for environment variables.
-@@ -1089,6 +1089,24 @@ libm = $(common-objpfx)math/libm.a
- libmvec = $(common-objpfx)mathvec/libmvec.a
- endif
-
-+# Generate a header file that #defines preprocessor symbols indicating
-+# which option groups are enabled. Note that the option-groups.config file
-+# may not exist at all.
-+before-compile += $(common-objpfx)gnu/option-groups.h
-+common-generated += gnu/option-groups.h gnu/option-groups.stmp
-+headers += gnu/option-groups.h
-+$(common-objpfx)gnu/option-groups.h: $(common-objpfx)gnu/option-groups.stmp; @:
-+$(common-objpfx)gnu/option-groups.stmp: \
-+ $(..)scripts/option-groups.awk \
-+ $(..)option-groups.defaults \
-+ $(wildcard $(common-objpfx)option-groups.config)
-+ $(make-target-directory)
-+ @rm -f ${@:stmp=T} $@
-+ LC_ALL=C $(AWK) -f $^ > ${@:stmp=T}
-+ $(move-if-change) ${@:stmp=T} ${@:stmp=h}
-+ touch $@
-+
-+
- # These are the subdirectories containing the library source. The order
- # is more or less arbitrary. The sorting step will take care of the
- # dependencies.
-diff --git a/Makerules b/Makerules
-index f9ca3f5..1dd41aa 100644
---- a/Makerules
-+++ b/Makerules
-@@ -456,6 +456,25 @@ define sed-remove-objpfx
- endef
- endif
-
-+# Include targets in the selected option groups.
-+aux += $(aux-y)
-+extra-libs += $(extra-libs-y)
-+extra-libs-others += $(extra-libs-others-y)
-+extra-objs += $(extra-objs-y)
-+install-bin += $(install-bin-y)
-+install-others += $(install-others-y)
-+install-sbin += $(install-sbin-y)
-+modules += $(modules-y)
-+others += $(others-y)
-+others-pie += $(others-pie-y)
-+routines += $(routines-y)
-+static-only-routines += $(static-only-routines-y)
-+sysdep_routines += $(sysdep_routines-y)
-+test-srcs += $(test-srcs-y)
-+tests += $(tests-y)
-+xtests += $(xtests-y)
-+
-+
- # Modify the list of routines we build for different targets
-
- ifeq (yes,$(build-shared))
-diff --git a/argp/Makefile b/argp/Makefile
-index 1a87629..f7c1e40 100644
---- a/argp/Makefile
-+++ b/argp/Makefile
-@@ -18,6 +18,8 @@
- #
- # Makefile for argp.
- #
-+include ../option-groups.mak
-+
- subdir := argp
-
- include ../Makeconfig
-diff --git a/argp/argp-fmtstream.c b/argp/argp-fmtstream.c
-index 2b845e0..c344e7b 100644
---- a/argp/argp-fmtstream.c
-+++ b/argp/argp-fmtstream.c
-@@ -42,6 +42,7 @@
- #ifdef _LIBC
- # include <wchar.h>
- # include <libio/libioP.h>
-+# include <gnu/option-groups.h>
- # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
- #endif
-
-@@ -100,7 +101,11 @@ __argp_fmtstream_free (argp_fmtstream_t fs)
- __argp_fmtstream_update (fs);
- if (fs->p > fs->buf)
- {
-+#ifdef _LIBC
- __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);
-@@ -145,9 +150,17 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
- size_t i;
- for (i = 0; i < pad; i++)
- {
-+#ifdef _LIBC
- if (_IO_fwide (fs->stream, 0) > 0)
-- putwc_unlocked (L' ', fs->stream);
-+ {
-+#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
-+ putwc_unlocked (L' ', fs->stream);
-+#else
-+ abort ();
-+#endif
-+ }
- else
-+#endif
- putc_unlocked (' ', fs->stream);
- }
- }
-@@ -308,9 +321,17 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
- *nl++ = ' ';
- else
- for (i = 0; i < fs->wmargin; ++i)
-+#ifdef _LIBC
- if (_IO_fwide (fs->stream, 0) > 0)
-- putwc_unlocked (L' ', fs->stream);
-+ {
-+#ifdef OPTION_POSIX_WIDE_CHAR_DEVICE_IO
-+ putwc_unlocked (L' ', fs->stream);
-+#else
-+ abort ();
-+#endif
-+ }
- else
-+#endif
- putc_unlocked (' ', fs->stream);
-
- /* Copy the tail of the original buffer into the current buffer
-diff --git a/argp/argp-help.c b/argp/argp-help.c
-index b055e45..6b3c4c1 100644
---- a/argp/argp-help.c
-+++ b/argp/argp-help.c
-@@ -51,6 +51,7 @@ char *alloca ();
- #ifdef _LIBC
- # include <../libio/libioP.h>
- # include <wchar.h>
-+# include <gnu/option-groups.h>
- #endif
-
- #ifndef _
-@@ -1702,7 +1703,7 @@ char *__argp_basename (char *name)
- }
-
- char *
--__argp_short_program_name (void)
-+(__argp_short_program_name) (void)
- {
- # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
- return program_invocation_short_name;
-@@ -1873,9 +1874,17 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
- #endif
- }
-
-+#ifdef _LIBC
- if (_IO_fwide (stream, 0) > 0)
-- putwc_unlocked (L'\n', stream);
-+ {
-+#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
-+ putwc_unlocked (L'\n', stream);
-+#else
-+ abort ();
-+#endif
-+ }
- else
-+#endif
- putc_unlocked ('\n', stream);
-
- #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
-diff --git a/argp/argp-namefrob.h b/argp/argp-namefrob.h
-index f67c58f..e2002dc 100644
---- a/argp/argp-namefrob.h
-+++ b/argp/argp-namefrob.h
-@@ -76,10 +76,12 @@
- #undef __argp_fmtstream_wmargin
- #define __argp_fmtstream_wmargin argp_fmtstream_wmargin
-
-+#if 0
- #include "mempcpy.h"
- #include "strcase.h"
- #include "strchrnul.h"
- #include "strndup.h"
-+#endif
-
- /* normal libc functions we call */
- #undef __flockfile
-diff --git a/catgets/Makefile b/catgets/Makefile
-index 4624a88..05714fd 100644
---- a/catgets/Makefile
-+++ b/catgets/Makefile
-@@ -22,20 +22,23 @@ subdir := catgets
-
- include ../Makeconfig
-
-+include ../option-groups.mak
-+
- headers = nl_types.h
--routines = catgets open_catalog
--others = gencat
--install-bin = gencat
--extra-objs = $(gencat-modules:=.o)
-+routines-$(OPTION_EGLIBC_CATGETS) := catgets open_catalog
-+others-$(OPTION_EGLIBC_CATGETS) := gencat
-+install-bin-$(OPTION_EGLIBC_CATGETS) := gencat
-+extra-objs-$(OPTION_EGLIBC_CATGETS) := $(gencat-modules:=.o)
-
--tests = tst-catgets
--test-srcs = test-gencat
-+tests-$(OPTION_EGLIBC_CATGETS) := tst-catgets
-+test-srcs-$(OPTION_EGLIBC_CATGETS) := test-gencat
-
-+ifeq (y,$(OPTION_EGLIBC_CATGETS))
- ifeq ($(run-built-tests),yes)
- tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
- $(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out
- endif
--
-+endif
- gencat-modules = xmalloc
-
- # To find xmalloc.c
-diff --git a/crypt/Makefile b/crypt/Makefile
-index 34c4dd7..7c18c88 100644
---- a/crypt/Makefile
-+++ b/crypt/Makefile
-@@ -18,21 +18,25 @@
- #
- # Sub-makefile for crypt() portion of the library.
- #
-+include ../option-groups.mak
-+
- subdir := crypt
-
- include ../Makeconfig
-
- headers := crypt.h
-
--extra-libs := libcrypt
--extra-libs-others := $(extra-libs)
-+extra-libs-$(OPTION_EGLIBC_CRYPT) := libcrypt
-+extra-libs-others-y := $(extra-libs-y)
-
--libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
-- crypt_util
-+libcrypt-routines :=crypt-entry md5-crypt sha256-crypt sha512-crypt crypt_common
-+libcrypt-routines-$(OPTION_EGLIBC_CRYPT_UFC) := crypt crypt_util
-+libcrypt-routines += $(libcrypt-routines-y)
-
--tests := cert md5c-test sha256c-test sha512c-test badsalttest
-+tests-$(OPTION_EGLIBC_CRYPT) := md5c-test sha256c-test sha512c-test badsalttest
-+tests-$(OPTION_EGLIBC_CRYPT_UFC) += cert
-
--ifeq ($(crypt-in-libc),yes)
-+ifeq ($(crypt-in-libc)$(OPTION_EGLIBC_CRYPT),yesy)
- routines += $(libcrypt-routines)
- endif
-
-@@ -44,7 +48,7 @@ LDLIBS-crypt.so = -lfreebl3
- else
- libcrypt-routines += md5 sha256 sha512
-
--tests += md5test sha256test sha512test
-+tests-$(OPTION_EGLIBC_CRYPT) += md5test sha256test sha512test
-
- # The test md5test-giant uses up to 400 MB of RSS and runs on a fast
- # machine over a minute.
-@@ -64,8 +68,10 @@ $(objpfx)sha256test: $(patsubst %, $(objpfx)%.o,$(sha256-routines))
- $(objpfx)sha512test: $(patsubst %, $(objpfx)%.o,$(sha512-routines))
- endif
-
-+ifeq ($(OPTION_EGLIBC_CRYPT),y)
- ifeq (yes,$(build-shared))
- $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.so
- else
- $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.a
- endif
-+endif # eglibc: OPTION_EGLIBC_CRYPT
-diff --git a/crypt/crypt-entry.c b/crypt/crypt-entry.c
-index 7e655ba..6ae5c2b 100644
---- a/crypt/crypt-entry.c
-+++ b/crypt/crypt-entry.c
-@@ -27,6 +27,7 @@
- #include <stdio.h>
- #endif
- #include <string.h>
-+#include <gnu/option-groups.h>
- #include <errno.h>
- #include <fips-private.h>
-
-@@ -76,9 +77,11 @@ __crypt_r (key, salt, data)
- const char *salt;
- struct crypt_data * __restrict data;
- {
-+#if __OPTION_EGLIBC_CRYPT_UFC
- ufc_long res[4];
- char ktab[9];
- ufc_long xx = 25; /* to cope with GCC long long compiler bugs */
-+#endif /*__OPTION_EGLIBC_CRYPT_UFC*/
-
- #ifdef _LIBC
- /* Try to find out whether we have to use MD5 encryption replacement. */
-@@ -105,6 +108,7 @@ __crypt_r (key, salt, data)
- sizeof (struct crypt_data));
- #endif
-
-+#if __OPTION_EGLIBC_CRYPT_UFC
- /*
- * Hack DES tables according to salt
- */
-@@ -144,6 +148,10 @@ __crypt_r (key, salt, data)
- */
- _ufc_output_conversion_r (res[0], res[1], salt, data);
- return data->crypt_3_buf;
-+#else /* __OPTION_EGLIBC_CRYPT_UFC */
-+ __set_errno (ENOSYS);
-+ return NULL;
-+#endif /* __OPTION_EGLIBC_CRYPT_UFC */
- }
- weak_alias (__crypt_r, crypt_r)
-
-@@ -168,7 +176,12 @@ crypt (key, salt)
- return __sha512_crypt (key, salt);
- #endif
-
-+#if __OPTION_EGLIBC_CRYPT_UFC
- return __crypt_r (key, salt, &_ufc_foobar);
-+#else /* __OPTION_EGLIBC_CRYPT_UFC */
-+ __set_errno (ENOSYS);
-+ return NULL;
-+#endif /* __OPTION_EGLIBC_CRYPT_UFC */
- }
-
-
-diff --git a/crypt/crypt_common.c b/crypt/crypt_common.c
-new file mode 100644
-index 0000000..cce6a31
---- /dev/null
-+++ b/crypt/crypt_common.c
-@@ -0,0 +1,42 @@
-+/*
-+ * crypt: crypt(3) implementation
-+ *
-+ * Copyright (C) 1991-2014 Free Software Foundation, Inc.
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; see the file COPYING.LIB. If not,
-+ * see <http://www.gnu.org/licenses/>.
-+ *
-+ * General Support routines
-+ *
-+ */
-+
-+#include "crypt-private.h"
-+
-+/* Table with characters for base64 transformation. */
-+static const char b64t[64] =
-+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-+
-+void
-+__b64_from_24bit (char **cp, int *buflen,
-+ unsigned int b2, unsigned int b1, unsigned int b0,
-+ int n)
-+{
-+ unsigned int w = (b2 << 16) | (b1 << 8) | b0;
-+ while (n-- > 0 && (*buflen) > 0)
-+ {
-+ *(*cp)++ = b64t[w & 0x3f];
-+ --(*buflen);
-+ w >>= 6;
-+ }
-+}
-diff --git a/crypt/crypt_util.c b/crypt/crypt_util.c
-index 1597885..9297974 100644
---- a/crypt/crypt_util.c
-+++ b/crypt/crypt_util.c
-@@ -242,10 +242,6 @@ static ufc_long eperm32tab[4][256][2];
- */
- static ufc_long efp[16][64][2];
-
--/* Table with characters for base64 transformation. */
--static const char b64t[64] =
--"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
--
- /*
- * For use by the old, non-reentrant routines
- * (crypt/encrypt/setkey)
-@@ -949,17 +945,3 @@ setkey(__key)
- {
- __setkey_r(__key, &_ufc_foobar);
- }
--
--void
--__b64_from_24bit (char **cp, int *buflen,
-- unsigned int b2, unsigned int b1, unsigned int b0,
-- int n)
--{
-- unsigned int w = (b2 << 16) | (b1 << 8) | b0;
-- while (n-- > 0 && (*buflen) > 0)
-- {
-- *(*cp)++ = b64t[w & 0x3f];
-- --(*buflen);
-- w >>= 6;
-- }
--}
-diff --git a/csu/Makefile b/csu/Makefile
-index 9f0855a..b1c3363 100644
---- a/csu/Makefile
-+++ b/csu/Makefile
-@@ -22,6 +22,8 @@
- # crtn.o, special "initializer" and "finalizer" files used in the link
- # to make the .init and .fini sections work right.
-
-+include ../option-groups.mak
-+
- subdir := csu
-
- include ../Makeconfig
-diff --git a/debug/Makefile b/debug/Makefile
-index 9ff357b..d23d97d 100644
---- a/debug/Makefile
-+++ b/debug/Makefile
-@@ -18,6 +18,8 @@
- #
- # Sub-makefile for debug portion of the library.
- #
-+include ../option-groups.mak
-+
- subdir := debug
-
- include ../Makeconfig
-@@ -27,7 +29,7 @@ headers := execinfo.h
- # Note that ptsname_r_chk and getlogin_r are not here, but in
- # login/Makefile instead. If that subdir is omitted from the
- # build, its _FORTIFY_SOURCE support will be too.
--routines = backtrace backtracesyms backtracesymsfd noophooks \
-+routines = noophooks \
- memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \
- strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \
- sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
-@@ -36,20 +38,27 @@ routines = backtrace backtracesyms backtracesymsfd noophooks \
- read_chk pread_chk pread64_chk recv_chk recvfrom_chk \
- readlink_chk readlinkat_chk getwd_chk getcwd_chk \
- realpath_chk fread_chk fread_u_chk \
-- wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
-- wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
-- wcpncpy_chk \
-- swprintf_chk vswprintf_chk wprintf_chk fwprintf_chk \
-- vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk \
- confstr_chk getgroups_chk ttyname_r_chk \
-- gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \
-- wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \
-- wcstombs_chk asprintf_chk vasprintf_chk dprintf_chk \
-+ gethostname_chk getdomainname_chk \
-+ asprintf_chk vasprintf_chk dprintf_chk \
- vdprintf_chk obprintf_chk \
- longjmp_chk ____longjmp_chk \
- fdelt_chk poll_chk ppoll_chk \
- stack_chk_fail fortify_fail \
- $(static-only-routines)
-+routines-$(OPTION_EGLIBC_BACKTRACE) += backtrace backtracesyms backtracesymsfd
-+routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
-+ += wprintf_chk fwprintf_chk \
-+ vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk
-+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
-+ += wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
-+ wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
-+ wcpncpy_chk \
-+ swprintf_chk vswprintf_chk \
-+ wcrtomb_chk mbsnrtowcs_chk \
-+ wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \
-+ wcstombs_chk
-+
- static-only-routines := warning-nop stack_chk_fail_local
-
- CFLAGS-backtrace.c = -fno-omit-frame-pointer
-@@ -131,11 +140,15 @@ LDFLAGS-tst-backtrace4 = -rdynamic
- LDFLAGS-tst-backtrace5 = -rdynamic
- LDFLAGS-tst-backtrace6 = -rdynamic
-
--tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
-- tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
-- tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \
-- tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \
-- tst-backtrace5 tst-backtrace6
-+tests = tst-longjmp_chk test-strcpy_chk test-stpcpy_chk tst-longjmp_chk2
-+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
-+ += tst-chk1 tst-chk2 tst-chk3 tst-lfschk1 tst-lfschk2 tst-lfschk3
-+tests-$(OPTION_EGLIBC_BACKTRACE) \
-+ += backtrace-tst tst-backtrace2 tst-backtrace3 tst-backtrace4 \
-+ tst-backtrace5 tst-backtrace6
-+ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_EGLIBC_CXX_TESTS))
-+tests += tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6
-+endif
-
- ifeq (,$(CXX))
- tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \
-diff --git a/debug/segfault.c b/debug/segfault.c
-index 3459a2a..ee9a146 100644
---- a/debug/segfault.c
-+++ b/debug/segfault.c
-@@ -30,6 +30,7 @@
- #include <unistd.h>
- #include <_itoa.h>
- #include <ldsodefs.h>
-+#include <gnu/option-groups.h>
-
- /* This file defines macros to access the content of the sigcontext element
- passed up by the signal handler. */
-@@ -68,11 +69,13 @@ write_strsignal (int fd, int signal)
- static void
- catch_segfault (int signal, SIGCONTEXT ctx)
- {
-- int fd, cnt, i;
-- void **arr;
-+ int fd;
- struct sigaction sa;
-+#if __OPTION_EGLIBC_BACKTRACE
-+ int cnt, i;
-+ void **arr;
- uintptr_t pc;
--
-+#endif
- /* This is the name of the file we are writing to. If none is given
- or we cannot write to this file write to stderr. */
- fd = 2;
-@@ -91,6 +94,7 @@ catch_segfault (int signal, SIGCONTEXT ctx)
- REGISTER_DUMP;
- #endif
-
-+#if __OPTION_EGLIBC_BACKTRACE
- WRITE_STRING ("\nBacktrace:\n");
-
- /* Get the backtrace. */
-@@ -113,6 +117,7 @@ catch_segfault (int signal, SIGCONTEXT ctx)
-
- /* Now generate nicely formatted output. */
- __backtrace_symbols_fd (arr + i, cnt - i, fd);
-+#endif
-
- #ifdef HAVE_PROC_SELF
- /* Now the link map. */
-diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
-index 53559e6..362d92a 100644
---- a/debug/tst-chk1.c
-+++ b/debug/tst-chk1.c
-@@ -31,6 +31,7 @@
- #include <sys/select.h>
- #include <sys/socket.h>
- #include <sys/un.h>
-+#include <gnu/option-groups.h>
-
-
- #define obstack_chunk_alloc malloc
-@@ -307,6 +308,7 @@ do_test (void)
- snprintf (buf + 8, l0 + 3, "%d", num2);
- CHK_FAIL_END
-
-+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
- CHK_FAIL_START
- swprintf (wbuf + 8, 3, L"%d", num1);
- CHK_FAIL_END
-@@ -314,6 +316,7 @@ do_test (void)
- CHK_FAIL_START
- swprintf (wbuf + 8, l0 + 3, L"%d", num1);
- CHK_FAIL_END
-+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
- # endif
-
- memcpy (buf, str1 + 2, l0 + 9);
-@@ -381,6 +384,7 @@ do_test (void)
- CHK_FAIL_END
- #endif
-
-+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
-
- /* These ops can be done without runtime checking of object size. */
- wmemcpy (wbuf, L"abcdefghij", 10);
-@@ -605,6 +609,7 @@ do_test (void)
- CHK_FAIL_END
- #endif
-
-+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
-
- /* Now checks for %n protection. */
-
-@@ -1192,6 +1197,7 @@ do_test (void)
- # endif
- #endif
-
-+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
- if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL)
- {
- assert (MB_CUR_MAX <= 10);
-@@ -1348,6 +1354,7 @@ do_test (void)
- puts ("cannot set locale");
- ret = 1;
- }
-+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
-
- int fd = posix_openpt (O_RDWR);
- if (fd != -1)
-diff --git a/dlfcn/Makefile b/dlfcn/Makefile
-index 759780d..3827607 100644
---- a/dlfcn/Makefile
-+++ b/dlfcn/Makefile
-@@ -15,6 +15,8 @@
- # License along with the GNU C Library; if not, see
- # <http://www.gnu.org/licenses/>.
-
-+include ../option-groups.mak
-+
- subdir := dlfcn
-
- include ../Makeconfig
-@@ -36,8 +38,11 @@ endif
- ifeq (yes,$(build-shared))
- tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
- bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
-- bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen
-+ tstatexit bug-dl-leaf tst-rec-dlopen
- endif
-+
-+tests-$(OPTION_EGLIBC_CXX_TESTS) += bug-atexit3
-+
- modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
- defaultmod2 errmsg1mod modatexit modcxaatexit \
- bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \
-diff --git a/elf/dl-support.c b/elf/dl-support.c
-index 4d036f1..c15f405 100644
---- a/elf/dl-support.c
-+++ b/elf/dl-support.c
-@@ -19,6 +19,7 @@
- /* This file defines some things that for the dynamic linker are defined in
- rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */
-
-+#include <gnu/option-groups.h>
- #include <errno.h>
- #include <libintl.h>
- #include <stdlib.h>
-@@ -42,7 +43,9 @@ char **_dl_argv = &__progname; /* This is checked for some error messages. */
- const char *_dl_platform;
- size_t _dl_platformlen;
-
-+#if __OPTION_EGLIBC_RTLD_DEBUG
- int _dl_debug_mask;
-+#endif
- int _dl_lazy;
- ElfW(Addr) _dl_use_load_bias = -2;
- int _dl_dynamic_weak;
-diff --git a/elf/rtld.c b/elf/rtld.c
-index 6d3add7..fc3a2db 100644
---- a/elf/rtld.c
-+++ b/elf/rtld.c
-@@ -16,6 +16,7 @@
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-+#include <gnu/option-groups.h>
- #include <errno.h>
- #include <dlfcn.h>
- #include <fcntl.h>
-@@ -2201,6 +2202,7 @@ print_missing_version (int errcode __attribute__ ((unused)),
- objname, errstring);
- }
-
-+#if __OPTION_EGLIBC_RTLD_DEBUG
- /* Nonzero if any of the debugging options is enabled. */
- static int any_debug attribute_relro;
-
-@@ -2310,6 +2312,7 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
- _exit (0);
- }
- }
-+#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
-
- static void
- process_dl_audit (char *str)
-@@ -2349,8 +2352,9 @@ process_envvars (enum mode *modep)
- char **runp = _environ;
- char *envline;
- enum mode mode = normal;
-+#if __OPTION_EGLIBC_RTLD_DEBUG
- char *debug_output = NULL;
--
-+#endif
- /* This is the default place for profiling data file. */
- GLRO(dl_profile_output)
- = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
-@@ -2377,12 +2381,14 @@ process_envvars (enum mode *modep)
- break;
-
- case 5:
-+#if __OPTION_EGLIBC_RTLD_DEBUG
- /* Debugging of the dynamic linker? */
- if (memcmp (envline, "DEBUG", 5) == 0)
- {
- process_dl_debug (&envline[6]);
- break;
- }
-+#endif
- if (memcmp (envline, "AUDIT", 5) == 0)
- process_dl_audit (&envline[6]);
- break;
-@@ -2448,13 +2454,14 @@ process_envvars (enum mode *modep)
- break;
- }
-
-+#if __OPTION_EGLIBC_RTLD_DEBUG
- /* Where to place the profiling data file. */
- if (memcmp (envline, "DEBUG_OUTPUT", 12) == 0)
- {
- debug_output = &envline[13];
- break;
- }
--
-+#endif
- if (!__libc_enable_secure
- && memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
- GLRO(dl_dynamic_weak) = 1;
-@@ -2491,7 +2498,9 @@ process_envvars (enum mode *modep)
- {
- mode = trace;
- GLRO(dl_verbose) = 1;
-+#if __OPTION_EGLIBC_RTLD_DEBUG
- GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
-+#endif
- GLRO(dl_trace_prelink) = &envline[17];
- }
- break;
-@@ -2538,12 +2547,15 @@ process_envvars (enum mode *modep)
- if (__access ("/etc/suid-debug", F_OK) != 0)
- {
- unsetenv ("MALLOC_CHECK_");
-+#if __OPTION_EGLIBC_RTLD_DEBUG
- GLRO(dl_debug_mask) = 0;
-+#endif
- }
-
- if (mode != normal)
- _exit (5);
- }
-+#if __OPTION_EGLIBC_RTLD_DEBUG
- /* If we have to run the dynamic linker in debugging mode and the
- LD_DEBUG_OUTPUT environment variable is given, we write the debug
- messages to this file. */
-@@ -2568,6 +2580,7 @@ process_envvars (enum mode *modep)
- /* We use standard output if opening the file failed. */
- GLRO(dl_debug_fd) = STDOUT_FILENO;
- }
-+#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
- }
-
-
-diff --git a/extra-lib.mk b/extra-lib.mk
-index b10748d..d71a06f 100644
---- a/extra-lib.mk
-+++ b/extra-lib.mk
-@@ -25,7 +25,9 @@ install-lib := $(install-lib)
- extra-objs := $(extra-objs)
-
- # The modules that go in $(lib).
--all-$(lib)-routines := $($(lib)-routines) $($(lib)-sysdep_routines)
-+all-$(lib)-routines := $($(lib)-routines) \
-+ $($(lib)-routines-y) \
-+ $($(lib)-sysdep_routines)
-
- # Add each flavor of library to the lists of things to build and install.
- install-lib += $(foreach o,$(object-suffixes-$(lib)),$(lib:lib%=$(libtype$o)))
-@@ -101,7 +103,7 @@ endif
- endif
-
- # This will define `libof-ROUTINE := LIB' for each of the routines.
--cpp-srcs-left := $($(lib)-routines) $($(lib)-sysdep_routines)
-+cpp-srcs-left := $(all-$(lib)-routines)
- ifneq (,$(cpp-srcs-left))
- include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
- endif
-diff --git a/grp/Makefile b/grp/Makefile
-index c63b552..7486f32 100644
---- a/grp/Makefile
-+++ b/grp/Makefile
-@@ -18,6 +18,8 @@
- #
- # Sub-makefile for grp portion of the library.
- #
-+include ../option-groups.mak
-+
- subdir := grp
-
- include ../Makeconfig
-@@ -29,6 +31,9 @@ routines := fgetgrent initgroups setgroups \
- getgrent_r getgrgid_r getgrnam_r fgetgrent_r
-
- tests := testgrp
-+ifneq (y,$(OPTION_EGLIBC_NSSWITCH))
-+LDLIBS-testgrp += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
-+endif
-
- ifeq (yes,$(build-shared))
- test-srcs := tst_fgetgrent
-diff --git a/hesiod/Makefile b/hesiod/Makefile
-index ac0bc01..38263b4 100644
---- a/hesiod/Makefile
-+++ b/hesiod/Makefile
-@@ -18,12 +18,14 @@
- #
- # Sub-makefile for hesiod portion of the library.
- #
-+include ../option-groups.mak
-+
- subdir := hesiod
-
- include ../Makeconfig
-
--extra-libs := libnss_hesiod
--extra-libs-others = $(extra-libs)
-+extra-libs-$(OPTION_EGLIBC_INET) += libnss_hesiod
-+extra-libs-others-y += $(extra-libs-y)
-
- subdir-dirs = nss_hesiod
- vpath %.c nss_hesiod
-diff --git a/iconv/Makefile b/iconv/Makefile
-index 0d55eda..a1847c6 100644
---- a/iconv/Makefile
-+++ b/iconv/Makefile
-@@ -18,6 +18,8 @@
- #
- # Makefile for iconv.
- #
-+include ../option-groups.mak
-+
- subdir := iconv
-
- include ../Makeconfig
-@@ -39,6 +41,11 @@ CFLAGS-iconv_charmap.c = -I../locale/programs
- CFLAGS-dummy-repertoire.c = -I../locale/programs
- CFLAGS-charmap.c = -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \
- -DDEFAULT_CHARMAP=null_pointer -DNEED_NULL_POINTER
-+
-+ifneq (y,$(OPTION_EGLIBC_SPAWN))
-+CFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
-+endif
-+
- CFLAGS-linereader.c = -DNO_TRANSLITERATION
- CFLAGS-simple-hash.c = -I../locale
-
-diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c
-index ce46216..ea18964 100644
---- a/iconv/gconv_db.c
-+++ b/iconv/gconv_db.c
-@@ -25,6 +25,7 @@
- #include <sys/param.h>
- #include <bits/libc-lock.h>
- #include <locale/localeinfo.h>
-+#include <gnu/option-groups.h>
-
- #include <dlfcn.h>
- #include <gconv_int.h>
-@@ -828,9 +829,11 @@ free_modules_db (struct gconv_module *node)
- /* Free all resources if necessary. */
- libc_freeres_fn (free_mem)
- {
-+#if __OPTION_EGLIBC_LOCALE_CODE
- /* First free locale memory. This needs to be done before freeing derivations,
- as ctype cleanup functions dereference steps arrays which we free below. */
- _nl_locale_subfreeres ();
-+#endif
-
- /* finddomain.c has similar problem. */
- extern void _nl_finddomain_subfreeres (void) attribute_hidden;
-diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
-index 5d5d4d7..a7d3072 100644
---- a/iconv/gconv_trans.c
-+++ b/iconv/gconv_trans.c
-@@ -23,6 +23,7 @@
- #include <stdint.h>
- #include <string.h>
- #include <stdlib.h>
-+#include <gnu/option-groups.h>
-
- #include <bits/libc-lock.h>
- #include "gconv_int.h"
-@@ -38,15 +39,19 @@ __gconv_transliterate (struct __gconv_step *step,
- unsigned char **outbufstart, size_t *irreversible)
- {
- /* Find out about the locale's transliteration. */
-+#if __OPTION_EGLIBC_LOCALE_CODE
- uint_fast32_t size;
- const uint32_t *from_idx;
- const uint32_t *from_tbl;
- const uint32_t *to_idx;
- const uint32_t *to_tbl;
-+#endif
- const uint32_t *winbuf;
- const uint32_t *winbufend;
-+#if __OPTION_EGLIBC_LOCALE_CODE
- uint_fast32_t low;
- uint_fast32_t high;
-+#endif
-
- /* The input buffer. There are actually 4-byte values. */
- winbuf = (const uint32_t *) *inbufp;
-@@ -58,6 +63,7 @@ __gconv_transliterate (struct __gconv_step *step,
- PTR_DEMANGLE (fct);
- #endif
-
-+#if __OPTION_EGLIBC_LOCALE_CODE
- /* If there is no transliteration information in the locale don't do
- anything and return the error. */
- size = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_TAB_SIZE);
-@@ -193,6 +199,7 @@ __gconv_transliterate (struct __gconv_step *step,
- sorted. */
- break;
- }
-+#endif
-
- /* One last chance: use the default replacement. */
- if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN) != 0)
-diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
-index e249bce..403ece5 100644
---- a/iconv/iconv_prog.c
-+++ b/iconv/iconv_prog.c
-@@ -35,6 +35,7 @@
- #ifdef _POSIX_MAPPED_FILES
- # include <sys/mman.h>
- #endif
-+#include <gnu/option-groups.h>
- #include <charmap.h>
- #include <gconv_int.h>
- #include "iconv_prog.h"
-@@ -221,10 +222,17 @@ main (int argc, char *argv[])
- bool to_wrong =
- (iconv_open (to_code, "UTF-8") == (iconv_t) -1
- && errno == EINVAL);
-+#if __OPTION_EGLIBC_LOCALE_CODE
- const char *from_pretty =
- (from_code[0] ? from_code : nl_langinfo (CODESET));
- const char *to_pretty =
- (orig_to_code[0] ? orig_to_code : nl_langinfo (CODESET));
-+#else
-+ const char *from_pretty =
-+ (from_code[0] ? from_code : "ANSI_X3.4-1968");
-+ const char *to_pretty =
-+ (orig_to_code[0] ? orig_to_code : "ANSI_X3.4-1968");
-+#endif
-
- if (from_wrong)
- {
-diff --git a/iconvdata/Makefile b/iconvdata/Makefile
-index a3d1d09..0832708 100644
---- a/iconvdata/Makefile
-+++ b/iconvdata/Makefile
-@@ -18,12 +18,15 @@
- #
- # Makefile for iconv data and code.
- #
-+include ../option-groups.mak
-+
- subdir := iconvdata
-
- include ../Makeconfig
-
- # Names of all the shared objects which implement the transformations.
--modules := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
-+modules-$(OPTION_EGLIBC_CHARSETS) \
-+ := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
- ISO8859-6 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-10 \
- ISO8859-11 ISO8859-13 ISO8859-14 ISO8859-15 ISO8859-16 \
- T.61 ISO_6937 SJIS KOI-8 HP-ROMAN8 HP-ROMAN9 EBCDIC-AT-DE \
-@@ -63,11 +66,13 @@ modules := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
- MAC-CENTRALEUROPE KOI8-RU ISO8859-9E \
- CP770 CP771 CP772 CP773 CP774
-
--modules.so := $(addsuffix .so, $(modules))
-+modules.so := $(addsuffix .so, $(modules-y))
-
- ifeq (yes,$(build-shared))
- tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
-- tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9
-+ tst-iconv6 bug-iconv5 bug-iconv8 bug-iconv9
-+tests-$(OPTION_EGLIBC_LOCALE_CODE) += bug-iconv6 tst-iconv7
-+
- ifeq ($(have-thread-library),yes)
- tests += bug-iconv3
- endif
-@@ -127,13 +132,13 @@ ifeq (yes,$(build-shared))
- # Rule to generate the shared objects.
- charmaps = ../localedata/charmaps
- -include $(objpfx)iconv-rules
--extra-modules-left := $(modules)
-+extra-modules-left := $(modules-y)
- include extra-module.mk
-
-
- extra-objs += $(modules.so)
--install-others = $(addprefix $(inst_gconvdir)/, $(modules.so)) \
-- $(inst_gconvdir)/gconv-modules
-+install-others-y += $(addprefix $(inst_gconvdir)/, $(modules.so))
-+install-others-$(OPTION_EGLIBC_CHARSETS) += $(inst_gconvdir)/gconv-modules
-
- # We can build the conversion tables for numerous charsets automatically.
-
-@@ -201,7 +206,7 @@ before-compile += $(addprefix $(objpfx),$(generated-modules:=.h))
- ifndef avoid-generated
- $(objpfx)iconv-rules: Makefile
- $(make-target-directory)
-- { echo $(filter-out lib%, $(modules)); \
-+ { echo $(filter-out lib%, $(modules-y)); \
- echo 8bit $(gen-8bit-modules); \
- echo 8bit-gap $(gen-8bit-gap-modules); } | \
- LC_ALL=C \
-@@ -245,7 +250,7 @@ $(addprefix $(inst_gconvdir)/, $(modules.so)): \
- $(do-install-program)
- $(inst_gconvdir)/gconv-modules: gconv-modules $(+force)
- $(do-install)
--ifeq (no,$(cross-compiling))
-+# eglibc: ifeq (no,$(cross-compiling))
- # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary
- # if this libc has more gconv modules than the previously installed one.
- if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \
-@@ -254,9 +259,9 @@ ifeq (no,$(cross-compiling))
- $(common-objpfx)iconv/iconvconfig \
- $(addprefix --prefix=,$(install_root)); \
- fi
--else
-- @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
--endif
-+# eglibc: else
-+# eglibc: @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
-+# eglibc: endif
-
- endif # build-shared = yes
-
-diff --git a/include/netdb.h b/include/netdb.h
-index e1f051d..f6d15aa 100644
---- a/include/netdb.h
-+++ b/include/netdb.h
-@@ -232,6 +232,10 @@ extern enum nss_status _nss_ ## service ## _gethostbyname2_r \
- (const char *name, int af, struct hostent *host, \
- char *buffer, size_t buflen, int *errnop, \
- int *h_errnop); \
-+extern enum nss_status _nss_ ## service ## _gethostbyname3_r \
-+ (const char *name, int af, struct hostent *result, \
-+ char *buffer, size_t buflen, int *errnop, \
-+ int *h_errnop, int32_t *ttlp, char **canonp); \
- extern enum nss_status _nss_ ## service ## _gethostbyname_r \
- (const char *name, struct hostent *host, char *buffer, \
- size_t buflen, int *errnop, int *h_errnop); \
-diff --git a/inet/Makefile b/inet/Makefile
-index f1d871f..7cb1709 100644
---- a/inet/Makefile
-+++ b/inet/Makefile
-@@ -18,6 +18,8 @@
- #
- # Sub-makefile for inet portion of the library.
- #
-+include ../option-groups.mak
-+
- subdir := inet
-
- include ../Makeconfig
-@@ -27,7 +29,8 @@ headers := netinet/ether.h netinet/in.h netinet/in_systm.h \
- netinet/tcp.h netinet/ip.h $(wildcard arpa/*.h protocols/*.h) \
- aliases.h ifaddrs.h netinet/ip6.h netinet/icmp6.h bits/in.h
-
--routines := htonl htons \
-+routines-$(OPTION_EGLIBC_INET) \
-+ += htonl htons \
- inet_lnaof inet_mkadr \
- inet_netof inet_ntoa inet_net herrno herrno-loc \
- gethstbyad gethstbyad_r gethstbynm gethstbynm2 gethstbynm2_r \
-@@ -39,18 +42,23 @@ routines := htonl htons \
- getservent_r \
- ether_aton ether_aton_r ether_hton ether_line \
- ether_ntoa ether_ntoa_r ether_ntoh \
-- rcmd rexec ruserpass \
- getnetgrent_r getnetgrent \
-- getaliasent_r getaliasent getaliasname getaliasname_r \
-- in6_addr getnameinfo if_index ifaddrs inet6_option \
-+ in6_addr getnameinfo if_index ifaddrs \
- getipv4sourcefilter setipv4sourcefilter \
-- getsourcefilter setsourcefilter inet6_opt inet6_rth
-+ getsourcefilter setsourcefilter
-+routines-$(OPTION_EGLIBC_RCMD) \
-+ += rcmd rexec ruserpass
-+routines-$(OPTION_EGLIBC_DB_ALIASES) \
-+ += getaliasent_r getaliasent getaliasname getaliasname_r
-+routines-$(OPTION_EGLIBC_ADVANCED_INET6) \
-+ += inet6_option inet6_opt inet6_rth
-
--aux := check_pf check_native ifreq
-+aux-$(OPTION_EGLIBC_INET) += check_pf check_native ifreq
-
- tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
-- tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
-+ tst-gethnm test-ifaddrs bug-if1 tst-ether_line \
- tst-getni1 tst-getni2 tst-inet6_rth tst-checks
-+tests-$(OPTION_EGLIBC_ADVANCED_INET6) += test-inet6_opt
-
- include ../Rules
-
-diff --git a/intl/Makefile b/intl/Makefile
-index 9ecf8fe..587bc0d 100644
---- a/intl/Makefile
-+++ b/intl/Makefile
-@@ -16,6 +16,7 @@
- # <http://www.gnu.org/licenses/>.
-
- # Makefile for intl subdirectory: message handling code from GNU gettext.
-+include ../option-groups.mak
-
- subdir = intl
-
-@@ -48,7 +49,7 @@ endif
- $(objpfx)plural.o: plural.c
-
- ifeq ($(run-built-tests),yes)
--ifeq (yes,$(build-shared))
-+ifeq (yyyes,$(OPTION_EGLIBC_LOCALES)$(OPTION_EGLIBC_LOCALE_CODE)$(build-shared))
- ifneq ($(strip $(MSGFMT)),:)
- tests-special += $(objpfx)tst-translit.out $(objpfx)tst-gettext.out \
- $(objpfx)tst-gettext2.out $(objpfx)tst-codeset.out \
-diff --git a/intl/dcigettext.c b/intl/dcigettext.c
-index 8a3f091..e271648 100644
---- a/intl/dcigettext.c
-+++ b/intl/dcigettext.c
-@@ -100,11 +100,15 @@ extern int errno;
- # include "libgnuintl.h"
- #endif
- #include "hash-string.h"
-+#ifdef _LIBC
-+# include <gnu/option-groups.h>
-+#endif
-
- /* Handle multi-threaded applications. */
- #ifdef _LIBC
- # include <bits/libc-lock.h>
- # define gl_rwlock_define_initialized __libc_rwlock_define_initialized
-+# define gl_rwlock_define __libc_rwlock_define
- # define gl_rwlock_rdlock __libc_rwlock_rdlock
- # define gl_rwlock_wrlock __libc_rwlock_wrlock
- # define gl_rwlock_unlock __libc_rwlock_unlock
-@@ -523,8 +527,10 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
- saved_errno = errno;
-
- #ifdef _LIBC
-- __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
-- __libc_rwlock_rdlock (__libc_setlocale_lock);
-+# if __OPTION_EGLIBC_LOCALE_CODE
-+ gl_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
-+ gl_rwlock_rdlock (__libc_setlocale_lock);
-+# endif
- #endif
-
- gl_rwlock_rdlock (_nl_state_lock);
-@@ -550,7 +556,11 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
- #ifdef HAVE_PER_THREAD_LOCALE
- # ifndef IN_LIBGLOCALE
- # ifdef _LIBC
-- localename = strdupa (__current_locale_name (category));
-+# if __OPTION_EGLIBC_LOCALE_CODE
-+ localename = strdupa (__current_locale_name (category));
-+# else
-+ localename = "C";
-+# endif
- # else
- categoryname = category_to_name (category);
- # define CATEGORYNAME_INITIALIZED
-@@ -581,10 +591,12 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
- else
- retval = (char *) (*foundp)->translation;
-
-- gl_rwlock_unlock (_nl_state_lock);
- # ifdef _LIBC
-- __libc_rwlock_unlock (__libc_setlocale_lock);
-+# if __OPTION_EGLIBC_LOCALE_CODE
-+ gl_rwlock_unlock (__libc_setlocale_lock);
-+# endif
- # endif
-+ gl_rwlock_unlock (_nl_state_lock);
- __set_errno (saved_errno);
- return retval;
- }
-@@ -838,10 +850,13 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
- if (plural)
- retval = plural_lookup (domain, n, retval, retlen);
-
-- gl_rwlock_unlock (_nl_state_lock);
- #ifdef _LIBC
-- __libc_rwlock_unlock (__libc_setlocale_lock);
-+# if __OPTION_EGLIBC_LOCALE_CODE
-+
-+ gl_rwlock_unlock (__libc_setlocale_lock);
-+# endif
- #endif
-+ gl_rwlock_unlock (_nl_state_lock);
- return retval;
- }
- }
-@@ -850,10 +865,12 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
- return_untranslated:
- /* Return the untranslated MSGID. */
- FREE_BLOCKS (block_list);
-- gl_rwlock_unlock (_nl_state_lock);
- #ifdef _LIBC
-- __libc_rwlock_unlock (__libc_setlocale_lock);
-+# if __OPTION_EGLIBC_LOCALE_CODE
-+ gl_rwlock_unlock (__libc_setlocale_lock);
-+# endif
- #endif
-+ gl_rwlock_unlock (_nl_state_lock);
- #ifndef _LIBC
- if (!ENABLE_SECURE)
- {
-@@ -1550,7 +1567,11 @@ guess_category_value (int category, const char *categoryname)
- `LC_xxx', and `LANG'. On some systems this can be done by the
- `setlocale' function itself. */
- # ifdef _LIBC
-+# if __OPTION_EGLIBC_LOCALE_CODE
- locale = __current_locale_name (category);
-+# else
-+ locale = "C";
-+# endif
- # else
- locale_defaulted = 0;
- # if HAVE_USELOCALE
-diff --git a/io/Makefile b/io/Makefile
-index 613dce0..697439e 100644
---- a/io/Makefile
-+++ b/io/Makefile
-@@ -18,6 +18,8 @@
- #
- # Sub-makefile for I/O portion of the library.
- #
-+include ../option-groups.mak
-+
- subdir := io
-
- include ../Makeconfig
-@@ -36,7 +38,7 @@ routines := \
- fxstatat fxstatat64 \
- statfs fstatfs statfs64 fstatfs64 \
- statvfs fstatvfs statvfs64 fstatvfs64 \
-- umask chmod fchmod lchmod fchmodat \
-+ umask chmod fchmod fchmodat \
- mkdir mkdirat \
- open open_2 open64 open64_2 openat openat_2 openat64 openat64_2 \
- read write lseek lseek64 access euidaccess faccessat \
-@@ -49,11 +51,13 @@ routines := \
- ttyname ttyname_r isatty \
- link linkat symlink symlinkat readlink readlinkat \
- unlink unlinkat rmdir \
-- ftw ftw64 fts poll ppoll \
-+ poll ppoll \
- posix_fadvise posix_fadvise64 \
- posix_fallocate posix_fallocate64 \
- sendfile sendfile64 \
- utimensat futimens
-+routines-$(OPTION_EGLIBC_BSD) += lchmod
-+routines-$(OPTION_EGLIBC_FTRAVERSE) += ftw ftw64 fts
-
- aux := have_o_cloexec
-
-@@ -64,18 +68,22 @@ static-only-routines = stat fstat lstat stat64 fstat64 lstat64 \
- fstatat fstatat64 mknod mknodat
-
- others := pwd
--test-srcs := ftwtest
-+test-srcs-$(OPTION_EGLIBC_FTRAVERSE) := ftwtest
- tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
-- tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 tst-statvfs \
-+ tst-fcntl tst-statvfs \
- tst-openat tst-unlinkat tst-fstatat tst-futimesat \
- tst-renameat tst-fchownat tst-fchmodat tst-faccessat \
- tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
-- tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \
-+ tst-mknodat tst-mkfifoat tst-ttyname_r \
- tst-posix_fallocate
-+tests-$(OPTION_EGLIBC_FTRAVERSE) += bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 \
-+ bug-ftw5
-
- ifeq ($(run-built-tests),yes)
-+ifeq (y,$(OPTION_EGLIBC_FTRAVERSE))
- tests-special += $(objpfx)ftwtest.out
- endif
-+endif
-
- include ../Rules
-
-diff --git a/libidn/Makefile b/libidn/Makefile
-index 940fa52..43aad0c 100644
---- a/libidn/Makefile
-+++ b/libidn/Makefile
-@@ -16,6 +16,7 @@
- # <http://www.gnu.org/licenses/>.
-
- # Makefile for libidn subdirectory of GNU C Library.
-+include ../option-groups.mak
-
- subdir := libidn
-
-@@ -23,8 +24,8 @@ include ../Makeconfig
-
- routines = idn-stub
-
--extra-libs = libcidn
--extra-libs-others = $(extra-libs)
-+extra-libs-$(OPTION_EGLIBC_IDN) = libcidn
-+extra-libs-others-y = $(extra-libs-y)
-
- libcidn-routines := punycode toutf8 nfkc stringprep rfc3454 profiles idna \
- iconvme
-diff --git a/libidn/toutf8.c b/libidn/toutf8.c
-index c7e67ca..62df478 100644
---- a/libidn/toutf8.c
-+++ b/libidn/toutf8.c
-@@ -33,6 +33,11 @@
- /* Get strlen. */
- #include <string.h>
-
-+/* Get __OPTION_EGLIBC_LOCALE_CODE. */
-+#ifdef _LIBC
-+# include <gnu/option-groups.h>
-+#endif
-+
- /* Get iconv_string. */
- #include "iconvme.h"
-
-@@ -47,7 +52,11 @@
- #endif
-
- #ifdef _LIBC
--# define stringprep_locale_charset() nl_langinfo (CODESET)
-+# if __OPTION_EGLIBC_LOCALE_CODE
-+# define stringprep_locale_charset() nl_langinfo (CODESET)
-+# else
-+# define stringprep_locale_charset() "ANSI_X3.4-1968"
-+# endif
- #else
- /**
- * stringprep_locale_charset - return charset used in current locale
-diff --git a/libio/Makefile b/libio/Makefile
-index 7b3bcf9..27c9186 100644
---- a/libio/Makefile
-+++ b/libio/Makefile
-@@ -18,6 +18,8 @@
- #
- # Specific makefile for libio.
- #
-+include ../option-groups.mak
-+
- subdir := libio
-
- include ../Makeconfig
-@@ -27,16 +29,13 @@ headers := stdio.h libio.h _G_config.h bits/stdio.h bits/stdio-lock.h \
-
- routines := \
- filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen \
-- iofopncook iofputs iofread iofsetpos ioftell wfiledoalloc \
-+ iofopncook iofputs iofread iofsetpos ioftell \
- iofwrite iogetdelim iogetline iogets iopadn iopopen ioputs \
- ioseekoff ioseekpos iosetbuffer iosetvbuf ioungetc \
- iovsprintf iovsscanf \
- iofgetpos64 iofopen64 iofsetpos64 \
-- fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
-- iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u \
-- putwchar putwchar_u putchar putchar_u fwprintf swprintf vwprintf \
-- wprintf wscanf fwscanf vwscanf vswprintf iovswscanf swscanf wgenops \
-- wstrops wfileops iofwide fwide wmemstream \
-+ putchar putchar_u \
-+ iofwide \
- \
- clearerr feof ferror fileno fputc freopen fseek getc getchar \
- memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \
-@@ -48,24 +47,49 @@ routines := \
- \
- libc_fatal fmemopen oldfmemopen
-
--tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
-- tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \
-- tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf \
-- tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof \
-- tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \
-+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += \
-+ wfiledoalloc \
-+ iowpadn \
-+ swprintf \
-+ vswprintf iovswscanf swscanf wgenops \
-+ wstrops wfileops wmemstream
-+routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) += \
-+ wdummyfileops
-+routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += \
-+ fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
-+ iofputws iofputws_u iogetwline ioungetwc putwc putwc_u \
-+ putwchar putwchar_u fwprintf vwprintf \
-+ wprintf wscanf fwscanf vwscanf \
-+ fwide
-+
-+tests = test-fmemopen tst-ext tst-ext2 \
-+ tst-mmap-setvbuf tst-atime tst-eof \
-+ tst-freopen bug-ungetc bug-fseek \
- tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \
-- tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \
-- bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4 tst-fopenloc2 \
-+ tst-mmap2-eofsync tst-mmap-offend bug-fopena+ \
-+ bug-ungetc2 bug-ungetc3 bug-ungetc4 \
- tst-memstream1 tst-memstream2 \
-- tst-wmemstream1 tst-wmemstream2 \
-- bug-memstream1 bug-wmemstream1 \
-- tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
-- tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
-- tst-ftell-append tst-fputws
-+ bug-memstream1 tst-popen1 tst-fwrite-error \
-+ tst-ftell-active-handler tst-ftell-append
-+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
-+ += tst-swscanf tst-fgetws tst-setvbuf1 \
-+ tst-ungetwc1 tst-ungetwc2 bug-ftell bug-ungetwc2 \
-+ tst-widetext tst-fputws
-+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
-+ += bug-rewind bug-rewind2 bug-ungetwc1 \
-+ bug-wfflush bug-wmemstream1 tst-fopenloc2 \
-+ tst_getwc \
-+ tst_putwc tst_wprintf tst_wprintf2 tst_wscanf \
-+ tst-fgetwc bug-wsetpos tst-fseek tst-ftell-partial-wide
-+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
-+ += tst_swprintf tst_swscanf \
-+ tst-sscanf \
-+ tst-wmemstream1 tst-wmemstream2
-+
- ifeq (yes,$(build-shared))
- # Add test-fopenloc only if shared library is enabled since it depends on
- # shared localedata objects.
--tests += tst-fopenloc
-+tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-fopenloc
- endif
- test-srcs = test-freopen
-
-@@ -164,13 +188,17 @@ shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \
- oldiofsetpos64
-
- ifeq ($(run-built-tests),yes)
-+ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
- tests-special += $(objpfx)test-freopen.out
-+endif
-+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
- ifeq (yes,$(build-shared))
- # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
- # library is enabled since they depend on tst-fopenloc.out.
- tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out
- endif
- endif
-+endif
-
- include ../Rules
-
-diff --git a/libio/__fpurge.c b/libio/__fpurge.c
-index 065cf61..e32a3e9 100644
---- a/libio/__fpurge.c
-+++ b/libio/__fpurge.c
-@@ -21,7 +21,7 @@
- void
- __fpurge (FILE *fp)
- {
-- if (fp->_mode > 0)
-+ if (_IO_is_wide (fp))
- {
- /* Wide-char stream. */
- if (_IO_in_backup (fp))
-diff --git a/libio/fileops.c b/libio/fileops.c
-index cbcd6f5..19e43c2 100644
---- a/libio/fileops.c
-+++ b/libio/fileops.c
-@@ -39,6 +39,7 @@
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
-+#include <gnu/option-groups.h>
- #include <stdlib.h>
- #if _LIBC
- # include "../wcsmbs/wcsmbsload.h"
-@@ -173,7 +174,7 @@ _IO_new_file_close_it (_IO_FILE *fp)
-
- /* Free buffer. */
- #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-- if (fp->_mode > 0)
-+ if (_IO_is_wide (fp))
- {
- if (_IO_have_wbackup (fp))
- _IO_free_wbackup_area (fp);
-@@ -348,6 +349,7 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
- cs = strstr (last_recognized + 1, ",ccs=");
- if (cs != NULL)
- {
-+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
- /* Yep. Load the appropriate conversions and set the orientation
- to wide. */
- struct gconv_fcts fcts;
-@@ -418,6 +420,12 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
-
- /* Set the mode now. */
- result->_mode = 1;
-+#else
-+ /* Treat this as if we couldn't find the given character set. */
-+ (void) _IO_file_close_it (fp);
-+ __set_errno (EINVAL);
-+ return NULL;
-+#endif
- }
- }
-
-diff --git a/libio/iofwide.c b/libio/iofwide.c
-index 0c175d1..3e9f52b 100644
---- a/libio/iofwide.c
-+++ b/libio/iofwide.c
-@@ -26,6 +26,7 @@
-
- #include <libioP.h>
- #ifdef _LIBC
-+# include <gnu/option-groups.h>
- # include <dlfcn.h>
- # include <wchar.h>
- #endif
-@@ -43,6 +44,8 @@
- #endif
-
-
-+#if ! defined _LIBC || __OPTION_POSIX_C_LANG_WIDE_CHAR
-+
- /* Prototypes of libio's codecvt functions. */
- static enum __codecvt_result do_out (struct _IO_codecvt *codecvt,
- __mbstate_t *statep,
-@@ -499,3 +502,26 @@ do_max_length (struct _IO_codecvt *codecvt)
- return MB_CUR_MAX;
- #endif
- }
-+
-+#else
-+/* OPTION_POSIX_C_LANG_WIDE_CHAR is disabled. */
-+
-+#undef _IO_fwide
-+int
-+_IO_fwide (fp, mode)
-+ _IO_FILE *fp;
-+ int mode;
-+{
-+ /* Die helpfully if the user tries to create a wide stream; I
-+ disbelieve that most users check the return value from
-+ 'fwide (fp, 1)'. */
-+ assert (mode <= 0);
-+
-+ /* We can only make streams byte-oriented, which is trivial. */
-+ if (mode < 0)
-+ fp->_mode = -1;
-+
-+ return fp->_mode;
-+}
-+
-+#endif
-diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c
-index 11765cf..15d6230 100644
---- a/libio/ioseekoff.c
-+++ b/libio/ioseekoff.c
-@@ -60,7 +60,7 @@ _IO_seekoff_unlocked (fp, offset, dir, mode)
- else
- abort ();
- }
-- if (_IO_fwide (fp, 0) < 0)
-+ if (! _IO_is_wide (fp))
- _IO_free_backup_area (fp);
- else
- _IO_free_wbackup_area (fp);
-diff --git a/libio/ioseekpos.c b/libio/ioseekpos.c
-index a7652a1..6938b68 100644
---- a/libio/ioseekpos.c
-+++ b/libio/ioseekpos.c
-@@ -35,7 +35,7 @@ _IO_seekpos_unlocked (fp, pos, mode)
- /* If we have a backup buffer, get rid of it, since the __seekoff
- callback may not know to do the right thing about it.
- This may be over-kill, but it'll do for now. TODO */
-- if (_IO_fwide (fp, 0) <= 0)
-+ if (! _IO_is_wide (fp))
- {
- if (_IO_have_backup (fp))
- _IO_free_backup_area (fp);
-diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c
-index 0a41c10..3d99fa0 100644
---- a/libio/iosetbuffer.c
-+++ b/libio/iosetbuffer.c
-@@ -24,6 +24,8 @@
- This exception applies to code released by its copyright holders
- in files containing the exception. */
-
-+#include <gnu/option-groups.h>
-+
- #include "libioP.h"
-
- void
-@@ -38,9 +40,11 @@ _IO_setbuffer (fp, buf, size)
- if (!buf)
- size = 0;
- (void) _IO_SETBUF (fp, buf, size);
-+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
- if (_IO_vtable_offset (fp) == 0 && fp->_mode == 0 && _IO_CHECK_WIDE (fp))
- /* We also have to set the buffer using the wide char function. */
- (void) _IO_WSETBUF (fp, buf, size);
-+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
- _IO_release_lock (fp);
- }
- libc_hidden_def (_IO_setbuffer)
-diff --git a/libio/libioP.h b/libio/libioP.h
-index 0f16e2d..d2626d6 100644
---- a/libio/libioP.h
-+++ b/libio/libioP.h
-@@ -44,6 +44,10 @@
- /*# include <comthread.h>*/
- #endif
-
-+#if defined _LIBC
-+# include <gnu/option-groups.h>
-+#endif
-+
- #include <math_ldbl_opt.h>
-
- #include "iolibio.h"
-@@ -523,8 +527,20 @@ extern void _IO_old_init (_IO_FILE *fp, int flags) __THROW;
-
-
- #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-+
-+/* _IO_is_wide (fp) is roughly equivalent to '_IO_fwide (fp, 0) > 0',
-+ except that when OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, it
-+ expands to a constant, allowing the compiler to realize that it can
-+ eliminate code that references wide stream handling functions.
-+ This, in turn, allows us to omit them. */
-+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
-+# define _IO_is_wide(_f) ((_f)->_mode > 0)
-+#else
-+# define _IO_is_wide(_f) (0)
-+#endif
-+
- # define _IO_do_flush(_f) \
-- ((_f)->_mode <= 0 \
-+ (! _IO_is_wide (_f) \
- ? _IO_do_write(_f, (_f)->_IO_write_base, \
- (_f)->_IO_write_ptr-(_f)->_IO_write_base) \
- : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base, \
-diff --git a/libio/wdummyfileops.c b/libio/wdummyfileops.c
-new file mode 100644
-index 0000000..c0150b8
---- /dev/null
-+++ b/libio/wdummyfileops.c
-@@ -0,0 +1,161 @@
-+/* Copyright (C) 2007 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA.
-+
-+ As a special exception, if you link the code in this file with
-+ files compiled with a GNU compiler to produce an executable,
-+ that does not cause the resulting executable to be covered by
-+ the GNU Lesser General Public License. This exception does not
-+ however invalidate any other reasons why the executable file
-+ might be covered by the GNU Lesser General Public License.
-+ This exception applies to code released by its copyright holders
-+ in files containing the exception. */
-+
-+#include <assert.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <libioP.h>
-+
-+static void __THROW __attribute__ ((__noreturn__))
-+_IO_wfile_wide_char_support_disabled (void)
-+{
-+ static const char errstr[]
-+ = ("The application tried to use wide character I/O, but libc.so"
-+ " was compiled\n"
-+ "with the OPTION_POSIX_C_LANG_WIDE_CHAR option group disabled.\n");
-+ __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
-+ abort ();
-+}
-+
-+static void
-+_IO_wfile_disabled_void_int (_IO_FILE *fp, int x)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static int
-+_IO_wfile_disabled_int_int (_IO_FILE *fp, int x)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static int
-+_IO_wfile_disabled_int_none (_IO_FILE *fp)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static _IO_size_t
-+_IO_wfile_disabled_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static _IO_size_t
-+_IO_wfile_disabled_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static _IO_off64_t
-+_IO_wfile_disabled_seekoff (_IO_FILE *fp, _IO_off64_t off, int dir, int mode)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static _IO_off64_t
-+_IO_wfile_disabled_seekpos (_IO_FILE *fp, _IO_off64_t pos, int flags)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static _IO_FILE *
-+_IO_wfile_disabled_setbuf (_IO_FILE *fp, char *buffer, _IO_ssize_t length)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static _IO_ssize_t
-+_IO_wfile_disabled_read (_IO_FILE *fp, void *buffer, _IO_ssize_t length)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static _IO_ssize_t
-+_IO_wfile_disabled_write (_IO_FILE *fp, const void *buffer, _IO_ssize_t length)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static _IO_off64_t
-+_IO_wfile_disabled_seek (_IO_FILE *fp, _IO_off64_t offset, int mode)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static int
-+_IO_wfile_disabled_close (_IO_FILE *fp)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static int
-+_IO_wfile_disabled_stat (_IO_FILE *fp, void *buf)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static int
-+_IO_wfile_disabled_showmanyc (_IO_FILE *fp)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static void
-+_IO_wfile_disabled_imbue (_IO_FILE *fp, void *locale)
-+{
-+ _IO_wfile_wide_char_support_disabled ();
-+}
-+
-+static const struct _IO_jump_t _IO_wfile_jumps_disabled =
-+{
-+ JUMP_INIT_DUMMY,
-+ JUMP_INIT(finish, _IO_wfile_disabled_void_int),
-+ JUMP_INIT(overflow, _IO_wfile_disabled_int_int),
-+ JUMP_INIT(underflow, _IO_wfile_disabled_int_none),
-+ JUMP_INIT(uflow, _IO_wfile_disabled_int_none),
-+ JUMP_INIT(pbackfail, _IO_wfile_disabled_int_int),
-+ JUMP_INIT(xsputn, _IO_wfile_disabled_xsputn),
-+ JUMP_INIT(xsgetn, _IO_wfile_disabled_xsgetn),
-+ JUMP_INIT(seekoff, _IO_wfile_disabled_seekoff),
-+ JUMP_INIT(seekpos, _IO_wfile_disabled_seekpos),
-+ JUMP_INIT(setbuf, _IO_wfile_disabled_setbuf),
-+ JUMP_INIT(sync, _IO_wfile_disabled_int_none),
-+ JUMP_INIT(doallocate, _IO_wfile_disabled_int_none),
-+ JUMP_INIT(read, _IO_wfile_disabled_read),
-+ JUMP_INIT(write, _IO_wfile_disabled_write),
-+ JUMP_INIT(seek, _IO_wfile_disabled_seek),
-+ JUMP_INIT(close, _IO_wfile_disabled_close),
-+ JUMP_INIT(stat, _IO_wfile_disabled_stat),
-+ JUMP_INIT(showmanyc, _IO_wfile_disabled_showmanyc),
-+ JUMP_INIT(imbue, _IO_wfile_disabled_imbue)
-+};
-+
-+strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps)
-+libc_hidden_data_def (_IO_wfile_jumps)
-+strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_mmap)
-+strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_maybe_mmap)
-diff --git a/locale/C-ctype.c b/locale/C-ctype.c
-index aa5f19f..06be081 100644
---- a/locale/C-ctype.c
-+++ b/locale/C-ctype.c
-@@ -19,8 +19,11 @@
- #include "localeinfo.h"
- #include <endian.h>
- #include <stdint.h>
-+#include <gnu/option-groups.h>
-
-+#if __OPTION_EGLIBC_LOCALE_CODE
- #include "C-translit.h"
-+#endif
-
- /* This table's entries are taken from POSIX.2 Table 2-6
- ``LC_CTYPE Category Definition in the POSIX Locale''.
-@@ -634,6 +637,7 @@ const struct __locale_data _nl_C_LC_CTYPE attribute_hidden =
- { .word = L'7' },
- { .word = L'8' },
- { .word = L'9' },
-+#if __OPTION_EGLIBC_LOCALE_CODE
- /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
- { .word = NTRANSLIT },
- /* _NL_CTYPE_TRANSLIT_FROM_IDX */
-@@ -644,6 +648,22 @@ const struct __locale_data _nl_C_LC_CTYPE attribute_hidden =
- { .wstr = translit_to_idx },
- /* _NL_CTYPE_TRANSLIT_TO_TBL */
- { .wstr = (uint32_t *) translit_to_tbl },
-+#else
-+ /* If the locale code isn't enabled, we don't have the
-+ transliteration code in iconv/gconv_trans.c anyway, so there's
-+ no need for the transliteration tables here. We'll fall back
-+ on the default missing replacement, '?'. */
-+ /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
-+ { .word = 0 },
-+ /* _NL_CTYPE_TRANSLIT_FROM_IDX */
-+ { .wstr = NULL },
-+ /* _NL_CTYPE_TRANSLIT_FROM_TBL */
-+ { .wstr = NULL },
-+ /* _NL_CTYPE_TRANSLIT_TO_IDX */
-+ { .wstr = NULL },
-+ /* _NL_CTYPE_TRANSLIT_TO_TBL */
-+ { .wstr = NULL },
-+#endif
- /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN */
- { .word = 1 },
- /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING */
-diff --git a/locale/Makefile b/locale/Makefile
-index f1b4343..599a1a9 100644
---- a/locale/Makefile
-+++ b/locale/Makefile
-@@ -18,27 +18,43 @@
- #
- # Makefile for locales.
- #
-+include ../option-groups.mak
-+
- subdir := locale
-
- include ../Makeconfig
-
- headers = locale.h bits/locale.h langinfo.h xlocale.h
--routines = setlocale findlocale loadlocale loadarchive \
-- localeconv nl_langinfo nl_langinfo_l mb_cur_max \
-- newlocale duplocale freelocale uselocale
--tests = tst-C-locale tst-locname tst-duplocale
-+# catnames is needed by OPTION_EGLIBC_LOCALE_CODE and by the 'intl' code.
-+# If we put the latter in an option group, too, we can omit catnames
-+# when both option groups are disabled. libstdc++-v3 needs mb_cur_max.
-+routines-y := catnames mb_cur_max
-+routines-$(OPTION_EGLIBC_LOCALE_CODE) \
-+ += setlocale findlocale loadlocale loadarchive \
-+ localeconv nl_langinfo nl_langinfo_l \
-+ newlocale duplocale freelocale uselocale
-+ifneq (y,$(OPTION_EGLIBC_LOCALE_CODE))
-+routines-y += dummy-setlocale
-+endif
-+tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-C-locale tst-locname tst-duplocale
- categories = ctype messages monetary numeric time paper name \
- address telephone measurement identification collate
--aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \
-- xlocale localename global-locale coll-lookup
--others = localedef locale
-+# C-messages belongs in an intl option group.
-+aux-y := C-ctype C-time \
-+ SYS_libc C_name xlocale global-locale coll-lookup
-+aux-$(OPTION_EGLIBC_LOCALE_CODE) \
-+ += $(filter-out $(aux-y), \
-+ $(categories:%=lc-%) $(categories:%=C-%)) \
-+ localename
-+others-$(OPTION_EGLIBC_LOCALE_CODE) = localedef locale
- #others-static = localedef locale
--install-bin = localedef locale
--extra-objs = $(localedef-modules:=.o) $(localedef-aux:=.o) \
-+install-bin = $(others-y)
-+extra-objs-$(OPTION_EGLIBC_LOCALE_CODE) \
-+ = $(localedef-modules:=.o) $(localedef-aux:=.o) \
- $(locale-modules:=.o) $(lib-modules:=.o)
-
--extra-libs = libBrokenLocale
--extra-libs-others = $(extra-libs)
-+extra-libs-$(OPTION_EGLIBC_LOCALE_CODE) = libBrokenLocale
-+extra-libs-others = $(extra-libs-y)
-
- libBrokenLocale-routines = broken_cur_max
-
-@@ -93,6 +109,9 @@ CPPFLAGS-locale-programs = -DLOCALE_PATH='$(localepath)' \
- CFLAGS-charmap.c = -Wno-write-strings -Wno-char-subscripts
- CFLAGS-locfile.c = -Wno-write-strings -Wno-char-subscripts
- CFLAGS-charmap-dir.c = -Wno-write-strings
-+ifneq (y,$(OPTION_EGLIBC_SPAWN))
-+CFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
-+endif
-
- # Set libof-* for each routine.
- cpp-srcs-left := $(localedef-modules) $(localedef-aux) $(locale-modules) \
-diff --git a/locale/catnames.c b/locale/catnames.c
-new file mode 100644
-index 0000000..9fad357
---- /dev/null
-+++ b/locale/catnames.c
-@@ -0,0 +1,48 @@
-+/* Copyright (C) 2006 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA. */
-+
-+#include "localeinfo.h"
-+
-+/* Define an array of category names (also the environment variable names). */
-+const union catnamestr_t _nl_category_names attribute_hidden =
-+ {
-+ {
-+#define DEFINE_CATEGORY(category, category_name, items, a) \
-+ category_name,
-+#include "categories.def"
-+#undef DEFINE_CATEGORY
-+ }
-+ };
-+
-+const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
-+ {
-+#define DEFINE_CATEGORY(category, category_name, items, a) \
-+ [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
-+#include "categories.def"
-+#undef DEFINE_CATEGORY
-+ };
-+
-+/* An array of their lengths, for convenience. */
-+const uint8_t _nl_category_name_sizes[] attribute_hidden =
-+ {
-+#define DEFINE_CATEGORY(category, category_name, items, a) \
-+ [category] = sizeof (category_name) - 1,
-+#include "categories.def"
-+#undef DEFINE_CATEGORY
-+ [LC_ALL] = sizeof ("LC_ALL") - 1
-+ };
-diff --git a/locale/dummy-setlocale.c b/locale/dummy-setlocale.c
-new file mode 100644
-index 0000000..219964a
---- /dev/null
-+++ b/locale/dummy-setlocale.c
-@@ -0,0 +1,33 @@
-+/* Copyright (C) 2006 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA. */
-+
-+#include <string.h>
-+#include <locale.h>
-+
-+char *
-+setlocale (int category, const char *locale)
-+{
-+ if (! locale
-+ || locale[0] == '\0'
-+ || strcmp (locale, "C") == 0
-+ || strcmp (locale, "POSIX") == 0)
-+ return (char *) "C";
-+ else
-+ return NULL;
-+}
-+libc_hidden_def (setlocale)
-diff --git a/locale/localeinfo.h b/locale/localeinfo.h
-index bdab9fe..a7516c0 100644
---- a/locale/localeinfo.h
-+++ b/locale/localeinfo.h
-@@ -232,7 +232,7 @@ __libc_tsd_define (extern, __locale_t, LOCALE)
- unused. We can manage this playing some tricks with weak references.
- But with thread-local locale settings, it becomes quite ungainly unless
- we can use __thread variables. So only in that case do we attempt this. */
--#ifndef SHARED
-+#if !defined SHARED && !defined IN_GLIBC_LOCALEDEF
- # include <tls.h>
- # define NL_CURRENT_INDIRECT 1
- #endif
-diff --git a/locale/programs/charmap-dir.c b/locale/programs/charmap-dir.c
-index cf7adea..ef3b811 100644
---- a/locale/programs/charmap-dir.c
-+++ b/locale/programs/charmap-dir.c
-@@ -19,7 +19,9 @@
- #include <error.h>
- #include <fcntl.h>
- #include <libintl.h>
-+#ifndef NO_UNCOMPRESS
- #include <spawn.h>
-+#endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-@@ -156,6 +158,7 @@ charmap_closedir (CHARMAP_DIR *cdir)
- return closedir (dir);
- }
-
-+#ifndef NO_UNCOMPRESS
- /* Creates a subprocess decompressing the given pathname, and returns
- a stream reading its output (the decompressed data). */
- static
-@@ -204,6 +207,7 @@ fopen_uncompressed (const char *pathname, const char *compressor)
- }
- return NULL;
- }
-+#endif
-
- /* Opens a charmap for reading, given its name (not an alias name). */
- FILE *
-@@ -226,6 +230,7 @@ charmap_open (const char *directory, const char *name)
- if (stream != NULL)
- return stream;
-
-+#ifndef NO_UNCOMPRESS
- memcpy (p, ".gz", 4);
- stream = fopen_uncompressed (pathname, "gzip");
- if (stream != NULL)
-@@ -235,6 +240,7 @@ charmap_open (const char *directory, const char *name)
- stream = fopen_uncompressed (pathname, "bzip2");
- if (stream != NULL)
- return stream;
-+#endif
-
- return NULL;
- }
-diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
-index a39a94f..16e9039 100644
---- a/locale/programs/ld-collate.c
-+++ b/locale/programs/ld-collate.c
-@@ -351,7 +351,7 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
- }
- if (wcs != NULL)
- {
-- size_t nwcs = wcslen ((wchar_t *) wcs);
-+ size_t nwcs = wcslen_uint32 (wcs);
- uint32_t zero = 0;
- /* Handle <U0000> as a single character. */
- if (nwcs == 0)
-@@ -1777,8 +1777,7 @@ symbol `%s' has the same encoding as"), (*eptr)->name);
-
- if ((*eptr)->nwcs == runp->nwcs)
- {
-- int c = wmemcmp ((wchar_t *) (*eptr)->wcs,
-- (wchar_t *) runp->wcs, runp->nwcs);
-+ int c = wmemcmp_uint32 ((*eptr)->wcs, runp->wcs, runp->nwcs);
-
- if (c == 0)
- {
-@@ -2011,9 +2010,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
- one consecutive entry. */
- if (runp->wcnext != NULL
- && runp->nwcs == runp->wcnext->nwcs
-- && wmemcmp ((wchar_t *) runp->wcs,
-- (wchar_t *)runp->wcnext->wcs,
-- runp->nwcs - 1) == 0
-+ && wmemcmp_uint32 (runp->wcs,
-+ runp->wcnext->wcs,
-+ runp->nwcs - 1) == 0
- && (runp->wcs[runp->nwcs - 1]
- == runp->wcnext->wcs[runp->nwcs - 1] + 1))
- {
-@@ -2037,9 +2036,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
- runp = runp->wcnext;
- while (runp->wcnext != NULL
- && runp->nwcs == runp->wcnext->nwcs
-- && wmemcmp ((wchar_t *) runp->wcs,
-- (wchar_t *)runp->wcnext->wcs,
-- runp->nwcs - 1) == 0
-+ && wmemcmp_uint32 (runp->wcs,
-+ runp->wcnext->wcs,
-+ runp->nwcs - 1) == 0
- && (runp->wcs[runp->nwcs - 1]
- == runp->wcnext->wcs[runp->nwcs - 1] + 1));
-
-diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
-index 3f464ef..b7b6b51 100644
---- a/locale/programs/ld-ctype.c
-+++ b/locale/programs/ld-ctype.c
-@@ -926,7 +926,7 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
- allocate_arrays (ctype, charmap, ctype->repertoire);
-
- default_missing_len = (ctype->default_missing
-- ? wcslen ((wchar_t *) ctype->default_missing)
-+ ? wcslen_uint32 (ctype->default_missing)
- : 0);
-
- init_locale_data (&file, nelems);
-@@ -1937,7 +1937,7 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype,
- ignore = 1;
- else
- /* This value is usable. */
-- obstack_grow (ob, to_wstr, wcslen ((wchar_t *) to_wstr) * 4);
-+ obstack_grow (ob, to_wstr, wcslen_uint32 (to_wstr) * 4);
-
- first = 0;
- }
-@@ -2471,8 +2471,8 @@ with character code range values one must use the absolute ellipsis `...'"));
- }
-
- handle_tok_digit:
-- class_bit = _ISwdigit;
-- class256_bit = _ISdigit;
-+ class_bit = BITw (tok_digit);
-+ class256_bit = BIT (tok_digit);
- handle_digits = 1;
- goto read_charclass;
-
-@@ -3929,8 +3929,7 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
-
- while (idx < number)
- {
-- int res = wcscmp ((const wchar_t *) sorted[idx]->from,
-- (const wchar_t *) runp->from);
-+ int res = wcscmp_uint32 (sorted[idx]->from, runp->from);
- if (res == 0)
- {
- replace = 1;
-@@ -3967,11 +3966,11 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
- for (size_t cnt = 0; cnt < number; ++cnt)
- {
- struct translit_to_t *srunp;
-- from_len += wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
-+ from_len += wcslen_uint32 (sorted[cnt]->from) + 1;
- srunp = sorted[cnt]->to;
- while (srunp != NULL)
- {
-- to_len += wcslen ((const wchar_t *) srunp->str) + 1;
-+ to_len += wcslen_uint32 (srunp->str) + 1;
- srunp = srunp->next;
- }
- /* Plus one for the extra NUL character marking the end of
-@@ -3995,18 +3994,18 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
- ctype->translit_from_idx[cnt] = from_len;
- ctype->translit_to_idx[cnt] = to_len;
-
-- len = wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
-- wmemcpy ((wchar_t *) &ctype->translit_from_tbl[from_len],
-- (const wchar_t *) sorted[cnt]->from, len);
-+ len = wcslen_uint32 (sorted[cnt]->from) + 1;
-+ wmemcpy_uint32 (&ctype->translit_from_tbl[from_len],
-+ sorted[cnt]->from, len);
- from_len += len;
-
- ctype->translit_to_idx[cnt] = to_len;
- srunp = sorted[cnt]->to;
- while (srunp != NULL)
- {
-- len = wcslen ((const wchar_t *) srunp->str) + 1;
-- wmemcpy ((wchar_t *) &ctype->translit_to_tbl[to_len],
-- (const wchar_t *) srunp->str, len);
-+ len = wcslen_uint32 (srunp->str) + 1;
-+ wmemcpy_uint32 (&ctype->translit_to_tbl[to_len],
-+ srunp->str, len);
- to_len += len;
- srunp = srunp->next;
- }
-diff --git a/locale/programs/ld-messages.c b/locale/programs/ld-messages.c
-index ec1a80b..736eed8 100644
---- a/locale/programs/ld-messages.c
-+++ b/locale/programs/ld-messages.c
-@@ -25,6 +25,7 @@
- #include <string.h>
- #include <stdint.h>
- #include <sys/uio.h>
-+#include <gnu/option-groups.h>
-
- #include <assert.h>
-
-@@ -124,6 +125,7 @@ No definition for %s category found"), "LC_MESSAGES"));
- }
- else
- {
-+#if __OPTION_POSIX_REGEXP
- int result;
- regex_t re;
-
-@@ -140,6 +142,7 @@ No definition for %s category found"), "LC_MESSAGES"));
- }
- else if (result != 0)
- regfree (&re);
-+#endif
- }
-
- if (messages->noexpr == NULL)
-@@ -158,6 +161,7 @@ No definition for %s category found"), "LC_MESSAGES"));
- }
- else
- {
-+#if __OPTION_POSIX_REGEXP
- int result;
- regex_t re;
-
-@@ -174,6 +178,7 @@ No definition for %s category found"), "LC_MESSAGES"));
- }
- else if (result != 0)
- regfree (&re);
-+#endif
- }
- }
-
-diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
-index db490c6..75dc505 100644
---- a/locale/programs/ld-time.c
-+++ b/locale/programs/ld-time.c
-@@ -215,8 +215,10 @@ No definition for %s category found"), "LC_TIME"));
- }
- else
- {
-+ static const uint32_t wt_fmt_ampm[]
-+ = { '%','I',':','%','M',':','%','S',' ','%','p',0 };
- time->t_fmt_ampm = "%I:%M:%S %p";
-- time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p";
-+ time->wt_fmt_ampm = wt_fmt_ampm;
- }
- }
-
-@@ -226,7 +228,7 @@ No definition for %s category found"), "LC_TIME"));
- const int days_per_month[12] = { 31, 29, 31, 30, 31, 30,
- 31, 31, 30, 31 ,30, 31 };
- size_t idx;
-- wchar_t *wstr;
-+ uint32_t *wstr;
-
- time->era_entries =
- (struct era_data *) xmalloc (time->num_era
-@@ -464,18 +466,18 @@ No definition for %s category found"), "LC_TIME"));
- }
-
- /* Now generate the wide character name and format. */
-- wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */
-- wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end offset */
-- wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end start */
-- wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end end */
-+ wstr = wcschr_uint32 (time->wera[idx], L':'); /* end direction */
-+ wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end offset */
-+ wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end start */
-+ wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end end */
- if (wstr != NULL)
- {
-- time->era_entries[idx].wname = (uint32_t *) wstr + 1;
-- wstr = wcschr (wstr + 1, L':'); /* end name */
-+ time->era_entries[idx].wname = wstr + 1;
-+ wstr = wcschr_uint32 (wstr + 1, L':'); /* end name */
- if (wstr != NULL)
- {
- *wstr = L'\0';
-- time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
-+ time->era_entries[idx].wformat = wstr + 1;
- }
- else
- time->era_entries[idx].wname =
-@@ -530,7 +532,16 @@ No definition for %s category found"), "LC_TIME"));
- if (time->date_fmt == NULL)
- time->date_fmt = "%a %b %e %H:%M:%S %Z %Y";
- if (time->wdate_fmt == NULL)
-- time->wdate_fmt = (const uint32_t *) L"%a %b %e %H:%M:%S %Z %Y";
-+ {
-+ static const uint32_t wdate_fmt[] =
-+ { '%','a',' ',
-+ '%','b',' ',
-+ '%','e',' ',
-+ '%','H',':','%','M',':','%','S',' ',
-+ '%','Z',' ',
-+ '%','Y',0 };
-+ time->wdate_fmt = wdate_fmt;
-+ }
- }
-
-
-diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c
-index 2e05130..653b68c 100644
---- a/locale/programs/linereader.c
-+++ b/locale/programs/linereader.c
-@@ -595,7 +595,7 @@ get_string (struct linereader *lr, const struct charmap_t *charmap,
- {
- int return_widestr = lr->return_widestr;
- char *buf;
-- wchar_t *buf2 = NULL;
-+ uint32_t *buf2 = NULL;
- size_t bufact;
- size_t bufmax = 56;
-
-diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
-index 2a0f2aa..583d233 100644
---- a/locale/programs/localedef.c
-+++ b/locale/programs/localedef.c
-@@ -114,6 +114,7 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
- #define OPT_LIST_ARCHIVE 309
- #define OPT_LITTLE_ENDIAN 400
- #define OPT_BIG_ENDIAN 401
-+#define OPT_UINT32_ALIGN 402
-
- /* Definitions of arguments for argp functions. */
- static const struct argp_option options[] =
-@@ -150,6 +151,8 @@ static const struct argp_option options[] =
- N_("Generate little-endian output") },
- { "big-endian", OPT_BIG_ENDIAN, NULL, 0,
- N_("Generate big-endian output") },
-+ { "uint32-align", OPT_UINT32_ALIGN, "ALIGNMENT", 0,
-+ N_("Set the target's uint32_t alignment in bytes (default 4)") },
- { NULL, 0, NULL, 0, NULL }
- };
-
-@@ -239,12 +242,14 @@ main (int argc, char *argv[])
- ctype locale. (P1003.2 4.35.5.2) */
- setlocale (LC_CTYPE, "POSIX");
-
-+#ifndef NO_SYSCONF
- /* Look whether the system really allows locale definitions. POSIX
- defines error code 3 for this situation so I think it must be
- a fatal error (see P1003.2 4.35.8). */
- if (sysconf (_SC_2_LOCALEDEF) < 0)
- WITH_CUR_LOCALE (error (3, 0, _("\
- FATAL: system does not define `_POSIX2_LOCALEDEF'")));
-+#endif
-
- /* Process charmap file. */
- charmap = charmap_read (charmap_file, verbose, 1, be_quiet, 1);
-@@ -338,6 +343,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
- case OPT_BIG_ENDIAN:
- set_big_endian (true);
- break;
-+ case OPT_UINT32_ALIGN:
-+ uint32_align_mask = strtol (arg, NULL, 0) - 1;
-+ break;
- case 'c':
- force_output = 1;
- break;
-diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c
-index 33da52e..f790c4c 100644
---- a/locale/programs/locfile.c
-+++ b/locale/programs/locfile.c
-@@ -544,6 +544,9 @@ compare_files (const char *filename1, const char *filename2, size_t size,
- machine running localedef. */
- bool swap_endianness_p;
-
-+/* The target's value of __align__(uint32_t) - 1. */
-+unsigned int uint32_align_mask = 3;
-+
- /* When called outside a start_locale_structure/end_locale_structure
- or start_locale_prelude/end_locale_prelude block, record that the
- next byte in FILE's obstack will be the first byte of a new element.
-@@ -621,7 +624,7 @@ add_locale_string (struct locale_file *file, const char *string)
- void
- add_locale_wstring (struct locale_file *file, const uint32_t *string)
- {
-- add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1);
-+ add_locale_uint32_array (file, string, wcslen_uint32 (string) + 1);
- }
-
- /* Record that FILE's next element is the 32-bit integer VALUE. */
-diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h
-index 6fc441b..118b171 100644
---- a/locale/programs/locfile.h
-+++ b/locale/programs/locfile.h
-@@ -71,6 +71,8 @@ extern void write_all_categories (struct localedef_t *definitions,
-
- extern bool swap_endianness_p;
-
-+extern unsigned int uint32_align_mask;
-+
- /* Change the output to be big-endian if BIG_ENDIAN is true and
- little-endian otherwise. */
- static inline void
-@@ -89,7 +91,8 @@ maybe_swap_uint32 (uint32_t value)
- }
-
- /* Likewise, but munge an array of N uint32_ts starting at ARRAY. */
--static inline void
-+static void
-+__attribute__ ((unused))
- maybe_swap_uint32_array (uint32_t *array, size_t n)
- {
- if (swap_endianness_p)
-@@ -99,7 +102,8 @@ maybe_swap_uint32_array (uint32_t *array, size_t n)
-
- /* Like maybe_swap_uint32_array, but the array of N elements is at
- the end of OBSTACK's current object. */
--static inline void
-+static void
-+__attribute__ ((unused))
- maybe_swap_uint32_obstack (struct obstack *obstack, size_t n)
- {
- maybe_swap_uint32_array ((uint32_t *) obstack_next_free (obstack) - n, n);
-@@ -276,4 +280,55 @@ extern void identification_output (struct localedef_t *locale,
- const struct charmap_t *charmap,
- const char *output_path);
-
-+static size_t wcslen_uint32 (const uint32_t *str) __attribute__ ((unused));
-+static uint32_t * wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
-+static uint32_t * wcschr_uint32 (const uint32_t *s, uint32_t ch) __attribute__ ((unused));
-+static int wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2) __attribute__ ((unused));
-+static int wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
-+
-+static size_t
-+wcslen_uint32 (const uint32_t *str)
-+{
-+ size_t len = 0;
-+ while (str[len] != 0)
-+ len++;
-+ return len;
-+}
-+
-+static int
-+wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n)
-+{
-+ while (n-- != 0)
-+ {
-+ int diff = *s1++ - *s2++;
-+ if (diff != 0)
-+ return diff;
-+ }
-+ return 0;
-+}
-+
-+static int
-+wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2)
-+{
-+ while (*s1 != 0 && *s1 == *s2)
-+ s1++, s2++;
-+ return *s1 - *s2;
-+}
-+
-+static uint32_t *
-+wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n)
-+{
-+ return memcpy (s1, s2, n * sizeof (uint32_t));
-+}
-+
-+static uint32_t *
-+wcschr_uint32 (const uint32_t *s, uint32_t ch)
-+{
-+ do
-+ if (*s == ch)
-+ return (uint32_t *) s;
-+ while (*s++ != 0);
-+ return 0;
-+}
-+
- #endif /* locfile.h */
-diff --git a/locale/setlocale.c b/locale/setlocale.c
-index fa9cb3a..8eee284 100644
---- a/locale/setlocale.c
-+++ b/locale/setlocale.c
-@@ -64,36 +64,6 @@ static char *const _nl_current_used[] =
- #endif
-
-
--/* Define an array of category names (also the environment variable names). */
--const union catnamestr_t _nl_category_names attribute_hidden =
-- {
-- {
--#define DEFINE_CATEGORY(category, category_name, items, a) \
-- category_name,
--#include "categories.def"
--#undef DEFINE_CATEGORY
-- }
-- };
--
--const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
-- {
--#define DEFINE_CATEGORY(category, category_name, items, a) \
-- [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
--#include "categories.def"
--#undef DEFINE_CATEGORY
-- };
--
--/* An array of their lengths, for convenience. */
--const uint8_t _nl_category_name_sizes[] attribute_hidden =
-- {
--#define DEFINE_CATEGORY(category, category_name, items, a) \
-- [category] = sizeof (category_name) - 1,
--#include "categories.def"
--#undef DEFINE_CATEGORY
-- [LC_ALL] = sizeof ("LC_ALL") - 1
-- };
--
--
- #ifdef NL_CURRENT_INDIRECT
- # define WEAK_POSTLOAD(postload) weak_extern (postload)
- #else
-diff --git a/locale/xlocale.c b/locale/xlocale.c
-index fec4564..f00269c 100644
---- a/locale/xlocale.c
-+++ b/locale/xlocale.c
-@@ -18,6 +18,7 @@
- <http://www.gnu.org/licenses/>. */
-
- #include <locale.h>
-+#include <gnu/option-groups.h>
- #include "localeinfo.h"
-
- #define DEFINE_CATEGORY(category, category_name, items, a) \
-@@ -25,6 +26,19 @@ extern struct __locale_data _nl_C_##category;
- #include "categories.def"
- #undef DEFINE_CATEGORY
-
-+/* If the locale support code isn't enabled, don't generate strong
-+ reference to the C locale_data structures here; let the Makefile
-+ decide which ones to include. (In the static linking case, the
-+ strong reference to the 'class', 'toupper', and 'tolower' tables
-+ will cause C-ctype.o to be brought in, as it should be, even when
-+ the reference to _nl_C_LC_CTYPE will be weak.) */
-+#if ! __OPTION_EGLIBC_LOCALE_CODE
-+# define DEFINE_CATEGORY(category, category_name, items, a) \
-+ weak_extern (_nl_C_##category)
-+# include "categories.def"
-+# undef DEFINE_CATEGORY
-+#endif
-+
- /* Defined in locale/C-ctype.c. */
- extern const char _nl_C_LC_CTYPE_class[] attribute_hidden;
- extern const char _nl_C_LC_CTYPE_toupper[] attribute_hidden;
-@@ -52,3 +66,26 @@ const struct __locale_struct _nl_C_locobj attribute_hidden =
- .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
- .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
- };
-+
-+
-+#if ! __OPTION_EGLIBC_LOCALE_CODE
-+/* When locale code is enabled, these are each defined in the
-+ appropriate lc-CATEGORY.c file, so that static links (when __thread
-+ is supported) bring in only those lc-CATEGORY.o files for
-+ categories the program actually uses; look for NL_CURRENT_INDIRECT
-+ in localeinfo.h.
-+
-+ When locale code is disabled, the _nl_C_CATEGORY objects are the
-+ only possible referents. At the moment, there isn't a way to get
-+ __OPTION_EGLIBC_LOCALE_CODE defined in every compilation unit that
-+ #includes localeinfo.h, so we can't just turn off
-+ NL_CURRENT_INDIRECT. So we'll define the _nl_current_CATEGORY
-+ pointers here. */
-+#if defined (NL_CURRENT_INDIRECT)
-+#define DEFINE_CATEGORY(category, category_name, items, a) \
-+ __thread struct __locale_data * const *_nl_current_##category \
-+ attribute_hidden = &_nl_C_locobj.__locales[category];
-+#include "categories.def"
-+#undef DEFINE_CATEGORY
-+#endif
-+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
-diff --git a/localedata/Makefile b/localedata/Makefile
-index ebf6ac9..1870753 100644
---- a/localedata/Makefile
-+++ b/localedata/Makefile
-@@ -21,12 +21,22 @@ subdir := localedata
-
- include ../Makeconfig
-
--# List with all available character set descriptions.
--charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
-+include ../option-groups.mak
-
- # List with all available character set descriptions.
--locales := $(wildcard locales/*)
--
-+all-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
-+
-+all-locales := $(wildcard locales/*)
-+
-+# If the EGLIBC_LOCALES option group is not enabled, trim the
-+# list of charmap and locale source files.
-+ifeq ($(OPTION_EGLIBC_LOCALES),y)
-+charmaps := $(all-charmaps)
-+locales := $(all-locales)
-+else
-+charmaps :=
-+locales := locales/POSIX
-+endif
-
- subdir-dirs = tests-mbwc
- vpath %.c tests-mbwc
-@@ -71,14 +81,20 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl \
- tst_wcsxfrm tst_wctob tst_wctomb tst_wctrans \
- tst_wctype tst_wcwidth
-
--tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
-+# Since these tests build their own locale files, they're not
-+# dependent on the OPTION_EGLIBC_LOCALES option group. But they do
-+# need the locale functions to be present.
-+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
-+ += $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
- tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \
- tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
- tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \
- tst-wctype
-+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
- tests-static = bug-setlocale1-static
- tests += $(tests-static)
--ifeq (yes,$(build-shared))
-+endif
-+ifeq (yesy,$(build-shared)$(OPTION_EGLIBC_LOCALE_CODE))
- ifneq (no,$(PERL))
- tests-special += $(objpfx)mtrace-tst-leaks.out
- endif
-@@ -95,6 +111,7 @@ tests: $(objdir)/iconvdata/gconv-modules
- tests-static += tst-langinfo-static
-
- ifeq ($(run-built-tests),yes)
-+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
- tests-special += $(objpfx)sort-test.out $(objpfx)tst-fmon.out \
- $(objpfx)tst-locale.out $(objpfx)tst-rpmatch.out \
- $(objpfx)tst-trans.out $(objpfx)tst-ctype.out \
-@@ -109,6 +126,7 @@ LOCALES := de_DE.ISO-8859-1 de_DE.UTF-8 en_US.ANSI_X3.4-1968 \
- tr_TR.ISO-8859-9 en_GB.UTF-8 uk_UA.UTF-8
- include ../gen-locales.mk
- endif
-+endif
-
- include ../Rules
-
-@@ -191,6 +209,11 @@ endif
-
- include SUPPORTED
-
-+# Only install locale data if OPTION_EGLIBC_LOCALES is selected.
-+ifneq ($(OPTION_EGLIBC_LOCALES),y)
-+SUPPORTED-LOCALES :=
-+endif
-+
- INSTALL-SUPPORTED-LOCALES=$(addprefix install-, $(SUPPORTED-LOCALES))
-
- # Sometimes the whole collection of locale files should be installed.
-diff --git a/login/Makefile b/login/Makefile
-index 0f4bb22..4036ddb 100644
---- a/login/Makefile
-+++ b/login/Makefile
-@@ -18,6 +18,7 @@
- #
- # Sub-makefile for login portion of the library.
- #
-+include ../option-groups.mak
-
- subdir := login
-
-@@ -25,14 +26,16 @@ include ../Makeconfig
-
- headers := utmp.h bits/utmp.h lastlog.h pty.h
-
--routines := getlogin getlogin_r setlogin getlogin_r_chk \
-- getutent getutent_r getutid getutline getutid_r getutline_r \
-- utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
-- ptsname_r_chk
-+routines := getpt grantpt unlockpt ptsname ptsname_r_chk
-+routines-$(OPTION_EGLIBC_UTMP) \
-+ += getutent getutent_r getutid getutline getutid_r getutline_r \
-+ utmp_file utmpname updwtmp
-+routines-$(OPTION_EGLIBC_GETLOGIN) += getlogin getlogin_r getlogin_r_chk
-+routines-$(OPTION_EGLIBC_BSD) += setlogin
-
- CFLAGS-grantpt.c = -DLIBEXECDIR='"$(libexecdir)"'
-
--others = utmpdump
-+others-$(OPTION_EGLIBC_UTMP) += utmpdump
-
- ifeq (yes,$(build-pt-chown))
- others += pt_chown
-@@ -46,8 +49,8 @@ vpath %.c programs
- tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin
-
- # Build the -lutil library with these extra functions.
--extra-libs := libutil
--extra-libs-others := $(extra-libs)
-+extra-libs-$(OPTION_EGLIBC_UTMP) := libutil
-+extra-libs-others := $(extra-libs-y)
-
- libutil-routines:= login login_tty logout logwtmp openpty forkpty
-
-diff --git a/malloc/Makefile b/malloc/Makefile
-index 67ed293..272ca4d 100644
---- a/malloc/Makefile
-+++ b/malloc/Makefile
-@@ -18,6 +18,8 @@
- #
- # Makefile for malloc routines
- #
-+include ../option-groups.mak
-+
- subdir := malloc
-
- include ../Makeconfig
-@@ -39,9 +41,15 @@ install-lib := libmcheck.a
- non-lib.a := libmcheck.a
-
- # Additional library.
-+ifeq ($(OPTION_EGLIBC_MEMUSAGE),y)
- extra-libs = libmemusage
- extra-libs-others = $(extra-libs)
-
-+ifdef OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
-+CPPFLAGS-memusage += -D__OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE=$(OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE)
-+endif
-+endif
-+
- libmemusage-routines = memusage
- libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
-
-@@ -71,7 +79,7 @@ endif
- # Unless we get a test for the availability of libgd which also works
- # for cross-compiling we disable the memusagestat generation in this
- # situation.
--ifneq ($(cross-compiling),yes)
-+ifeq ($(cross-compiling)$(OPTION_EGLIBC_MEMUSAGE),noy)
- # If the gd library is available we build the `memusagestat' program.
- ifneq ($(LIBGD),no)
- others: $(objpfx)memusage
-diff --git a/malloc/memusage.c b/malloc/memusage.c
-index a57ba8e..732ba9d 100644
---- a/malloc/memusage.c
-+++ b/malloc/memusage.c
-@@ -33,6 +33,7 @@
- #include <stdint.h>
- #include <sys/mman.h>
- #include <sys/time.h>
-+#include <gnu/option-groups.h>
-
- #include <memusage.h>
-
-@@ -93,7 +94,11 @@ static __thread uintptr_t start_sp;
- #define peak_stack peak_use[1]
- #define peak_total peak_use[2]
-
--#define DEFAULT_BUFFER_SIZE 32768
-+#ifndef __OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
-+# define DEFAULT_BUFFER_SIZE 32768
-+#else
-+# define DEFAULT_BUFFER_SIZE __OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
-+#endif
- static size_t buffer_size;
-
- static int fd = -1;
-diff --git a/malloc/memusage.sh b/malloc/memusage.sh
-index 8ab8cc2..d18f446 100755
---- a/malloc/memusage.sh
-+++ b/malloc/memusage.sh
-@@ -35,7 +35,7 @@ do_missing_arg() {
-
- # Print help message
- do_help() {
-- echo $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
-+ printf $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
- Profile memory usage of PROGRAM.
-
- -n,--progname=NAME Name of the program file to profile
-diff --git a/math/Makefile b/math/Makefile
-index 6388bae..ed1c511 100644
---- a/math/Makefile
-+++ b/math/Makefile
-@@ -21,6 +21,8 @@ subdir := math
-
- include ../Makeconfig
-
-+include ../option-groups.mak
-+
- # Installed header files.
- headers := math.h bits/mathcalls.h bits/mathinline.h bits/huge_val.h \
- bits/huge_valf.h bits/huge_vall.h bits/inf.h bits/nan.h \
-@@ -34,8 +36,8 @@ aux := setfpucw fpu_control
-
- # Build the -lm library.
-
--extra-libs := libm
--extra-libs-others = $(extra-libs)
-+extra-libs-$(OPTION_EGLIBC_LIBM) := libm
-+extra-libs-others-$(OPTION_EGLIBC_LIBM) = $(extra-libs-$(OPTION_EGLIBC_LIBM))
-
- libm-support = s_lib_version s_matherr s_signgam \
- fclrexcpt fgetexcptflg fraiseexcpt fsetexcptflg \
-diff --git a/misc/Makefile b/misc/Makefile
-index aecb0da..e6b7c23 100644
---- a/misc/Makefile
-+++ b/misc/Makefile
-@@ -19,6 +19,10 @@
- # Sub-makefile for misc portion of the library.
- #
-
-+# Some system-dependent implementations of these functions use option
-+# groups (see sysdeps/unix/sysv/linux/Makefile, for example).
-+include ../option-groups.mak
-+
- subdir := misc
-
- include ../Makeconfig
-@@ -46,40 +50,47 @@ routines := brk sbrk sstk ioctl \
- select pselect \
- acct chroot fsync sync fdatasync syncfs reboot \
- gethostid sethostid \
-- revoke vhangup \
-+ vhangup \
- swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \
- mkostemp mkostemp64 mkstemps mkstemps64 mkostemps mkostemps64 \
- ualarm usleep \
- gtty stty \
- ptrace \
-- fstab mntent mntent_r \
-+ mntent mntent_r \
- utimes lutimes futimes futimesat \
- truncate ftruncate truncate64 ftruncate64 \
-- chflags fchflags \
- insremque getttyent getusershell getpass ttyslot \
- syslog syscall daemon \
- mmap mmap64 munmap mprotect msync madvise mincore remap_file_pages\
- mlock munlock mlockall munlockall \
-- efgcvt efgcvt_r qefgcvt qefgcvt_r \
- hsearch hsearch_r tsearch lsearch \
- err error ustat \
-- getsysstats dirname regexp \
-+ getsysstats dirname \
- getloadavg getclktck \
- fgetxattr flistxattr fremovexattr fsetxattr getxattr \
- listxattr lgetxattr llistxattr lremovexattr lsetxattr \
- removexattr setxattr getauxval ifunc-impl-list
-
-+routines-$(OPTION_POSIX_REGEXP) += regexp
-+routines-$(OPTION_EGLIBC_FSTAB) += fstab
-+routines-$(OPTION_EGLIBC_BSD) += chflags fchflags revoke
-+routines-$(OPTION_EGLIBC_FCVT) += efgcvt efgcvt_r qefgcvt qefgcvt_r
-+
- generated += tst-error1.mtrace tst-error1-mem.out
-
- aux := init-misc
- install-lib := libg.a
- gpl2lgpl := error.c error.h
-
--tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
-- tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
-+tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
-+ tst-pselect tst-insremque tst-mntent2 bug-hsearch1
-+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += tst-error1
-+tests-$(OPTION_EGLIBC_FCVT) += tst-efgcvt
- ifeq ($(run-built-tests),yes)
-+ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
- tests-special += $(objpfx)tst-error1-mem.out
- endif
-+endif
-
- CFLAGS-select.c = -fexceptions -fasynchronous-unwind-tables
- CFLAGS-tsearch.c = $(uses-callbacks)
-diff --git a/misc/err.c b/misc/err.c
-index 7b98157..efce8d5 100644
---- a/misc/err.c
-+++ b/misc/err.c
-@@ -22,6 +22,7 @@
- #include <errno.h>
- #include <string.h>
- #include <stdio.h>
-+#include <gnu/option-groups.h>
-
- #include <wchar.h>
- #define flockfile(s) _IO_flockfile (s)
-@@ -37,6 +38,7 @@ extern char *__progname;
- va_end (ap); \
- }
-
-+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
- static void
- convert_and_print (const char *format, __gnuc_va_list ap)
- {
-@@ -81,6 +83,7 @@ convert_and_print (const char *format, __gnuc_va_list ap)
-
- __vfwprintf (stderr, wformat, ap);
- }
-+#endif
-
- void
- vwarnx (const char *format, __gnuc_va_list ap)
-@@ -88,9 +91,13 @@ vwarnx (const char *format, __gnuc_va_list ap)
- flockfile (stderr);
- if (_IO_fwide (stderr, 0) > 0)
- {
-+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
- __fwprintf (stderr, L"%s: ", __progname);
- convert_and_print (format, ap);
- putwc_unlocked (L'\n', stderr);
-+#else
-+ abort ();
-+#endif
- }
- else
- {
-@@ -111,6 +118,7 @@ vwarn (const char *format, __gnuc_va_list ap)
- flockfile (stderr);
- if (_IO_fwide (stderr, 0) > 0)
- {
-+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
- __fwprintf (stderr, L"%s: ", __progname);
- if (format)
- {
-@@ -119,6 +127,9 @@ vwarn (const char *format, __gnuc_va_list ap)
- }
- __set_errno (error);
- __fwprintf (stderr, L"%m\n");
-+#else
-+ abort ();
-+#endif
- }
- else
- {
-diff --git a/misc/error.c b/misc/error.c
-index aaa120d..d6cbc82 100644
---- a/misc/error.c
-+++ b/misc/error.c
-@@ -35,6 +35,7 @@
- #endif
-
- #ifdef _LIBC
-+# include <gnu/option-groups.h>
- # include <libintl.h>
- # include <stdbool.h>
- # include <stdint.h>
-@@ -205,6 +206,7 @@ error_tail (int status, int errnum, const char *message, va_list args)
- #if _LIBC
- if (_IO_fwide (stderr, 0) > 0)
- {
-+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
- size_t len = strlen (message) + 1;
- wchar_t *wmessage = NULL;
- mbstate_t st;
-@@ -265,6 +267,9 @@ error_tail (int status, int errnum, const char *message, va_list args)
-
- if (use_malloc)
- free (wmessage);
-+#else
-+ abort ();
-+#endif
- }
- else
- #endif
-diff --git a/misc/tst-efgcvt.c b/misc/tst-efgcvt.c
-index 5083fec..79ed36c 100644
---- a/misc/tst-efgcvt.c
-+++ b/misc/tst-efgcvt.c
-@@ -59,7 +59,7 @@ static testcase ecvt_tests[] =
- { 123.01, -4, 3, "" },
- { 126.71, -4, 3, "" },
- { 0.0, 4, 1, "0000" },
--#if DBL_MANT_DIG == 53
-+#if DBL_MANT_DIG == 53 && !(defined __powerpc__ && defined __NO_FPRS__ && !defined _SOFT_FLOAT && !defined _SOFT_DOUBLE)
- { 0x1p-1074, 3, -323, "494" },
- { -0x1p-1074, 3, -323, "494" },
- #endif
-diff --git a/nis/Makefile b/nis/Makefile
-index 037e674..c967850 100644
---- a/nis/Makefile
-+++ b/nis/Makefile
-@@ -18,6 +18,8 @@
- #
- # Makefile for NIS/NIS+ part.
- #
-+include ../option-groups.mak
-+
- subdir := nis
-
- include ../Makeconfig
-@@ -30,19 +32,26 @@ endif
-
- # These are the databases available for the nis (and perhaps later nisplus)
- # service. This must be a superset of the services in nss.
--databases = proto service hosts network grp pwd rpc ethers \
-- spwd netgrp alias publickey
-+databases-y := proto service hosts network grp pwd rpc ethers \
-+ spwd netgrp publickey
-+databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
-
- # Specify rules for the nss_* modules.
--services := nis nisplus compat
-+# The 'compat' module includes nis support, and the 'nss' directory
-+# includes a bare-bones "files" library, so we'll include 'compat' in
-+# OPTION_EGLIBC_NIS.
-+services-y :=
-+services-$(OPTION_EGLIBC_NIS) += nis nisplus compat
-+
-+extra-libs-$(OPTION_EGLIBC_NIS) += libnsl
-+extra-libs-y += $(services-y:%=libnss_%)
-
--extra-libs = libnsl $(services:%=libnss_%)
- # These libraries will be built in the `others' pass rather than
- # the `lib' pass, because they depend on libc.so being built already.
--extra-libs-others = $(extra-libs)
-+extra-libs-others-y += $(extra-libs-y)
-
- # The sources are found in the appropriate subdir.
--subdir-dirs = $(services:%=nss_%)
-+subdir-dirs = $(services-y:%=nss_%)
- vpath %.c $(subdir-dirs)
-
- libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
-@@ -60,11 +69,11 @@ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
- libnss_compat-routines := $(addprefix compat-,grp pwd spwd initgroups)
- libnss_compat-inhibit-o = $(filter-out .os,$(object-suffixes))
-
--libnss_nis-routines := $(addprefix nis-,$(databases)) nis-initgroups \
-+libnss_nis-routines := $(addprefix nis-,$(databases-y)) nis-initgroups \
- nss-nis
- libnss_nis-inhibit-o = $(filter-out .os,$(object-suffixes))
-
--libnss_nisplus-routines := $(addprefix nisplus-,$(databases)) nisplus-parser \
-+libnss_nisplus-routines := $(addprefix nisplus-,$(databases-y)) nisplus-parser \
- nss-nisplus nisplus-initgroups
- libnss_nisplus-inhibit-o = $(filter-out .os,$(object-suffixes))
-
-@@ -80,12 +89,12 @@ libnsl-libc = $(common-objpfx)linkobj/libc.so
- # Target-specific variable setting to link objects using deprecated
- # RPC interfaces with the version of libc.so that makes them available
- # for new links:
--$(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
-+$(services-y:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
- libc-for-link = $(libnsl-libc)
-
-
- ifeq ($(build-shared),yes)
--$(others:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
-+$(others-y:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
- else
--$(others:%=$(objpfx)%): $(objpfx)libnsl.a
-+$(others-y:%=$(objpfx)%): $(objpfx)libnsl.a
- endif
-diff --git a/nptl/Makefile b/nptl/Makefile
-index aaca0a4..596ca3c 100644
---- a/nptl/Makefile
-+++ b/nptl/Makefile
-@@ -18,6 +18,8 @@
- #
- # Sub-makefile for NPTL portion of the library.
- #
-+include ../option-groups.mak
-+
- subdir := nptl
-
- include ../Makeconfig
-@@ -118,7 +120,7 @@ libpthread-routines = nptl-init vars events version pt-interp \
- pt-raise pt-system \
- flockfile ftrylockfile funlockfile \
- sigaction \
-- herrno res pt-allocrtsig \
-+ pt-allocrtsig \
- pthread_kill_other_threads \
- pthread_getaffinity pthread_setaffinity \
- pthread_attr_getaffinity pthread_attr_setaffinity \
-@@ -138,8 +140,10 @@ libpthread-routines = nptl-init vars events version pt-interp \
- # pthread_setgid pthread_setegid pthread_setregid \
- # pthread_setresgid
-
-+libpthread-routines-$(OPTION_EGLIBC_INET) := herrno res
- libpthread-shared-only-routines = version pt-interp pt-allocrtsig \
- unwind-forcedunwind
-+
- libpthread-static-only-routines = pthread_atfork
-
- # Since cancellation handling is in large parts handled using exceptions
-@@ -220,7 +224,7 @@ tests = tst-typesizes \
- tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
- tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
- tst-mutexpi9 \
-- tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
-+ tst-spin1 tst-spin2 tst-spin3 \
- tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
- tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
- tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
-@@ -256,14 +260,14 @@ tests = tst-typesizes \
- tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
- tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
- tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \
-- tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 tst-cancel25 \
-+ tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel25 \
- tst-cancel-self tst-cancel-self-cancelstate \
- tst-cancel-self-canceltype tst-cancel-self-testcancel \
- tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
- tst-flock1 tst-flock2 \
- tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
- tst-signal6 tst-signal7 \
-- tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
-+ tst-exec2 tst-exec3 tst-exec4 \
- tst-exit1 tst-exit2 tst-exit3 \
- tst-stdio1 tst-stdio2 \
- tst-stack1 tst-stack2 tst-stack3 tst-stack4 tst-pthread-getattr \
-@@ -271,13 +275,12 @@ tests = tst-typesizes \
- tst-unload \
- tst-dlsym1 \
- tst-sysconf \
-- tst-locale1 tst-locale2 \
-+ tst-locale2 \
- tst-umask1 \
- tst-popen1 \
- tst-clock1 \
- tst-context1 \
- tst-sched1 \
-- tst-backtrace1 \
- tst-abstime \
- tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
- tst-getpid3 \
-@@ -288,9 +291,16 @@ xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
- tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
- test-srcs = tst-oddstacklimit
-
--# Test expected to fail on most targets (except x86_64) due to bug
--# 18435 - pthread_once hangs when init routine throws an exception.
--test-xfail-tst-once5 = yes
-+# This test uses the posix_spawn functions.
-+tests-$(OPTION_EGLIBC_SPAWN) += tst-exec1
-+
-+# This test uses the 'backtrace' functions.
-+tests-$(OPTION_EGLIBC_BACKTRACE) += tst-backtrace1
-+
-+# This test is written in C++.
-+tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24
-+
-+tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-locale1
-
- # Files which must not be linked with libpthread.
- tests-nolibpthread = tst-unload
-diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
-index d10f4ea..14257ce 100644
---- a/nptl/pthread_create.c
-+++ b/nptl/pthread_create.c
-@@ -33,6 +33,7 @@
- #include <default-sched.h>
- #include <futex-internal.h>
-
-+#include <gnu/option-groups.h>
- #include <shlib-compat.h>
-
- #include <stap-probe.h>
-@@ -262,8 +263,10 @@ START_THREAD_DEFN
- THREAD_SETMEM (pd, cpuclock_offset, now);
- #endif
-
-+#if __OPTION_EGLIBC_INET
- /* Initialize resolver state pointer. */
- __resp = &pd->res;
-+#endif
-
- /* Initialize pointers to locale data. */
- __ctype_init ();
-@@ -346,8 +349,10 @@ START_THREAD_DEFN
- /* Run the destructor for the thread-local data. */
- __nptl_deallocate_tsd ();
-
-+#if __OPTION_EGLIBC_INET
- /* Clean up any state libc stored in thread-local variables. */
- __libc_thread_freeres ();
-+#endif
-
- /* If this is the last thread we terminate the process now. We
- do not notify the debugger, it might just irritate it if there
-diff --git a/nscd/Makefile b/nscd/Makefile
-index ede941d..f4f3f8d 100644
---- a/nscd/Makefile
-+++ b/nscd/Makefile
-@@ -18,14 +18,17 @@
- #
- # Sub-makefile for nscd portion of the library.
- #
-+include ../option-groups.mak
-+
- subdir := nscd
-
- include ../Makeconfig
-
- ifneq ($(use-nscd),no)
--routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
-+routines-$(OPTION_EGLIBC_INET) += \
-+ nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
- nscd_initgroups nscd_getserv_r nscd_netgroup
--aux := nscd_helper
-+aux-$(OPTION_EGLIBC_INET) += nscd_helper
- endif
-
- # To find xmalloc.c
-@@ -37,14 +40,18 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
- dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
- xmalloc xstrdup aicache initgrcache gai res_hconf \
- netgroupcache
--
-+ifneq (y,$(OPTION_EGLIBC_NIS))
-+# If we haven't build libnsl.so, then we'll need to include our
-+# own copy of nis_hash.
-+nscd-modules += nis_hash
-+endif
- ifeq ($(build-nscd)$(have-thread-library),yesyes)
-
--others += nscd
--others-pie += nscd
--install-sbin := nscd
-+others-$(OPTION_EGLIBC_INET) += nscd
-+others-pie-$(OPTION_EGLIBC_INET) += nscd
-+install-sbin-$(OPTION_EGLIBC_INET) += nscd
-
--extra-objs = $(nscd-modules:=.o)
-+extra-objs-$(OPTION_EGLIBC_INET) += $(nscd-modules:=.o)
-
- endif
-
-@@ -100,7 +107,15 @@ include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
- $(objpfx)nscd: $(nscd-modules:%=$(objpfx)%.o)
-
- ifeq ($(build-shared),yes)
--$(objpfx)nscd: $(shared-thread-library) $(common-objpfx)nis/libnsl.so
-+$(objpfx)nscd: $(shared-thread-library)
-+else
-+$(objpfx)nscd: $(static-thread-library)
-+endif
-+
-+ifeq (y,$(OPTION_EGLIBC_NIS))
-+ifeq ($(build-shared),yes)
-+$(objpfx)nscd: $(common-objpfx)nis/libnsl.so
- else
--$(objpfx)nscd: $(static-thread-library) $(common-objpfx)nis/libnsl.a
-+$(objpfx)nscd: $(common-objpfx)nis/libnsl.a
-+endif
- endif
-diff --git a/nscd/nis_hash.c b/nscd/nis_hash.c
-new file mode 100644
-index 0000000..d244c41
---- /dev/null
-+++ b/nscd/nis_hash.c
-@@ -0,0 +1,3 @@
-+/* If OPTION_EGLIBC_NIS is disabled, nscd can't get this from libnsl.so;
-+ we need our own copy. */
-+#include "../nis/nis_hash.c"
-diff --git a/nss/Makefile b/nss/Makefile
-index 65ab7b5..19f0aef 100644
---- a/nss/Makefile
-+++ b/nss/Makefile
-@@ -18,28 +18,35 @@
- #
- # Makefile for name service switch.
- #
-+include ../option-groups.mak
-+
- subdir := nss
-
- include ../Makeconfig
-
- headers := nss.h
-
--# This is the trivial part which goes into libc itself.
--routines = nsswitch getnssent getnssent_r digits_dots \
-- $(addsuffix -lookup,$(databases))
--
- # These are the databases that go through nss dispatch.
- # Caution: if you add a database here, you must add its real name
- # in databases.def, too.
--databases = proto service hosts network grp pwd ethers \
-- spwd netgrp alias sgrp
-+databases-y = grp pwd spwd sgrp
-+databases-$(OPTION_EGLIBC_INET) \
-+ += proto service hosts network ethers \
-+ netgrp
-+databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
-+
-+routines-$(OPTION_EGLIBC_INET) += digits_dots
-
- ifneq (,$(filter sunrpc,$(subdirs)))
--databases += key rpc
-+databases-$(OPTION_EGLIBC_INET) += key rpc
- have-sunrpc := 1
- else
- have-sunrpc := 0
- endif
-+# This is the trivial part which goes into libc itself.
-+routines-y += nsswitch getnssent getnssent_r \
-+ $(addsuffix -lookup,$(databases-y))
-+
- CPPFLAGS-getent.c = -DHAVE_SUNRPC=$(have-sunrpc)
-
- others := getent makedb
-@@ -47,8 +54,9 @@ install-bin := getent makedb
- makedb-modules = xmalloc hash-string
- extra-objs += $(makedb-modules:=.o)
-
--tests = test-netdb tst-nss-test1 test-digits-dots tst-nss-getpwent
--xtests = bug-erange
-+tests = tst-nss-test1 tst-nss-getpwent
-+tests-$(OPTION_EGLIBC_INET) += test-netdb test-digits-dots
-+xtests-$(OPTION_EGLIBC_INET) += bug-erange
-
- # Specify rules for the nss_* modules. We have some services.
- services := files db
-@@ -63,7 +71,7 @@ subdir-dirs = $(services:%=nss_%)
- vpath %.c $(subdir-dirs) ../locale/programs ../intl
-
-
--libnss_files-routines := $(addprefix files-,$(databases)) \
-+libnss_files-routines := $(addprefix files-,$(databases-y)) \
- files-initgroups files-have_o_cloexec files-init
-
- libnss_db-dbs := $(addprefix db-,\
-@@ -86,6 +94,45 @@ tests-static = tst-nss-static
- tests += $(tests-static)
- endif
-
-+ifneq ($(OPTION_EGLIBC_NSSWITCH),y)
-+
-+ifndef OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG
-+$(error OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG variable left unset)
-+endif
-+
-+ifndef OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS
-+$(error OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS variable left unset)
-+endif
-+
-+ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)))
-+$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed config file)
-+$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG))
-+endif
-+
-+ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)))
-+$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed functions file)
-+$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS))
-+endif
-+
-+before-compile := $(objpfx)fixed-nsswitch.h
-+generated := fixed-nsswitch.h
-+$(objpfx)fixed-nsswitch.h $(objfpx)fixed-nsswitch-libs: \
-+ $(objpfx)gen-fixed-nsswitch \
-+ $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
-+ $< $(objpfx)fixed-nsswitch.h \
-+ $(objpfx)fixed-nsswitch-libs \
-+ $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
-+
-+$(objpfx)gen-fixed-nsswitch: gen-fixed-nsswitch.c \
-+ $(common-objpfx)option-groups.config \
-+ $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)
-+ $(native-compile)
-+gen-fixed-nsswitch-CFLAGS = \
-+ -g3 -O -Wall \
-+ -I $(objpfx) \
-+ -DFIXED_FUNCTIONS='"$(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)"'
-+endif
-+
- include ../Rules
-
- ifeq (yes,$(have-selinux))
-diff --git a/nss/fixed-nsswitch.conf b/nss/fixed-nsswitch.conf
-new file mode 100644
-index 0000000..91bb675
---- /dev/null
-+++ b/nss/fixed-nsswitch.conf
-@@ -0,0 +1,22 @@
-+# /etc/nsswitch.conf
-+#
-+# Example configuration for fixed name service.
-+# See the description of OPTION_EGLIBC_NSSWITCH in option-groups.def
-+# for details.
-+#
-+
-+aliases: files
-+
-+passwd: files
-+group: files
-+shadow: files
-+
-+hosts: files dns
-+networks: files dns
-+
-+protocols: files
-+services: files
-+ethers: files
-+rpc: files
-+
-+netgroup: files
-diff --git a/nss/fixed-nsswitch.functions b/nss/fixed-nsswitch.functions
-new file mode 100644
-index 0000000..2f3fa83
---- /dev/null
-+++ b/nss/fixed-nsswitch.functions
-@@ -0,0 +1,121 @@
-+/* List of functions defined for fixed NSS in GNU C Library.
-+ Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA. */
-+
-+/* When OPTION_EGLIBC_NSSWITCH is disabled (see option-groups.def),
-+ EGLIBC does not use the 'dlopen' and 'dlsym' functions to look for
-+ database query functions in the individual name service libraries.
-+ Instead, it uses a set of functions chosen at compile time, as
-+ directed by the OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS file. This
-+ file is a sample of what you might use there.
-+
-+ This file is C source code; it should only contain invocations of
-+ the following macros:
-+
-+ - DEFINE_ENT (DATABASE, SERVICE, X)
-+
-+ Declare the 'setXent', 'getXent_r', and 'endXent' functions that
-+ query DATABASE using the service library 'libnss_SERVICE.so.2'.
-+ DATABASE should be the full name of the database as it appears in
-+ 'nsswitch.conf', like 'passwd' or 'aliases'.
-+
-+ (The non-reentrant 'getXent' functions are implemented in terms
-+ of the reentrant 'getXent_r' functions, so there is no need to
-+ refer to them explicitly here.)
-+
-+ - DEFINE_GETBY (DATABASE, SERVICE, X, KEY)
-+
-+ Declare the 'getXbyKEY_r' functions that query DATABASE using
-+ SERVICE. DATABASE and SERVICE are as described above.
-+
-+ (The non-reentrant 'getXbyKEY' functions are implemented in terms
-+ of the reentrant 'getXbyKEY_r' functions, so there is no need to
-+ refer to them explicitly here.)
-+
-+ Use the special key 'name3' for the service library function that
-+ implements the 'getaddrinfo' function.
-+
-+ - DEFINE_GET (DATABASE, SERVICE, QUERY)
-+
-+ Declare the 'getQUERY_r' functions that query DATABASE using
-+ SERVICE. This is used for functions like 'getpwnam'.
-+
-+ (The non-reentrant 'getQUERY' functions are implemented in terms
-+ of the reentrant 'getQUERY_r' functions, so there is no need to
-+ refer to them explicitly here.)
-+
-+ This sample file only includes functions that consult the files in
-+ '/etc', and the Domain Name System (DNS). */
-+
-+/* aliases */
-+DEFINE_ENT (aliases, files, alias)
-+DEFINE_GETBY (aliases, files, alias, name)
-+
-+/* ethers */
-+DEFINE_ENT (ethers, files, ether)
-+
-+/* group */
-+DEFINE_ENT (group, files, gr)
-+DEFINE_GET (group, files, grgid)
-+DEFINE_GET (group, files, grnam)
-+
-+/* hosts */
-+DEFINE_ENT (hosts, files, host)
-+DEFINE_GETBY (hosts, files, host, addr)
-+DEFINE_GETBY (hosts, files, host, name)
-+DEFINE_GETBY (hosts, files, host, name2)
-+DEFINE_GET (hosts, files, hostton)
-+DEFINE_GET (hosts, files, ntohost)
-+DEFINE_GETBY (hosts, dns, host, addr)
-+DEFINE_GETBY (hosts, dns, host, name)
-+DEFINE_GETBY (hosts, dns, host, name2)
-+DEFINE_GETBY (hosts, dns, host, name3)
-+
-+/* netgroup */
-+DEFINE_ENT (netgroup, files, netgr)
-+
-+/* networks */
-+DEFINE_ENT (networks, files, net)
-+DEFINE_GETBY (networks, files, net, name)
-+DEFINE_GETBY (networks, files, net, addr)
-+DEFINE_GETBY (networks, dns, net, name)
-+DEFINE_GETBY (networks, dns, net, addr)
-+
-+/* protocols */
-+DEFINE_ENT (protocols, files, proto)
-+DEFINE_GETBY (protocols, files, proto, name)
-+DEFINE_GETBY (protocols, files, proto, number)
-+
-+/* passwd */
-+DEFINE_ENT (passwd, files, pw)
-+DEFINE_GET (passwd, files, pwnam)
-+DEFINE_GET (passwd, files, pwuid)
-+
-+/* rpc */
-+DEFINE_ENT (rpc, files, rpc)
-+DEFINE_GETBY (rpc, files, rpc, name)
-+DEFINE_GETBY (rpc, files, rpc, number)
-+
-+/* services */
-+DEFINE_ENT (services, files, serv)
-+DEFINE_GETBY (services, files, serv, name)
-+DEFINE_GETBY (services, files, serv, port)
-+
-+/* shadow */
-+DEFINE_ENT (shadow, files, sp)
-+DEFINE_GET (shadow, files, spnam)
-diff --git a/nss/gen-fixed-nsswitch.c b/nss/gen-fixed-nsswitch.c
-new file mode 100644
-index 0000000..6e1c98c
---- /dev/null
-+++ b/nss/gen-fixed-nsswitch.c
-@@ -0,0 +1,803 @@
-+/* gen-fixed-nsswitch.c --- generate fixed name service data structures
-+ Copyright (C) 1996-1999, 2001-2006, 2007 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA. */
-+
-+#define _GNU_SOURCE
-+
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <stdarg.h>
-+#include <assert.h>
-+#include <ctype.h>
-+
-+#include "gnu/lib-names.h"
-+#include "nss.h"
-+
-+/* Provide a fallback definition to allow this file to be compiled outside
-+ libc. */
-+#ifndef internal_function
-+# define internal_function
-+#endif
-+
-+
-+/* Simple utilities. */
-+
-+void __attribute__ ((noreturn))
-+error (const char *message)
-+{
-+ fprintf (stderr, "%s\n", message);
-+ exit (1);
-+}
-+
-+
-+void *
-+check_alloc (void *p)
-+{
-+ if (p)
-+ return p;
-+ else
-+ error ("out of memory");
-+}
-+
-+void *
-+xmalloc (size_t size)
-+{
-+ return check_alloc (malloc (size));
-+}
-+
-+
-+/* Format ARGS according to FORMAT, and return the result as a
-+ malloc'ed string. */
-+char *
-+saprintf (const char *format, ...)
-+{
-+ va_list args;
-+ size_t len;
-+ char *buf;
-+
-+ va_start (args, format);
-+ len = vsnprintf (NULL, 0, format, args);
-+ va_end (args);
-+
-+ buf = xmalloc (len + 1);
-+ va_start (args, format);
-+ assert (len == vsnprintf (buf, len + 1, format, args));
-+ va_end (args);
-+
-+ return buf;
-+}
-+
-+
-+
-+/* Data structures representing the configuration file in memory. */
-+
-+/* These are copied from nsswitch.h.
-+
-+ We could simply #include that file, but this program runs on the
-+ build machine and links against the build machine's libraries,
-+ whereas that header is meant for use by target code; it uses
-+ 'libc_hidden_proto', 'internal_function', and related hair. Since
-+ we've copied the parsing code, we might as well copy the data
-+ structure definitions as well. */
-+
-+/* Actions performed after lookup finished. */
-+typedef enum
-+{
-+ NSS_ACTION_CONTINUE,
-+ NSS_ACTION_RETURN
-+} lookup_actions;
-+
-+
-+typedef struct service_library
-+{
-+ /* Name of service (`files', `dns', `nis', ...). */
-+ const char *name;
-+ /* Pointer to the loaded shared library. */
-+ void *lib_handle;
-+ /* And the link to the next entry. */
-+ struct service_library *next;
-+} service_library;
-+
-+
-+/* For mapping a function name to a function pointer. It is known in
-+ nsswitch.c:nss_lookup_function that a string pointer for the lookup key
-+ is the first member. */
-+typedef struct
-+{
-+ const char *fct_name;
-+ void *fct_ptr;
-+} known_function;
-+
-+
-+typedef struct service_user
-+{
-+ /* And the link to the next entry. */
-+ struct service_user *next;
-+ /* Action according to result. */
-+ lookup_actions actions[5];
-+ /* Link to the underlying library object. */
-+ service_library *library;
-+ /* Collection of known functions.
-+
-+ With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
-+ 'tsearch'-style tree.
-+
-+ With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
-+ pointers to known_function structures, NULL-terminated. */
-+ union
-+ {
-+ void *tree;
-+ const known_function **array;
-+ } known;
-+ /* Name of the service (`files', `dns', `nis', ...). */
-+ const char *name;
-+} service_user;
-+
-+/* To access the action based on the status value use this macro. */
-+#define nss_next_action(ni, status) ((ni)->actions[2 + status])
-+
-+
-+typedef struct name_database_entry
-+{
-+ /* And the link to the next entry. */
-+ struct name_database_entry *next;
-+ /* List of service to be used. */
-+ service_user *service;
-+ /* Name of the database. */
-+ const char *name;
-+} name_database_entry;
-+
-+
-+typedef struct name_database
-+{
-+ /* List of all known databases. */
-+ name_database_entry *entry;
-+ /* List of libraries with service implementation. */
-+ service_library *library;
-+} name_database;
-+
-+
-+
-+/* Gathering the contents of the FIXED_FUNCTIONS file. */
-+
-+/* It should be possible to generate this list automatically by
-+ looking at the services and databases used in the nsswitch.conf
-+ file, and having a hard-coded set of queries supported on each
-+ database. */
-+
-+/* We #include the FIXED_FUNCTIONS file several times to build an
-+ array of function structures holding its data. */
-+enum function_kind {
-+ fk_end = 0, /* Last entry. */
-+ fk_setent, /* Like setpwent. */
-+ fk_getent, /* Like getpwent. */
-+ fk_endent, /* Like endpwent. */
-+ fk_getby, /* Like gethostbyname. */
-+ fk_get /* Like getpwnam. */
-+};
-+
-+
-+struct function {
-+ /* What kind of function this is. */
-+ enum function_kind kind;
-+
-+ /* The database and service of the function being hardwired in. */
-+ char *database, *service;
-+
-+ /* The kind of entry being queried, for 'fk_setent', 'fk_getent',
-+ 'fk_endent', and 'fk_getby' functions. */
-+ char *entry;
-+
-+ /* The key, for 'fk_getby' entries. */
-+ char *key;
-+
-+ /* The value and key, for 'fk_get' entries. */
-+ char *value_and_key;
-+};
-+
-+
-+const struct function functions[] =
-+ {
-+
-+#define DEFINE_ENT(database, service, entry) \
-+ { fk_setent, #database, #service, #entry }, \
-+ { fk_getent, #database, #service, #entry }, \
-+ { fk_endent, #database, #service, #entry },
-+#define DEFINE_GETBY(database, service, entry, key) \
-+ { fk_getby, #database, #service, #entry, #key },
-+#define DEFINE_GET(database, service, value_and_key) \
-+ { fk_get, #database, #service, NULL, NULL, #value_and_key },
-+
-+#include FIXED_FUNCTIONS
-+
-+#undef DEFINE_ENT
-+#undef DEFINE_GETBY
-+#undef DEFINE_GET
-+
-+ { fk_end }
-+ };
-+
-+
-+/* Parsing the config file. Functions copied from nsswitch.c. */
-+
-+#define __strchrnul strchrnul
-+#define __getline getline
-+#define __strncasecmp strncasecmp
-+
-+/* Prototypes for the local functions. */
-+static name_database *nss_parse_file (const char *fname) internal_function;
-+static name_database_entry *nss_getline (char *line) internal_function;
-+static service_user *nss_parse_service_list (const char *line)
-+ internal_function;
-+
-+static name_database *
-+internal_function
-+nss_parse_file (const char *fname)
-+{
-+ FILE *fp;
-+ name_database *result;
-+ name_database_entry *last;
-+ char *line;
-+ size_t len;
-+
-+ /* Open the configuration file. */
-+ fp = fopen (fname, "rc");
-+ if (fp == NULL)
-+ return NULL;
-+
-+ // /* No threads use this stream. */
-+ // __fsetlocking (fp, FSETLOCKING_BYCALLER);
-+
-+ result = (name_database *) xmalloc (sizeof (name_database));
-+
-+ result->entry = NULL;
-+ result->library = NULL;
-+ last = NULL;
-+ line = NULL;
-+ len = 0;
-+ do
-+ {
-+ name_database_entry *this;
-+ ssize_t n;
-+
-+ n = __getline (&line, &len, fp);
-+ if (n < 0)
-+ break;
-+ if (line[n - 1] == '\n')
-+ line[n - 1] = '\0';
-+
-+ /* Because the file format does not know any form of quoting we
-+ can search forward for the next '#' character and if found
-+ make it terminating the line. */
-+ *__strchrnul (line, '#') = '\0';
-+
-+ /* If the line is blank it is ignored. */
-+ if (line[0] == '\0')
-+ continue;
-+
-+ /* Each line completely specifies the actions for a database. */
-+ this = nss_getline (line);
-+ if (this != NULL)
-+ {
-+ if (last != NULL)
-+ last->next = this;
-+ else
-+ result->entry = this;
-+
-+ last = this;
-+ }
-+ }
-+ while (!feof_unlocked (fp));
-+
-+ /* Free the buffer. */
-+ free (line);
-+ /* Close configuration file. */
-+ fclose (fp);
-+
-+ return result;
-+}
-+
-+
-+/* Read the source names:
-+ `( <source> ( "[" "!"? (<status> "=" <action> )+ "]" )? )*'
-+ */
-+static service_user *
-+internal_function
-+nss_parse_service_list (const char *line)
-+{
-+ service_user *result = NULL, **nextp = &result;
-+
-+ while (1)
-+ {
-+ service_user *new_service;
-+ const char *name;
-+
-+ while (isspace (line[0]))
-+ ++line;
-+ if (line[0] == '\0')
-+ /* No source specified. */
-+ return result;
-+
-+ /* Read <source> identifier. */
-+ name = line;
-+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[')
-+ ++line;
-+ if (name == line)
-+ return result;
-+
-+
-+ new_service = (service_user *) xmalloc (sizeof (*new_service));
-+ new_service->name = (char *) xmalloc (line - name + 1);
-+
-+ *((char *) __mempcpy ((char *) new_service->name, name, line - name))
-+ = '\0';
-+
-+ /* Set default actions. */
-+ new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
-+ new_service->actions[2 + NSS_STATUS_UNAVAIL] = NSS_ACTION_CONTINUE;
-+ new_service->actions[2 + NSS_STATUS_NOTFOUND] = NSS_ACTION_CONTINUE;
-+ new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
-+ new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
-+ new_service->library = NULL;
-+ new_service->known.tree = NULL;
-+ new_service->next = NULL;
-+
-+ while (isspace (line[0]))
-+ ++line;
-+
-+ if (line[0] == '[')
-+ {
-+ /* Read criterions. */
-+ do
-+ ++line;
-+ while (line[0] != '\0' && isspace (line[0]));
-+
-+ do
-+ {
-+ int not;
-+ enum nss_status status;
-+ lookup_actions action;
-+
-+ /* Grok ! before name to mean all statii but that one. */
-+ not = line[0] == '!';
-+ if (not)
-+ ++line;
-+
-+ /* Read status name. */
-+ name = line;
-+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
-+ && line[0] != ']')
-+ ++line;
-+
-+ /* Compare with known statii. */
-+ if (line - name == 7)
-+ {
-+ if (__strncasecmp (name, "SUCCESS", 7) == 0)
-+ status = NSS_STATUS_SUCCESS;
-+ else if (__strncasecmp (name, "UNAVAIL", 7) == 0)
-+ status = NSS_STATUS_UNAVAIL;
-+ else
-+ return result;
-+ }
-+ else if (line - name == 8)
-+ {
-+ if (__strncasecmp (name, "NOTFOUND", 8) == 0)
-+ status = NSS_STATUS_NOTFOUND;
-+ else if (__strncasecmp (name, "TRYAGAIN", 8) == 0)
-+ status = NSS_STATUS_TRYAGAIN;
-+ else
-+ return result;
-+ }
-+ else
-+ return result;
-+
-+ while (isspace (line[0]))
-+ ++line;
-+ if (line[0] != '=')
-+ return result;
-+ do
-+ ++line;
-+ while (isspace (line[0]));
-+
-+ name = line;
-+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
-+ && line[0] != ']')
-+ ++line;
-+
-+ if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0)
-+ action = NSS_ACTION_RETURN;
-+ else if (line - name == 8
-+ && __strncasecmp (name, "CONTINUE", 8) == 0)
-+ action = NSS_ACTION_CONTINUE;
-+ else
-+ return result;
-+
-+ if (not)
-+ {
-+ /* Save the current action setting for this status,
-+ set them all to the given action, and reset this one. */
-+ const lookup_actions save = new_service->actions[2 + status];
-+ new_service->actions[2 + NSS_STATUS_TRYAGAIN] = action;
-+ new_service->actions[2 + NSS_STATUS_UNAVAIL] = action;
-+ new_service->actions[2 + NSS_STATUS_NOTFOUND] = action;
-+ new_service->actions[2 + NSS_STATUS_SUCCESS] = action;
-+ new_service->actions[2 + status] = save;
-+ }
-+ else
-+ new_service->actions[2 + status] = action;
-+
-+ /* Skip white spaces. */
-+ while (isspace (line[0]))
-+ ++line;
-+ }
-+ while (line[0] != ']');
-+
-+ /* Skip the ']'. */
-+ ++line;
-+ }
-+
-+ *nextp = new_service;
-+ nextp = &new_service->next;
-+ }
-+}
-+
-+static name_database_entry *
-+internal_function
-+nss_getline (char *line)
-+{
-+ const char *name;
-+ name_database_entry *result;
-+ size_t len;
-+
-+ /* Ignore leading white spaces. ATTENTION: this is different from
-+ what is implemented in Solaris. The Solaris man page says a line
-+ beginning with a white space character is ignored. We regard
-+ this as just another misfeature in Solaris. */
-+ while (isspace (line[0]))
-+ ++line;
-+
-+ /* Recognize `<database> ":"'. */
-+ name = line;
-+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != ':')
-+ ++line;
-+ if (line[0] == '\0' || name == line)
-+ /* Syntax error. */
-+ return NULL;
-+ *line++ = '\0';
-+
-+ len = strlen (name) + 1;
-+
-+ result = (name_database_entry *) xmalloc (sizeof (*result));
-+ result->name = (char *) xmalloc (len);
-+
-+ /* Save the database name. */
-+ memcpy ((char *) result->name, name, len);
-+
-+ /* Parse the list of services. */
-+ result->service = nss_parse_service_list (line);
-+
-+ result->next = NULL;
-+ return result;
-+}
-+
-+
-+
-+/* Generating code for statically initialized nsswitch structures. */
-+
-+
-+/* Return the service-neutral suffix of the name of the service
-+ library function referred to by the function F. The result is
-+ allocated with malloc. */
-+char *
-+known_function_suffix (const struct function *f)
-+{
-+ switch (f->kind)
-+ {
-+ case fk_setent:
-+ return saprintf ("set%sent", f->entry);
-+
-+ case fk_getent:
-+ return saprintf ("get%sent_r", f->entry);
-+
-+ case fk_endent:
-+ return saprintf ("end%sent", f->entry);
-+
-+ case fk_getby:
-+ return saprintf ("get%sby%s_r", f->entry, f->key);
-+
-+ case fk_get:
-+ return saprintf ("get%s_r", f->value_and_key);
-+
-+ default:
-+ abort ();
-+ }
-+}
-+
-+
-+/* Return the name of the service library function referred to by the
-+ function F. The result is allocated with malloc. */
-+char *
-+known_function_name (const struct function *f)
-+{
-+ return saprintf ("_nss_%s_%s", f->service, known_function_suffix (f));
-+}
-+
-+
-+/* Write initialized known_function structures to OUT for
-+ all the functions we'll use. */
-+void
-+generate_known_functions (FILE *out)
-+{
-+ int i;
-+
-+ /* First, generate weak references to the functions. The service
-+ libraries depend on libc, and if these references weren't weak,
-+ we'd be making libc depend circularly on the service
-+ libraries. */
-+ for (i = 0; functions[i].kind; i++)
-+ {
-+ char *name = known_function_name (&functions[i]);
-+ fprintf (out, "typeof (%s) %s __attribute__ ((weak));\n",
-+ name, name);
-+ }
-+ fputs ("\n", out);
-+
-+ /* Then, a table mapping names to functions. */
-+ fputs ("static const known_function fixed_known_functions[] = {\n",
-+ out);
-+ for (i = 0; functions[i].kind; i++)
-+ {
-+ const struct function *f = &functions[i];
-+ char *suffix = known_function_suffix (f);
-+
-+ fprintf (out, " /* %2d */ { \"%s\", _nss_%s_%s },\n",
-+ i, suffix, f->service, suffix);
-+ }
-+ fputs ("};\n", out);
-+ fputs ("\n", out);
-+}
-+
-+
-+/* Print code to OUT for an initialized array of pointers to the
-+ 'known_function' structures needed for USER, which is for
-+ DATABASE. Return its name, allocated with malloc. */
-+char *
-+generate_known_function_list (FILE *out,
-+ const name_database_entry *database,
-+ const service_user *user)
-+{
-+ char *list_name = saprintf ("fixed_%s_%s_known_funcs",
-+ database->name, user->name);
-+ fprintf (out, "static const known_function *%s[] = {\n",
-+ list_name);
-+ int i;
-+ for (i = 0; functions[i].kind; i++)
-+ if (strcmp (functions[i].database, database->name) == 0
-+ && strcmp (functions[i].service, user->name) == 0)
-+ fprintf (out, " &fixed_known_functions[%d], /* %s */\n",
-+ i, known_function_name (&functions[i]));
-+ fputs (" NULL\n", out);
-+ fputs ("};\n", out);
-+ fputs ("\n", out);
-+
-+ return list_name;
-+}
-+
-+
-+/* Return the name of the status value STATUS, as a statically
-+ allocated string. */
-+const char *
-+lookup_status_name (enum nss_status status)
-+{
-+ switch (status)
-+ {
-+ case NSS_STATUS_TRYAGAIN: return "NSS_STATUS_TRYAGAIN";
-+ case NSS_STATUS_UNAVAIL: return "NSS_STATUS_UNAVAIL";
-+ case NSS_STATUS_NOTFOUND: return "NSS_STATUS_NOTFOUND";
-+ case NSS_STATUS_SUCCESS: return "NSS_STATUS_SUCCESS";
-+ case NSS_STATUS_RETURN: return "NSS_STATUS_RETURN";
-+ default: abort ();
-+ };
-+}
-+
-+
-+/* Return the name of ACTION as a statically allocated string. */
-+const char *
-+lookup_action_name (lookup_actions action)
-+{
-+ switch (action)
-+ {
-+ case NSS_ACTION_CONTINUE: return "NSS_ACTION_CONTINUE";
-+ case NSS_ACTION_RETURN: return "NSS_ACTION_RETURN";
-+ default: abort ();
-+ }
-+}
-+
-+
-+/* Print code to OUT for the list of service_user structures starting
-+ with USER, which are all for DATABASE. Return the name of the
-+ first structure in that list, or zero if USER is NULL. */
-+char *
-+generate_service_user_list (FILE *out,
-+ name_database_entry *database,
-+ service_user *user)
-+{
-+ if (user)
-+ {
-+ /* Generate the tail of the list. */
-+ char *next_name = generate_service_user_list (out, database, user->next);
-+ /* Generate our known function list. */
-+ char *known_function_list_name =
-+ generate_known_function_list (out, database, user);
-+
-+ char *name = saprintf ("fixed_%s_%s_user", database->name, user->name);
-+
-+ fprintf (out, "static const service_user %s = {\n", name);
-+ if (next_name)
-+ fprintf (out, " (service_user *) &%s,\n", next_name);
-+ else
-+ fprintf (out, " NULL, /* no next entry */\n");
-+ fputs (" {\n", out);
-+ int i;
-+ for (i = 0; i < sizeof (user->actions) / sizeof (user->actions[0]); i++)
-+ fprintf (out, " %s, /* %s */\n",
-+ lookup_action_name (user->actions[i]),
-+ lookup_status_name (i - 2));
-+ fputs (" },\n", out);
-+ fprintf (out, " NULL, /* we never need the service library */\n");
-+ fprintf (out, " { .array = %s },\n", known_function_list_name);
-+ fprintf (out, " \"%s\"\n", user->name);
-+ fputs ("};\n", out);
-+ fputs ("\n", out);
-+
-+ return name;
-+ }
-+ else
-+ return NULL;
-+}
-+
-+
-+/* Print code to OUT for the list of name_database_entry structures
-+ starting with DATABASE. Return the name of the first structure
-+ in that list, or zero if DATABASE is NULL. */
-+char *
-+generate_name_database_entries (FILE *out, name_database_entry *database)
-+{
-+ if (database)
-+ {
-+ char *next_name = generate_name_database_entries (out, database->next);
-+ char *service_user_name
-+ = generate_service_user_list (out, database, database->service);
-+ char *name = saprintf ("fixed_%s_name_database", database->name);
-+
-+ fprintf (out, "static const name_database_entry %s = {\n", name);
-+
-+ if (next_name)
-+ fprintf (out, " (name_database_entry *) &%s,\n", next_name);
-+ else
-+ fprintf (out, " NULL,\n");
-+
-+ if (service_user_name)
-+ fprintf (out, " (service_user *) &%s,\n", service_user_name);
-+ else
-+ fprintf (out, " NULL,\n");
-+
-+ fprintf (out, " \"%s\"\n", database->name);
-+ fprintf (out, "};\n");
-+ fputs ("\n", out);
-+
-+ return name;
-+ }
-+ else
-+ return NULL;
-+}
-+
-+
-+void
-+generate_name_database (FILE *out, name_database *service_table)
-+{
-+ /* Produce a linked list of the known name_database_entry
-+ structures. */
-+ char *entries = generate_name_database_entries (out, service_table->entry);
-+
-+ /* Now produce the main structure that points to them all. */
-+ fprintf (out, "static const name_database fixed_name_database = {\n");
-+ if (entries)
-+ fprintf (out, " (name_database_entry *) &%s,\n", entries);
-+ else
-+ fprintf (out, " NULL,\n");
-+ fputs (" NULL /* we don't need the libraries */\n"
-+ "};\n",
-+ out);
-+}
-+
-+
-+
-+/* Generating the list of service libraries we generate references to. */
-+
-+/* String with revision number of the shared object files. */
-+static const char *const nss_shlib_revision = LIBNSS_FILES_SO + 15;
-+
-+void
-+generate_service_lib_list (FILE *out, name_database *service_table)
-+{
-+ int i, j;
-+ int printed_any = 0;
-+
-+ for (i = 0; functions[i].kind; i++)
-+ {
-+ /* Mention each service library only once. */
-+ for (j = 0; j < i; j++)
-+ if (strcmp (functions[i].service, functions[j].service) == 0)
-+ break;
-+
-+ if (j >= i)
-+ {
-+ if (printed_any)
-+ putc (' ', out);
-+ fprintf (out, "-lnss_%s",
-+ functions[i].service,
-+ nss_shlib_revision);
-+ printed_any = 1;
-+ }
-+ }
-+}
-+
-+
-+/* Main. */
-+
-+int
-+main (int argc, char **argv)
-+{
-+ if (argc != 4)
-+ {
-+ fprintf (stderr, "usage: gen-fixed-nsswitch HEADER SERVLIBS CONFIG\n");
-+ exit (1);
-+ }
-+
-+ name_database *service_table = nss_parse_file (argv[3]);
-+
-+ FILE *header = fopen (argv[1], "w");
-+ if (! header)
-+ {
-+ fprintf (stderr,
-+ "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
-+ argv[1], strerror (errno));
-+ exit (1);
-+ }
-+ fputs ("/* Generated by nss/gen-fixed-nsswitch.c. */\n", header);
-+ fputs ("\n", header);
-+ generate_known_functions (header);
-+ generate_name_database (header, service_table);
-+ fclose (header);
-+
-+ FILE *service_lib_list = fopen (argv[2], "w");
-+ if (! service_lib_list)
-+ {
-+ fprintf (stderr,
-+ "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
-+ argv[2], strerror (errno));
-+ exit (1);
-+ }
-+ generate_service_lib_list (service_lib_list, service_table);
-+ fclose (service_lib_list);
-+
-+ return 0;
-+}
-diff --git a/nss/getent.c b/nss/getent.c
-index 34df848..674c8ee 100644
---- a/nss/getent.c
-+++ b/nss/getent.c
-@@ -39,6 +39,7 @@
- #include <netinet/ether.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
-+#include <gnu/option-groups.h>
-
- /* Get libc version number. */
- #include <version.h>
-@@ -91,6 +92,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
- fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
- }
-
-+#if __OPTION_EGLIBC_DB_ALIASES
- /* This is for aliases */
- static void
- print_aliases (struct aliasent *alias)
-@@ -135,7 +137,9 @@ aliases_keys (int number, char *key[])
-
- return result;
- }
-+#endif /* __OPTION_EGLIBC_DB_ALIASES */
-
-+#if __OPTION_EGLIBC_INET
- /* This is for ethers */
- static int
- ethers_keys (int number, char *key[])
-@@ -179,6 +183,7 @@ ethers_keys (int number, char *key[])
-
- return result;
- }
-+#endif /* __OPTION_EGLIBC_INET */
-
- /* This is for group */
- static void
-@@ -301,6 +306,7 @@ gshadow_keys (int number, char *key[])
- return result;
- }
-
-+#if __OPTION_EGLIBC_INET
- /* This is for hosts */
- static void
- print_hosts (struct hostent *host)
-@@ -598,6 +604,7 @@ networks_keys (int number, char *key[])
-
- return result;
- }
-+#endif /* __OPTION_EGLIBC_INET */
-
- /* Now is all for passwd */
- static void
-@@ -650,6 +657,7 @@ passwd_keys (int number, char *key[])
- return result;
- }
-
-+#if __OPTION_EGLIBC_INET
- /* This is for protocols */
- static void
- print_protocols (struct protoent *proto)
-@@ -807,6 +815,7 @@ services_keys (int number, char *key[])
-
- return result;
- }
-+#endif /* __OPTION_EGLIBC_INET */
-
- /* This is for shadow */
- static void
-@@ -873,23 +882,36 @@ struct
- } databases[] =
- {
- #define D(name) { #name, name ## _keys },
--D(ahosts)
--D(ahostsv4)
--D(ahostsv6)
--D(aliases)
--D(ethers)
-+
-+#if __OPTION_EGLIBC_INET
-+# define DN(name) D(name)
-+#else
-+# define DN(name)
-+#endif
-+
-+#if __OPTION_EGLIBC_DB_ALIASES
-+# define DA(name) D(name)
-+#else
-+# define DA(name)
-+#endif
-+
-+DN(ahosts)
-+DN(ahostsv4)
-+DN(ahostsv6)
-+DA(aliases)
-+DN(ethers)
- D(group)
- D(gshadow)
--D(hosts)
--D(initgroups)
--D(netgroup)
--D(networks)
-+DN(hosts)
-+DN(initgroups)
-+DN(netgroup)
-+DN(networks)
- D(passwd)
--D(protocols)
-+DN(protocols)
- #if HAVE_SUNRPC
--D(rpc)
-+DN(rpc)
- #endif
--D(services)
-+DN(services)
- D(shadow)
- #undef D
- { NULL, NULL }
-diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c
-index f5b9036..f09f7fe 100644
---- a/nss/getnssent_r.c
-+++ b/nss/getnssent_r.c
-@@ -16,6 +16,7 @@
- <http://www.gnu.org/licenses/>. */
-
- #include <errno.h>
-+#include <gnu/option-groups.h>
- #include <netdb.h>
- #include "nsswitch.h"
-
-@@ -59,11 +60,13 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct,
- } fct;
- int no_more;
-
-+#if __OPTION_EGLIBC_INET
- if (res && __res_maybe_init (&_res, 0) == -1)
- {
- __set_h_errno (NETDB_INTERNAL);
- return;
- }
-+#endif /* __OPTION_EGLIBC_INET */
-
- /* Cycle through the services and run their `setXXent' functions until
- we find an available service. */
-@@ -101,11 +104,13 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct,
- } fct;
- int no_more;
-
-+#if __OPTION_EGLIBC_INET
- if (res && __res_maybe_init (&_res, 0) == -1)
- {
- __set_h_errno (NETDB_INTERNAL);
- return;
- }
-+#endif /* __OPTION_EGLIBC_INET */
-
- /* Cycle through all the services and run their endXXent functions. */
- no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
-@@ -141,12 +146,14 @@ __nss_getent_r (const char *getent_func_name,
- int no_more;
- enum nss_status status;
-
-+#if __OPTION_EGLIBC_INET
- if (res && __res_maybe_init (&_res, 0) == -1)
- {
- *h_errnop = NETDB_INTERNAL;
- *result = NULL;
- return errno;
- }
-+#endif /* __OPTION_EGLIBC_INET */
-
- /* Initialize status to return if no more functions are found. */
- status = NSS_STATUS_NOTFOUND;
-@@ -161,7 +168,7 @@ __nss_getent_r (const char *getent_func_name,
- int is_last_nip = *nip == *last_nip;
-
- status = DL_CALL_FCT (fct.f,
-- (resbuf, buffer, buflen, &errno, &h_errno));
-+ (resbuf, buffer, buflen, &errno, h_errnop));
-
- /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
- provided buffer is too small. In this case we should give
-diff --git a/nss/nsswitch.c b/nss/nsswitch.c
-index 9712623..c81e207 100644
---- a/nss/nsswitch.c
-+++ b/nss/nsswitch.c
-@@ -26,6 +26,7 @@
- #include <stdio_ext.h>
- #include <stdlib.h>
- #include <string.h>
-+#include <gnu/option-groups.h>
-
- #include <aliases.h>
- #include <grp.h>
-@@ -41,6 +42,15 @@
- #include "../nscd/nscd_proto.h"
- #include <sysdep.h>
-
-+/* When OPTION_EGLIBC_NSSWITCH is disabled, we use fixed tables of
-+ databases and services, generated at library build time. Thus:
-+ - We can't reconfigure individual databases, so we don't need a
-+ name-to-database map.
-+ - We never add databases or service libraries, or look up functions
-+ at runtime, so there's no need for a lock to protect our tables.
-+ See ../option-groups.def for the details. */
-+#if __OPTION_EGLIBC_NSSWITCH
-+
- /* Prototypes for the local functions. */
- static name_database *nss_parse_file (const char *fname) internal_function;
- static name_database_entry *nss_getline (char *line) internal_function;
-@@ -79,6 +89,9 @@ bool __nss_database_custom[NSS_DBSIDX_max];
-
- __libc_lock_define_initialized (static, lock)
-
-+#define lock_nsswitch __libc_lock_lock (lock)
-+#define unlock_nsswitch __libc_lock_unlock (lock)
-+
- #if !defined DO_STATIC_NSS || defined SHARED
- /* String with revision number of the shared object files. */
- static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15;
-@@ -93,6 +106,20 @@ static name_database *service_table;
- __libc_freeres. */
- static name_database_entry *defconfig_entries;
-
-+#else /* __OPTION_EGLIBC_NSSWITCH */
-+
-+/* Bring in the statically initialized service table we generated at
-+ build time. */
-+#include "fixed-nsswitch.h"
-+
-+const static name_database *service_table = &fixed_name_database;
-+
-+/* Nothing ever changes, so there's no need to lock anything. */
-+#define lock_nsswitch (0)
-+#define unlock_nsswitch (0)
-+
-+#endif /* __OPTION_EGLIBC_NSSWITCH */
-+
-
- #ifdef USE_NSCD
- /* Nonzero if this is the nscd process. */
-@@ -109,20 +136,22 @@ __nss_database_lookup (const char *database, const char *alternate_name,
- const char *defconfig, service_user **ni)
- {
- /* Prevent multiple threads to change the service table. */
-- __libc_lock_lock (lock);
-+ lock_nsswitch;
-
- /* Reconsider database variable in case some other thread called
- `__nss_configure_lookup' while we waited for the lock. */
- if (*ni != NULL)
- {
-- __libc_lock_unlock (lock);
-+ unlock_nsswitch;
- return 0;
- }
-
-+#if __OPTION_EGLIBC_NSSWITCH
- /* Are we initialized yet? */
- if (service_table == NULL)
- /* Read config file. */
- service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
-+#endif
-
- /* Test whether configuration data is available. */
- if (service_table != NULL)
-@@ -144,6 +173,7 @@ __nss_database_lookup (const char *database, const char *alternate_name,
- *ni = entry->service;
- }
-
-+#if __OPTION_EGLIBC_NSSWITCH
- /* No configuration data is available, either because nsswitch.conf
- doesn't exist or because it doesn't have a line for this database.
-
-@@ -166,13 +196,23 @@ __nss_database_lookup (const char *database, const char *alternate_name,
- {
- entry->next = defconfig_entries;
- entry->service = *ni;
-- entry->name[0] = '\0';
-+ entry->name = "";
- defconfig_entries = entry;
- }
- }
- }
-+#else
-+ /* Without the dynamic behavior, we can't process defconfig. The
-+ databases the user specified at library build time are all you
-+ get. */
-+ if (*ni == NULL)
-+ {
-+ unlock_nsswitch;
-+ return -1;
-+ }
-+#endif
-
-- __libc_lock_unlock (lock);
-+ unlock_nsswitch;
-
- return *ni != NULL ? 0 : -1;
- }
-@@ -252,6 +292,7 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name,
- libc_hidden_def (__nss_next2)
-
-
-+#if __OPTION_EGLIBC_NSSWITCH
- int
- attribute_compat_text_section
- __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
-@@ -300,13 +341,13 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
- }
-
- /* Prevent multiple threads to change the service table. */
-- __libc_lock_lock (lock);
-+ lock_nsswitch;
-
- /* Install new rules. */
- *databases[cnt].dbp = new_db;
- __nss_database_custom[cnt] = true;
-
-- __libc_lock_unlock (lock);
-+ unlock_nsswitch;
-
- return 0;
- }
-@@ -402,7 +443,7 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
- void **found, *result;
-
- /* We now modify global data. Protect it. */
-- __libc_lock_lock (lock);
-+ lock_nsswitch;
-
- /* Search the tree of functions previously requested. Data in the
- tree are `known_function' structures, whose first member is a
-@@ -413,7 +454,7 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
- enough to a pointer to our structure to use as a lookup key that
- will be passed to `known_compare' (above). */
-
-- found = __tsearch (&fct_name, &ni->known, &known_compare);
-+ found = __tsearch (&fct_name, &ni->known.tree, &known_compare);
- if (found == NULL)
- /* This means out-of-memory. */
- result = NULL;
-@@ -440,7 +481,7 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
- #endif
- /* Oops. We can't instantiate this node properly.
- Remove it from the tree. */
-- __tdelete (&fct_name, &ni->known, &known_compare);
-+ __tdelete (&fct_name, &ni->known.tree, &known_compare);
- free (known);
- result = NULL;
- }
-@@ -520,13 +561,43 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
- }
-
- /* Remove the lock. */
-- __libc_lock_unlock (lock);
-+ unlock_nsswitch;
-
- return result;
- }
- libc_hidden_def (__nss_lookup_function)
-
-
-+#else /* below if ! __OPTION_EGLIBC_NSSWITCH */
-+
-+
-+int
-+__nss_configure_lookup (const char *dbname, const char *service_line)
-+{
-+ /* We can't dynamically configure lookup without
-+ OPTION_EGLIBC_NSSWITCH. */
-+ __set_errno (EINVAL);
-+ return -1;
-+}
-+
-+
-+void *
-+__nss_lookup_function (service_user *ni, const char *fct_name)
-+{
-+ int i;
-+ const known_function **known = ni->known.array;
-+
-+ for (i = 0; known[i]; i++)
-+ if (strcmp (fct_name, known[i]->fct_name) == 0)
-+ return known[i]->fct_ptr;
-+
-+ return NULL;
-+}
-+libc_hidden_def (__nss_lookup_function)
-+#endif
-+
-+
-+#if __OPTION_EGLIBC_NSSWITCH
- static name_database *
- internal_function
- nss_parse_file (const char *fname)
-@@ -632,8 +703,10 @@ nss_parse_service_list (const char *line)
- + (line - name + 1));
- if (new_service == NULL)
- return result;
-+ new_service->name = (char *) (new_service + 1);
-
-- *((char *) __mempcpy (new_service->name, name, line - name)) = '\0';
-+ *((char *) __mempcpy ((char *) new_service->name, name, line - name))
-+ = '\0';
-
- /* Set default actions. */
- new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
-@@ -642,7 +715,7 @@ nss_parse_service_list (const char *line)
- new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
- new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
- new_service->library = NULL;
-- new_service->known = NULL;
-+ new_service->known.tree = NULL;
- new_service->next = NULL;
-
- while (isspace (line[0]))
-@@ -778,9 +851,10 @@ nss_getline (char *line)
- result = (name_database_entry *) malloc (sizeof (name_database_entry) + len);
- if (result == NULL)
- return NULL;
-+ result->name = (char *) (result + 1);
-
- /* Save the database name. */
-- memcpy (result->name, name, len);
-+ memcpy ((char *) result->name, name, len);
-
- /* Parse the list of services. */
- result->service = nss_parse_service_list (line);
-@@ -816,6 +890,7 @@ nss_new_service (name_database *database, const char *name)
- return *currentp;
- }
- #endif
-+#endif /* __OPTION_EGLIBC_NSSWITCH */
-
-
- #if defined SHARED && defined USE_NSCD
-@@ -834,6 +909,7 @@ nss_load_all_libraries (const char *service, const char *def)
- }
-
-
-+#if __OPTION_EGLIBC_INET
- /* Called by nscd and nscd alone. */
- void
- __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
-@@ -857,8 +933,10 @@ __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
- __nss_not_use_nscd_services = -1;
- __nss_not_use_nscd_netgroup = -1;
- }
-+#endif /* __OPTION_EGLIBC_INET */
- #endif
-
-+#if __OPTION_EGLIBC_NSSWITCH
- static void
- free_database_entries (name_database_entry *entry)
- {
-@@ -871,8 +949,8 @@ free_database_entries (name_database_entry *entry)
- {
- service_user *olds = service;
-
-- if (service->known != NULL)
-- __tdestroy (service->known, free);
-+ if (service->known.tree != NULL)
-+ __tdestroy (service->known.tree, free);
-
- service = service->next;
- free (olds);
-@@ -926,3 +1004,4 @@ libc_freeres_fn (free_mem)
-
- free (top);
- }
-+#endif /* __OPTION_EGLIBC_NSSWITCH */
-diff --git a/nss/nsswitch.h b/nss/nsswitch.h
-index a5318fa..1730977 100644
---- a/nss/nsswitch.h
-+++ b/nss/nsswitch.h
-@@ -65,10 +65,20 @@ typedef struct service_user
- lookup_actions actions[5];
- /* Link to the underlying library object. */
- service_library *library;
-- /* Collection of known functions. */
-- void *known;
-+ /* Collection of known functions.
-+
-+ With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
-+ 'tsearch'-style tree.
-+
-+ With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
-+ pointers to known_function structures, NULL-terminated. */
-+ union
-+ {
-+ void *tree;
-+ const known_function **array;
-+ } known;
- /* Name of the service (`files', `dns', `nis', ...). */
-- char name[0];
-+ const char *name;
- } service_user;
-
- /* To access the action based on the status value use this macro. */
-@@ -82,7 +92,7 @@ typedef struct name_database_entry
- /* List of service to be used. */
- service_user *service;
- /* Name of the database. */
-- char name[0];
-+ const char *name;
- } name_database_entry;
-
-
-diff --git a/posix/Makefile b/posix/Makefile
-index 15e8818..609ed03 100644
---- a/posix/Makefile
-+++ b/posix/Makefile
-@@ -18,6 +18,8 @@
- #
- # Sub-makefile for POSIX portion of the library.
- #
-+include ../option-groups.mak
-+
- subdir := posix
-
- include ../Makeconfig
-@@ -43,13 +45,24 @@ routines := \
- getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid \
- getresuid getresgid setresuid setresgid \
- pathconf sysconf fpathconf \
-- glob glob64 fnmatch regex \
-+ glob glob64 fnmatch \
- confstr \
- getopt getopt1 getopt_init \
- sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax \
- sched_primin sched_rr_gi sched_getaffinity sched_setaffinity \
-- getaddrinfo gai_strerror wordexp \
- pread pwrite pread64 pwrite64 \
-+ posix_madvise \
-+ get_child_max sched_cpucount sched_cpualloc sched_cpufree
-+
-+routines-$(OPTION_EGLIBC_INET) += getaddrinfo gai_strerror
-+
-+ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
-+routines-$(OPTION_POSIX_REGEXP) += regex
-+else
-+routines-$(OPTION_POSIX_REGEXP) += xregex
-+endif
-+
-+routines-$(OPTION_EGLIBC_SPAWN) += \
- spawn_faction_init spawn_faction_destroy spawn_faction_addclose \
- spawn_faction_addopen spawn_faction_adddup2 \
- spawnattr_init spawnattr_destroy \
-@@ -61,37 +74,54 @@ routines := \
- posix_madvise \
- get_child_max sched_cpucount sched_cpualloc sched_cpufree
-
-+routines-$(OPTION_EGLIBC_WORDEXP) += wordexp
-+
- aux := init-posix environ
--tests := tstgetopt testfnm runtests runptests \
-+tests := tstgetopt testfnm runtests \
- tst-preadwrite tst-preadwrite64 test-vfork regexbug1 \
-- tst-mmap tst-getaddrinfo tst-truncate \
-- tst-truncate64 tst-fork tst-fnmatch tst-regexloc tst-dir \
-- tst-chmod bug-regex1 bug-regex2 bug-regex3 bug-regex4 \
-- tst-gnuglob tst-regex bug-regex5 bug-regex6 bug-regex7 \
-- bug-regex8 bug-regex9 bug-regex10 bug-regex11 bug-regex12 \
-- bug-regex13 bug-regex14 bug-regex15 bug-regex16 \
-- bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
-- bug-regex21 bug-regex22 bug-regex23 bug-regex24 \
-- bug-regex25 bug-regex26 bug-regex27 bug-regex28 \
-+ tst-mmap tst-truncate \
-+ tst-truncate64 tst-fork tst-dir \
-+ tst-chmod bug-regex2 bug-regex3 bug-regex4 \
-+ tst-gnuglob bug-regex6 bug-regex7 \
-+ bug-regex8 bug-regex9 bug-regex10 bug-regex12 \
-+ bug-regex14 bug-regex15 \
-+ bug-regex21 bug-regex24 \
-+ bug-regex27 bug-regex28 \
- bug-regex29 bug-regex30 bug-regex31 bug-regex32 \
-- bug-regex33 tst-nice tst-nanosleep tst-regex2 \
-- transbug tst-rxspencer tst-pcre tst-boost \
-- bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
-- tst-getaddrinfo2 bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
-+ tst-nice tst-nanosleep \
-+ transbug \
-+ tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
-+ bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
- tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \
- tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
- tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
-- tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
-- tst-rfc3484-3 \
-- tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
-+ tst-execvp3 tst-execvp4 \
-+ tst-fnmatch2 tst-cpucount tst-cpuset \
- bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
- bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
- tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \
- tst-fnmatch3 bug-regex36 tst-getaddrinfo5
--xtests := bug-ga2
-+
-+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
-+ += tst-fnmatch tst-regexloc bug-regex1 bug-regex5 \
-+ bug-regex23 bug-regex25 bug-regex32 bug-regex33
-+tests-$(OPTION_EGLIBC_INET) \
-+ += tst-getaddrinfo bug-ga1 tst-getaddrinfo2 \
-+ tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 tst-getaddrinfo3
-+tests-$(OPTION_POSIX_REGEXP_GLIBC) \
-+ += runptests bug-regex11 bug-regex13 bug-regex16 \
-+ tst-regex2 tst-rxspencer tst-pcre tst-boost
-+ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP_GLIBC))
-+tests += tst-regex bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
-+ bug-regex22 bug-regex26
-+endif
-+xtests-$(OPTION_EGLIBC_INET) += bug-ga2
-+
- ifeq (yes,$(build-shared))
- test-srcs := globtest
--tests += wordexp-test tst-exec tst-spawn
-+tests += tst-exec
-+tests-$(OPTION_EGLIBC_SPAWN) += tst-spawn
-+tests-$(OPTION_EGLIBC_WORDEXP) += wordexp-test
- endif
- tests-static = tst-exec-static tst-spawn-static
- tests += $(tests-static)
-@@ -117,7 +147,10 @@ generated += $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
-
- ifeq ($(run-built-tests),yes)
- ifeq (yes,$(build-shared))
--tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out
-+tests-special += $(objpfx)globtest.out
-+ifeq (y,$(OPTION_EGLIBC_WORDEXP))
-+tests-special += $(objpfx)wordexp-tst.out
-+endif
- endif
- endif
-
-@@ -125,12 +158,16 @@ endif
- # XXX Please note that for now we ignore the result of this test.
- tests-special += $(objpfx)annexc.out
- ifeq ($(run-built-tests),yes)
--tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
-+tests-special += $(objpfx)bug-regex2-mem.out \
- $(objpfx)bug-regex21-mem.out $(objpfx)bug-regex31-mem.out \
-- $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
-- $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
-+ $(objpfx)tst-getconf.out \
- $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
- $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
-+ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
-+tests-special += $(objpfx)bug-regex14-mem.out $(objpfx)tst-rxspencer-no-utf8-mem.out \
-+ $(objpfx)tst-pcre-mem.out $(objpfx)tst-boost-mem.out
-+endif
-+
- xtests-special += $(objpfx)bug-ga2-mem.out
- endif
-
-@@ -143,6 +180,8 @@ $(objpfx)globtest.out: globtest.sh $(objpfx)globtest
- $(SHELL) $< $(common-objpfx) '$(test-via-rtld-prefix)' \
- '$(test-program-prefix)' '$(test-wrapper-env)'; \
- $(evaluate-test)
-+LDLIBS-globtest += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
-+
- $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test
- $(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \
- '$(run-program-env)' '$(test-program-prefix-after-env)'; \
-@@ -205,7 +244,10 @@ tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir);
- tst-chmod-ARGS = $(objdir)
- tst-vfork3-ARGS = --test-dir=$(objpfx)
-
--tst-rxspencer-ARGS = --utf8 rxspencer/tests
-+tst-rxspencer-ARGS = rxspencer/tests
-+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
-+tst-rxspencer-ARGS += --utf8
-+endif
- tst-rxspencer-no-utf8-ARGS = rxspencer/tests
- tst-pcre-ARGS = PCRE.tests
- tst-boost-ARGS = BOOST.tests
-diff --git a/posix/bug-regex1.c b/posix/bug-regex1.c
-index 38eb543..17cd1a0 100644
---- a/posix/bug-regex1.c
-+++ b/posix/bug-regex1.c
-@@ -4,6 +4,7 @@
- #include <string.h>
- #include <regex.h>
- #include <wchar.h>
-+#include <gnu/option-groups.h>
-
- int
- main (void)
-@@ -17,7 +18,9 @@ main (void)
- memset (&regex, '\0', sizeof (regex));
-
- setlocale (LC_ALL, "de_DE.ISO-8859-1");
-+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
- fwide (stdout, -1);
-+#endif
-
- re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_DEBUG);
-
-diff --git a/posix/bug-regex6.c b/posix/bug-regex6.c
-index efcc890..3b270c7 100644
---- a/posix/bug-regex6.c
-+++ b/posix/bug-regex6.c
-@@ -22,6 +22,7 @@
- #include <string.h>
- #include <sys/types.h>
- #include <regex.h>
-+#include <gnu/option-groups.h>
-
-
- int
-@@ -30,7 +31,12 @@ main (int argc, char *argv[])
- regex_t re;
- regmatch_t mat[10];
- int i, j, ret = 0;
-- const char *locales[] = { "C", "de_DE.UTF-8" };
-+ const char *locales[] = {
-+ "C",
-+#if __OPTION_EGLIBC_LOCALE_CODE
-+ "de_DE.UTF-8"
-+#endif
-+ };
- const char *string = "http://www.regex.com/pattern/matching.html#intro";
- regmatch_t expect[10] = {
- { 0, 48 }, { 0, 5 }, { 0, 4 }, { 5, 20 }, { 7, 20 }, { 20, 42 },
-diff --git a/posix/fnmatch.c b/posix/fnmatch.c
-index fd85efa..01cc9fe 100644
---- a/posix/fnmatch.c
-+++ b/posix/fnmatch.c
-@@ -30,6 +30,10 @@
- #include <ctype.h>
- #include <string.h>
-
-+#if defined _LIBC
-+# include <gnu/option-groups.h>
-+#endif
-+
- #if defined STDC_HEADERS || defined _LIBC
- # include <stdlib.h>
- #endif
-@@ -131,7 +135,7 @@ extern int fnmatch (const char *pattern, const char *string, int flags);
- # define ISWCTYPE(WC, WT) iswctype (WC, WT)
- # endif
-
--# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
-+# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS && _LIBC && __OPTION_EGLIBC_LOCALE_CODE)
- /* In this case we are implementing the multibyte character handling. */
- # define HANDLE_MULTIBYTE 1
- # endif
-diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c
-index f46c9df..74e1754 100644
---- a/posix/fnmatch_loop.c
-+++ b/posix/fnmatch_loop.c
-@@ -15,6 +15,8 @@
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-+#include <gnu/option-groups.h>
-+
- #include <stdint.h>
-
- struct STRUCT
-@@ -54,10 +56,15 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
- const char *collseq = (const char *)
- _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
- # else
-+# if __OPTION_EGLIBC_LOCALE_CODE
- const UCHAR *collseq = (const UCHAR *)
- _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
--# endif
--#endif
-+# define COLLSEQ_BYTE_LOOKUP(ix) (collseq[(ix)])
-+# else
-+# define COLLSEQ_BYTE_LOOKUP(ix) (ix)
-+# endif /* __OPTION_EGLIBC_LOCALE_CODE */
-+# endif /* WIDE_CHAR_VERSION */
-+#endif /* _LIBC */
-
- while ((c = *p++) != L('\0'))
- {
-@@ -277,7 +284,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
- /* Leave room for the null. */
- CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
- size_t c1 = 0;
--#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
-+#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
- wctype_t wt;
- #endif
- const CHAR *startp = p;
-@@ -307,7 +314,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
- }
- str[c1] = L('\0');
-
--#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
-+#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
- wt = IS_CHAR_CLASS (str);
- if (wt == 0)
- /* Invalid character class name. */
-@@ -680,8 +687,10 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
- else
- lcollseq = __collseq_table_lookup (collseq, cold);
- # else
-- fcollseq = collseq[fn];
-- lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
-+ fcollseq = COLLSEQ_BYTE_LOOKUP (fn);
-+ lcollseq = (is_seqval
-+ ? cold
-+ : COLLSEQ_BYTE_LOOKUP ((UCHAR) cold));
- # endif
-
- is_seqval = 0;
-@@ -857,7 +866,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
- goto matched;
- }
- # else
-- hcollseq = collseq[cend];
-+ hcollseq = COLLSEQ_BYTE_LOOKUP (cend);
- # endif
- }
-
-diff --git a/posix/glob.c b/posix/glob.c
-index d65e55d..1ac00a1 100644
---- a/posix/glob.c
-+++ b/posix/glob.c
-@@ -25,6 +25,9 @@
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stddef.h>
-+#ifdef _LIBC
-+# include <gnu/option-groups.h>
-+#endif
-
- /* Outcomment the following line for production quality code. */
- /* #define NDEBUG 1 */
-@@ -607,6 +610,7 @@ glob (pattern, flags, errfunc, pglob)
- if (home_dir == NULL || home_dir[0] == '\0')
- home_dir = "c:/users/default"; /* poor default */
- # else
-+# if ! _LIBC || __OPTION_EGLIBC_GETLOGIN
- if (home_dir == NULL || home_dir[0] == '\0')
- {
- int success;
-@@ -623,19 +627,19 @@ glob (pattern, flags, errfunc, pglob)
- if (success)
- {
- struct passwd *p;
--# if defined HAVE_GETPWNAM_R || defined _LIBC
-+# if defined HAVE_GETPWNAM_R || defined _LIBC
- long int pwbuflen = GETPW_R_SIZE_MAX ();
- char *pwtmpbuf;
- struct passwd pwbuf;
- int malloc_pwtmpbuf = 0;
- int save = errno;
-
--# ifndef _LIBC
-+# ifndef _LIBC
- if (pwbuflen == -1)
- /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
- Try a moderate value. */
- pwbuflen = 1024;
--# endif
-+# endif
- if (__libc_use_alloca (alloca_used + pwbuflen))
- pwtmpbuf = alloca_account (pwbuflen, alloca_used);
- else
-@@ -682,9 +686,9 @@ glob (pattern, flags, errfunc, pglob)
- }
- __set_errno (save);
- }
--# else
-+# else
- p = getpwnam (name);
--# endif
-+# endif
- if (p != NULL)
- {
- if (!malloc_pwtmpbuf)
-@@ -713,6 +717,7 @@ glob (pattern, flags, errfunc, pglob)
- }
- }
- }
-+# endif /* ! _LIBC || __OPTION_EGLIBC_GETLOGIN */
- if (home_dir == NULL || home_dir[0] == '\0')
- {
- if (flags & GLOB_TILDE_CHECK)
-diff --git a/posix/regcomp.c b/posix/regcomp.c
-index bf8aa16..6a41251 100644
---- a/posix/regcomp.c
-+++ b/posix/regcomp.c
-@@ -18,6 +18,7 @@
- <http://www.gnu.org/licenses/>. */
-
- #include <stdint.h>
-+#include <gnu/option-groups.h>
-
- #ifdef _LIBC
- # include <locale/weight.h>
-@@ -309,7 +310,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
- {
- re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
- int node_cnt;
-- int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
-+ int icase = (dfa_mb_cur_max (dfa) == 1 && (bufp->syntax & RE_ICASE));
- for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
- {
- int node = init_state->nodes.elems[node_cnt];
-@@ -319,9 +320,9 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
- {
- re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
- #ifdef RE_ENABLE_I18N
-- if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
-+ if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
- {
-- unsigned char *buf = alloca (dfa->mb_cur_max), *p;
-+ unsigned char *buf = alloca (dfa_mb_cur_max (dfa)), *p;
- wchar_t wc;
- mbstate_t state;
-
-@@ -352,7 +353,11 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
- re_set_fastmap (fastmap, icase, ch);
- }
- }
--#ifdef RE_ENABLE_I18N
-+
-+ /* When OPTION_EGLIBC_LOCALE_CODE is disabled, the current
-+ locale is always C, which has no rules and no multi-byte
-+ characters. */
-+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
- else if (type == COMPLEX_BRACKET)
- {
- re_charset_t *cset = dfa->nodes[node].opr.mbcset;
-@@ -380,7 +385,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
- 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
-+ if (dfa_mb_cur_max (dfa) > 1
- && (cset->nchar_classes || cset->non_match || cset->nranges
- # ifdef _LIBC
- || cset->nequiv_classes
-@@ -408,7 +413,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_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 ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
- {
- if (__wcrtomb (buf, __towlower (cset->mbchars[i]), &state)
- != (size_t) -1)
-@@ -417,7 +422,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
- }
- }
- }
--#endif /* RE_ENABLE_I18N */
-+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
- else if (type == OP_PERIOD
- #ifdef RE_ENABLE_I18N
- || type == OP_UTF8_PERIOD
-@@ -860,11 +865,15 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
-
- dfa->mb_cur_max = MB_CUR_MAX;
- #ifdef _LIBC
-- if (dfa->mb_cur_max == 6
-+ if (dfa_mb_cur_max (dfa) == 6
- && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
- dfa->is_utf8 = 1;
-+# if __OPTION_EGLIBC_LOCALE_CODE
- dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
- != 0);
-+# else
-+ dfa->map_notascii = 0;
-+# endif
- #else
- # ifdef HAVE_LANGINFO_CODESET
- codeset_name = nl_langinfo (CODESET);
-@@ -890,7 +899,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
- #endif
-
- #ifdef RE_ENABLE_I18N
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- {
- if (dfa->is_utf8)
- dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
-@@ -1788,7 +1797,7 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
- token->word_char = 0;
- #ifdef RE_ENABLE_I18N
- token->mb_partial = 0;
-- if (input->mb_cur_max > 1 &&
-+ if (string_mb_cur_max (input) > 1 &&
- !re_string_first_byte (input, re_string_cur_idx (input)))
- {
- token->type = CHARACTER;
-@@ -1809,7 +1818,7 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
- token->opr.c = c2;
- token->type = CHARACTER;
- #ifdef RE_ENABLE_I18N
-- if (input->mb_cur_max > 1)
-+ if (string_mb_cur_max (input) > 1)
- {
- wint_t wc = re_string_wchar_at (input,
- re_string_cur_idx (input) + 1);
-@@ -1923,7 +1932,7 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
-
- token->type = CHARACTER;
- #ifdef RE_ENABLE_I18N
-- if (input->mb_cur_max > 1)
-+ if (string_mb_cur_max (input) > 1)
- {
- wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
- token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
-@@ -2023,7 +2032,7 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
- token->opr.c = c;
-
- #ifdef RE_ENABLE_I18N
-- if (input->mb_cur_max > 1 &&
-+ if (string_mb_cur_max (input) > 1 &&
- !re_string_first_byte (input, re_string_cur_idx (input)))
- {
- token->type = CHARACTER;
-@@ -2246,7 +2255,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
- return NULL;
- }
- #ifdef RE_ENABLE_I18N
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- {
- while (!re_string_eoi (regexp)
- && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
-@@ -2384,7 +2393,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
- *err = REG_ESPACE;
- return NULL;
- }
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- dfa->has_mb_node = 1;
- break;
- case OP_WORD:
-@@ -2690,7 +2699,7 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
- 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. */
-+ no MBCSET if dfa_mb_cur_max (dfa) == 1. */
- if (mbcset)
- {
- /* Check the space of the arrays. */
-@@ -2786,7 +2795,13 @@ 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
-+#if __OPTION_EGLIBC_LOCALE_CODE
- const unsigned char *collseqmb;
-+# define COLLSEQMB_LOOKUP(ix) (collseqmb[(ix)])
-+#else
-+# define COLLSEQMB_LOOKUP(ix) (ix)
-+#endif
-+
- const char *collseqwc;
- uint32_t nrules;
- int32_t table_size;
-@@ -2834,18 +2849,20 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
- if (MB_CUR_MAX == 1)
- */
- if (nrules == 0)
-- return collseqmb[br_elem->opr.ch];
-+ return COLLSEQMB_LOOKUP (br_elem->opr.ch);
- else
- {
- wint_t wc = __btowc (br_elem->opr.ch);
- return __collseq_table_lookup (collseqwc, wc);
- }
- }
-+#if __OPTION_EGLIBC_LOCALE_CODE
- else if (br_elem->type == MB_CHAR)
- {
- if (nrules != 0)
- return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
- }
-+#endif
- else if (br_elem->type == COLL_SYM)
- {
- size_t sym_name_len = strlen ((char *) br_elem->opr.name);
-@@ -2876,11 +2893,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
- {
- /* No valid character. Match it as a single byte
- character. */
-- return collseqmb[br_elem->opr.name[0]];
-+ return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
- }
- }
- else if (sym_name_len == 1)
-- return collseqmb[br_elem->opr.name[0]];
-+ return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
- }
- return UINT_MAX;
- }
-@@ -2920,7 +2937,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
- 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)
-+ if (nrules > 0 || dfa_mb_cur_max (dfa) > 1)
- {
- /* Check the space of the arrays. */
- if (BE (*range_alloc == mbcset->nranges, 0))
-@@ -2957,7 +2974,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
- if (MB_CUR_MAX == 1)
- */
- if (nrules == 0)
-- ch_collseq = collseqmb[ch];
-+ ch_collseq = COLLSEQMB_LOOKUP (ch);
- else
- ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
- if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
-@@ -3035,7 +3052,10 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
- re_bitset_ptr_t sbcset;
- #ifdef RE_ENABLE_I18N
- re_charset_t *mbcset;
-- int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
-+ int coll_sym_alloc = 0, range_alloc = 0;
-+#if __OPTION_EGLIBC_LOCALE_CODE
-+ int mbchar_alloc = 0;
-+#endif
- int equiv_class_alloc = 0, char_class_alloc = 0;
- #endif /* not RE_ENABLE_I18N */
- int non_match = 0;
-@@ -3043,9 +3063,15 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
- int token_len;
- int first_round = 1;
- #ifdef _LIBC
-+#if __OPTION_EGLIBC_LOCALE_CODE
- collseqmb = (const unsigned char *)
- _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
- nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-+#else
-+ /* This is true when OPTION_EGLIBC_LOCALE_CODE is disabled, but the
-+ compiler can't figure that out. */
-+ nrules = 0;
-+#endif
- if (nrules)
- {
- /*
-@@ -3175,7 +3201,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
- #else
- # ifdef RE_ENABLE_I18N
- *err = build_range_exp (sbcset,
-- dfa->mb_cur_max > 1 ? mbcset : NULL,
-+ dfa_mb_cur_max (dfa) > 1 ? mbcset : NULL,
- &range_alloc, &start_elem, &end_elem);
- # else
- *err = build_range_exp (sbcset, &start_elem, &end_elem);
-@@ -3191,7 +3217,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
- case SB_CHAR:
- bitset_set (sbcset, start_elem.opr.ch);
- break;
--#ifdef RE_ENABLE_I18N
-+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
- case MB_CHAR:
- /* Check whether the array has enough space. */
- if (BE (mbchar_alloc == mbcset->nmbchars, 0))
-@@ -3209,7 +3235,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
- }
- mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
- break;
--#endif /* RE_ENABLE_I18N */
-+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
- case EQUIV_CLASS:
- *err = build_equiv_class (sbcset,
- #ifdef RE_ENABLE_I18N
-@@ -3259,11 +3285,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
-
- #ifdef RE_ENABLE_I18N
- /* Ensure only single byte characters are set. */
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 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->nranges || (dfa_mb_cur_max (dfa) > 1 && (mbcset->nchar_classes
- || mbcset->non_match)))
- {
- bin_tree_t *mbc_tree;
-@@ -3332,7 +3358,7 @@ 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, int accept_hyphen)
- {
--#ifdef RE_ENABLE_I18N
-+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
- int cur_char_size;
- cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
- if (cur_char_size > 1)
-@@ -3342,7 +3368,7 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
- re_string_skip_bytes (regexp, cur_char_size);
- return REG_NOERROR;
- }
--#endif /* RE_ENABLE_I18N */
-+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
- 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)
-@@ -3422,7 +3448,9 @@ build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
- build_equiv_class (bitset_t sbcset, const unsigned char *name)
- #endif /* not RE_ENABLE_I18N */
- {
--#ifdef _LIBC
-+ /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C locale
-+ is supported; it has no collation rules. */
-+#if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
- uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
- if (nrules != 0)
- {
-@@ -3492,7 +3520,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
- mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
- }
- else
--#endif /* _LIBC */
-+#endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
- {
- if (BE (strlen ((const char *) name) != 1, 0))
- return REG_ECOLLATE;
-@@ -3526,7 +3554,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
- && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
- name = "alpha";
-
--#ifdef RE_ENABLE_I18N
-+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
- /* Check the space of the arrays. */
- if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
- {
-@@ -3542,7 +3570,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
- *char_class_alloc = new_char_class_alloc;
- }
- mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
--#endif /* RE_ENABLE_I18N */
-+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
-
- #define BUILD_CHARCLASS_LOOP(ctype_func) \
- do { \
-@@ -3653,7 +3681,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
-
- #ifdef RE_ENABLE_I18N
- /* Ensure only single byte characters are set. */
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- bitset_mask (sbcset, dfa->sb_char);
- #endif
-
-@@ -3665,7 +3693,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
- goto build_word_op_espace;
-
- #ifdef RE_ENABLE_I18N
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- {
- bin_tree_t *mbc_tree;
- /* Build a tree for complex bracket. */
-diff --git a/posix/regex.h b/posix/regex.h
-index 5b1981e..2941f94 100644
---- a/posix/regex.h
-+++ b/posix/regex.h
-@@ -21,6 +21,7 @@
- #define _REGEX_H 1
-
- #include <sys/types.h>
-+#include <gnu/option-groups.h>
-
- /* Allow the use in C++ code. */
- #ifdef __cplusplus
-@@ -156,6 +157,8 @@ typedef unsigned long int reg_syntax_t;
- treated as 'a\{1'. */
- # define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
-
-+/* EGLIBC: Old regex implementation does not support these. */
-+# if __OPTION_POSIX_REGEXP_GLIBC
- /* 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)
-@@ -172,6 +175,7 @@ typedef unsigned long int reg_syntax_t;
- /* 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 /* __OPTION_POSIX_REGEXP_GLIBC */
- #endif
-
- /* This global variable defines the particular regexp syntax to use (for
-@@ -231,8 +235,13 @@ extern reg_syntax_t re_syntax_options;
- (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
- | RE_INTERVALS | RE_NO_EMPTY_RANGES)
-
-+#if __OPTION_POSIX_REGEXP_GLIBC
- #define RE_SYNTAX_POSIX_BASIC \
- (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
-+#else
-+#define RE_SYNTAX_POSIX_BASIC \
-+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
-+#endif
-
- /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
- RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
-@@ -298,9 +307,11 @@ extern reg_syntax_t re_syntax_options;
- /* Like REG_NOTBOL, except for the end-of-line. */
- #define REG_NOTEOL (1 << 1)
-
-+#if __OPTION_POSIX_REGEXP_GLIBC
- /* Use PMATCH[0] to delimit the start and end of the search in the
- buffer. */
- #define REG_STARTEND (1 << 2)
-+#endif
-
-
- /* If any error codes are removed, changed, or added, update the
-diff --git a/posix/regex_internal.c b/posix/regex_internal.c
-index 8597d7e..d53b2a8 100644
---- a/posix/regex_internal.c
-+++ b/posix/regex_internal.c
-@@ -43,8 +43,8 @@ re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
- int 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;
-+ if (init_len < dfa_mb_cur_max (dfa))
-+ init_len = dfa_mb_cur_max (dfa);
- init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
- re_string_construct_common (str, len, pstr, trans, icase, dfa);
-
-@@ -55,7 +55,7 @@ re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
- 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_len = (pstr->mbs_allocated || dfa_mb_cur_max (dfa) > 1) ? 0 : len;
- pstr->valid_raw_len = pstr->valid_len;
- return REG_NOERROR;
- }
-@@ -82,7 +82,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
- if (icase)
- {
- #ifdef RE_ENABLE_I18N
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- {
- while (1)
- {
-@@ -91,7 +91,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
- return ret;
- if (pstr->valid_raw_len >= len)
- break;
-- if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
-+ if (pstr->bufs_len > pstr->valid_len + dfa_mb_cur_max (dfa))
- break;
- ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
- if (BE (ret != REG_NOERROR, 0))
-@@ -105,7 +105,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
- else
- {
- #ifdef RE_ENABLE_I18N
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- build_wcs_buffer (pstr);
- else
- #endif /* RE_ENABLE_I18N */
-@@ -130,7 +130,7 @@ internal_function __attribute_warn_unused_result__
- re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
- {
- #ifdef RE_ENABLE_I18N
-- if (pstr->mb_cur_max > 1)
-+ if (string_mb_cur_max (pstr) > 1)
- {
- wint_t *new_wcs;
-
-@@ -177,7 +177,7 @@ re_string_construct_common (const char *str, int len, re_string_t *pstr,
- pstr->trans = trans;
- pstr->icase = icase ? 1 : 0;
- pstr->mbs_allocated = (trans != NULL || icase);
-- pstr->mb_cur_max = dfa->mb_cur_max;
-+ pstr->mb_cur_max = dfa_mb_cur_max (dfa);
- pstr->is_utf8 = dfa->is_utf8;
- pstr->map_notascii = dfa->map_notascii;
- pstr->stop = pstr->len;
-@@ -203,7 +203,7 @@ build_wcs_buffer (re_string_t *pstr)
- {
- #ifdef _LIBC
- unsigned char buf[MB_LEN_MAX];
-- assert (MB_LEN_MAX >= pstr->mb_cur_max);
-+ assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
- #else
- unsigned char buf[64];
- #endif
-@@ -226,7 +226,7 @@ build_wcs_buffer (re_string_t *pstr)
- {
- int i, ch;
-
-- for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
-+ for (i = 0; i < string_mb_cur_max (pstr) && 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];
-@@ -275,7 +275,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
- size_t mbclen;
- #ifdef _LIBC
- char buf[MB_LEN_MAX];
-- assert (MB_LEN_MAX >= pstr->mb_cur_max);
-+ assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
- #else
- char buf[64];
- #endif
-@@ -369,7 +369,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
- {
- int i, ch;
-
-- for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
-+ for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
- {
- ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
- buf[i] = pstr->trans[ch];
-@@ -567,8 +567,9 @@ re_string_translate_buffer (re_string_t *pstr)
- }
-
- /* 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. */
-+ Concretely, convert to wide character in case of
-+ string_mb_cur_max (pstr) > 1, convert to upper case in case of
-+ REG_ICASE, apply translation. */
-
- static reg_errcode_t
- internal_function __attribute_warn_unused_result__
-@@ -579,7 +580,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
- {
- /* Reset buffer. */
- #ifdef RE_ENABLE_I18N
-- if (pstr->mb_cur_max > 1)
-+ if (string_mb_cur_max (pstr) > 1)
- memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
- #endif /* RE_ENABLE_I18N */
- pstr->len = pstr->raw_len;
-@@ -670,7 +671,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
- pstr->tip_context = re_string_context_at (pstr, offset - 1,
- eflags);
- #ifdef RE_ENABLE_I18N
-- if (pstr->mb_cur_max > 1)
-+ if (string_mb_cur_max (pstr) > 1)
- memmove (pstr->wcs, pstr->wcs + offset,
- (pstr->valid_len - offset) * sizeof (wint_t));
- #endif /* RE_ENABLE_I18N */
-@@ -699,7 +700,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
- #endif
- pstr->valid_len = 0;
- #ifdef RE_ENABLE_I18N
-- if (pstr->mb_cur_max > 1)
-+ if (string_mb_cur_max (pstr) > 1)
- {
- int wcs_idx;
- wint_t wc = WEOF;
-@@ -711,7 +712,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
- /* 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);
-+ end = raw + (offset - string_mb_cur_max (pstr));
- if (end < pstr->raw_mbs)
- end = pstr->raw_mbs;
- p = raw + offset - 1;
-@@ -803,7 +804,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
-
- /* Then build the buffers. */
- #ifdef RE_ENABLE_I18N
-- if (pstr->mb_cur_max > 1)
-+ if (string_mb_cur_max (pstr) > 1)
- {
- if (pstr->icase)
- {
-@@ -841,7 +842,7 @@ re_string_peek_byte_case (const re_string_t *pstr, int idx)
- return re_string_peek_byte (pstr, idx);
-
- #ifdef RE_ENABLE_I18N
-- if (pstr->mb_cur_max > 1
-+ if (string_mb_cur_max (pstr) > 1
- && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
- return re_string_peek_byte (pstr, idx);
- #endif
-@@ -930,7 +931,7 @@ re_string_context_at (const re_string_t *input, int idx, int eflags)
- return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
- : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
- #ifdef RE_ENABLE_I18N
-- if (input->mb_cur_max > 1)
-+ if (string_mb_cur_max (input) > 1)
- {
- wint_t wc;
- int wc_idx = idx;
-@@ -1444,7 +1445,7 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
- dfa->nodes[dfa->nodes_len].constraint = 0;
- #ifdef RE_ENABLE_I18N
- dfa->nodes[dfa->nodes_len].accept_mb =
-- (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
-+ (type == OP_PERIOD && dfa_mb_cur_max (dfa) > 1) || type == COMPLEX_BRACKET;
- #endif
- dfa->nexts[dfa->nodes_len] = -1;
- re_node_set_init_empty (dfa->edests + dfa->nodes_len);
-diff --git a/posix/regex_internal.h b/posix/regex_internal.h
-index 154e969..c43909a 100644
---- a/posix/regex_internal.h
-+++ b/posix/regex_internal.h
-@@ -26,6 +26,10 @@
- #include <stdlib.h>
- #include <string.h>
-
-+#if defined _LIBC
-+# include <gnu/option-groups.h>
-+#endif
-+
- #if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
- # include <langinfo.h>
- #endif
-@@ -369,6 +373,13 @@ struct re_string_t
- };
- typedef struct re_string_t re_string_t;
-
-+/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
-+ help the compiler make use of that fact. */
-+#if __OPTION_EGLIBC_LOCALE_CODE
-+# define string_mb_cur_max(str) ((str)->mb_cur_max + 0)
-+#else
-+# define string_mb_cur_max(str) (1)
-+#endif
-
- struct re_dfa_t;
- typedef struct re_dfa_t re_dfa_t;
-@@ -654,6 +665,14 @@ struct re_dfa_t
- __libc_lock_define (, lock)
- };
-
-+/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
-+ help the compiler make use of that fact. */
-+#if __OPTION_EGLIBC_LOCALE_CODE
-+# define dfa_mb_cur_max(dfa) ((dfa)->mb_cur_max + 0)
-+#else
-+# define dfa_mb_cur_max(dfa) (1)
-+#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))
-@@ -714,7 +733,7 @@ internal_function __attribute__ ((pure, unused))
- re_string_char_size_at (const re_string_t *pstr, int idx)
- {
- int byte_idx;
-- if (pstr->mb_cur_max == 1)
-+ if (string_mb_cur_max (pstr) == 1)
- return 1;
- for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
- if (pstr->wcs[idx + byte_idx] != WEOF)
-@@ -726,7 +745,7 @@ static wint_t
- internal_function __attribute__ ((pure, unused))
- re_string_wchar_at (const re_string_t *pstr, int idx)
- {
-- if (pstr->mb_cur_max == 1)
-+ if (string_mb_cur_max (pstr) == 1)
- return (wint_t) pstr->mbs[idx];
- return (wint_t) pstr->wcs[idx];
- }
-diff --git a/posix/regexec-compat.c b/posix/regexec-compat.c
-new file mode 100644
-index 0000000..0f9b7c7
---- /dev/null
-+++ b/posix/regexec-compat.c
-@@ -0,0 +1,39 @@
-+/* Extended regular expression matching and search library.
-+ Copyright (C) 2008 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA. */
-+
-+#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
-diff --git a/posix/regexec.c b/posix/regexec.c
-index 70cd606..e3b49e4 100644
---- a/posix/regexec.c
-+++ b/posix/regexec.c
-@@ -18,6 +18,7 @@
- <http://www.gnu.org/licenses/>. */
-
- #include <stdint.h>
-+#include <gnu/option-groups.h>
-
- static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
- int n) internal_function;
-@@ -186,11 +187,11 @@ static int build_trtable (const re_dfa_t *dfa,
- static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
- const re_string_t *input, int idx)
- internal_function;
--# ifdef _LIBC
-+# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
- static unsigned int find_collation_sequence_value (const unsigned char *mbs,
- size_t name_len)
- internal_function;
--# endif /* _LIBC */
-+# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
- #endif /* RE_ENABLE_I18N */
- static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
- const re_dfastate_t *state,
-@@ -255,25 +256,9 @@ regexec (preg, string, nmatch, pmatch, eflags)
- 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
-+/* EGLIBC: The code that used to be here was move to a separate file
-+ so that it can be shared with xregex.c. */
-+#include "regexec-compat.c"
-
- /* Entry points for GNU code. */
-
-@@ -728,7 +713,7 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
- incr = (range < 0) ? -1 : 1;
- left_lim = (range < 0) ? start + range : start;
- right_lim = (range < 0) ? start : start + range;
-- sb = dfa->mb_cur_max == 1;
-+ sb = dfa_mb_cur_max (dfa) == 1;
- match_kind =
- (fastmap
- ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
-@@ -3448,7 +3433,7 @@ out_free:
- 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)
-+ if (dest_states[i] != dest_states_word[i] && dfa_mb_cur_max (dfa) > 1)
- need_word_trtable = 1;
-
- dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
-@@ -3590,7 +3575,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
- else if (type == OP_PERIOD)
- {
- #ifdef RE_ENABLE_I18N
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- bitset_merge (accepts, dfa->sb_char);
- else
- #endif
-@@ -3641,7 +3626,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
- continue;
- }
- #ifdef RE_ENABLE_I18N
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- for (j = 0; j < BITSET_WORDS; ++j)
- any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
- else
-@@ -3660,7 +3645,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
- continue;
- }
- #ifdef RE_ENABLE_I18N
-- if (dfa->mb_cur_max > 1)
-+ if (dfa_mb_cur_max (dfa) > 1)
- for (j = 0; j < BITSET_WORDS; ++j)
- any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
- else
-@@ -3836,12 +3821,6 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
- 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);
-- int 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);
-@@ -3853,6 +3832,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
- match_len = char_len;
- goto check_node_accept_bytes_match;
- }
-+#if __OPTION_EGLIBC_LOCALE_CODE
- /* match with character_class? */
- for (i = 0; i < cset->nchar_classes; ++i)
- {
-@@ -3863,14 +3843,22 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
- goto check_node_accept_bytes_match;
- }
- }
-+#endif
-+
-+ /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C
-+ locale is supported; it has no collation rules. */
-+# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
-+ const unsigned char *pin
-+ = ((const unsigned char *) re_string_get_buffer (input) + str_idx);
-+ int j;
-+ uint32_t nrules;
-
--# 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 unsigned char *weights, *extra = NULL;
- const char *collseqwc;
-
- /* match with collating_symbol? */
-@@ -3955,8 +3943,12 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
- }
- }
- else
--# endif /* _LIBC */
-+# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
- {
-+ /* In the _LIBC version, if OPTION_EGLIBC_LOCALE_CODE is
-+ disabled, there can be no multibyte range endpoints, and
-+ cset->nranges is always zero. */
-+#if __OPTION_EGLIBC_LOCALE_CODE
- /* match with range expression? */
- #if __GNUC__ >= 2
- wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
-@@ -3975,6 +3967,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
- goto check_node_accept_bytes_match;
- }
- }
-+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
- }
- check_node_accept_bytes_match:
- if (!cset->non_match)
-@@ -3990,7 +3983,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
- return 0;
- }
-
--# ifdef _LIBC
-+# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
- static unsigned int
- internal_function
- find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
-@@ -4048,7 +4041,7 @@ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
- return UINT_MAX;
- }
- }
--# endif /* _LIBC */
-+# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
- #endif /* RE_ENABLE_I18N */
-
- /* Check whether the node accepts the byte which is IDX-th
-@@ -4139,7 +4132,7 @@ extend_buffers (re_match_context_t *mctx, int min_len)
- if (pstr->icase)
- {
- #ifdef RE_ENABLE_I18N
-- if (pstr->mb_cur_max > 1)
-+ if (string_mb_cur_max (pstr) > 1)
- {
- ret = build_wcs_upper_buffer (pstr);
- if (BE (ret != REG_NOERROR, 0))
-@@ -4152,7 +4145,7 @@ extend_buffers (re_match_context_t *mctx, int min_len)
- else
- {
- #ifdef RE_ENABLE_I18N
-- if (pstr->mb_cur_max > 1)
-+ if (string_mb_cur_max (pstr) > 1)
- build_wcs_buffer (pstr);
- else
- #endif /* RE_ENABLE_I18N */
-diff --git a/posix/xregex.c b/posix/xregex.c
-new file mode 100644
-index 0000000..d3f7ace
---- /dev/null
-+++ b/posix/xregex.c
-@@ -0,0 +1,8215 @@
-+/* Extended regular expression matching and search library,
-+ version 0.12.
-+ (Implements POSIX draft P1003.2/D11.2, except for some of the
-+ internationalization features.)
-+
-+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-+ 2002, 2005 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ 02110-1301 USA. */
-+
-+/* AIX requires this to be the first thing in the file. */
-+#if defined _AIX && !defined __GNUC__ && !defined REGEX_MALLOC
-+ #pragma alloca
-+#endif
-+
-+#undef _GNU_SOURCE
-+#define _GNU_SOURCE
-+
-+#ifndef INSIDE_RECURSION
-+# ifdef HAVE_CONFIG_H
-+# include <config.h>
-+# endif
-+#endif
-+
-+/*#include <ansidecl.h>*/
-+
-+
-+#ifndef INSIDE_RECURSION
-+
-+# if defined STDC_HEADERS && !defined emacs
-+# include <stddef.h>
-+# else
-+/* We need this for `regex.h', and perhaps for the Emacs include files. */
-+# include <sys/types.h>
-+# endif
-+
-+# if (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_BTOWC)
-+# define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC)
-+# else
-+# define WIDE_CHAR_SUPPORT 0
-+# endif
-+/* For platform which support the ISO C amendement 1 functionality we
-+ support user defined character classes. */
-+# if WIDE_CHAR_SUPPORT
-+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
-+# include <wchar.h>
-+# include <wctype.h>
-+# 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)
-+
-+# define btowc __btowc
-+
-+/* We are also using some library internals. */
-+# include <locale/localeinfo.h>
-+# include <locale/elem-hash.h>
-+# include <langinfo.h>
-+# include <locale/coll-lookup.h>
-+# 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) __dcgettext ("libc", 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
-+
-+/* The `emacs' switch turns on certain matching commands
-+ that make sense only in Emacs. */
-+# ifdef emacs
-+
-+# include "lisp.h"
-+# include "buffer.h"
-+# include "syntax.h"
-+
-+# else /* not emacs */
-+
-+/* If we are not linking with Emacs proper,
-+ we can't use the relocating allocator
-+ even if config.h says that we can. */
-+# undef REL_ALLOC
-+
-+# if defined STDC_HEADERS || defined _LIBC
-+# include <stdlib.h>
-+# else
-+char *malloc ();
-+char *realloc ();
-+# endif
-+
-+/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
-+ If nothing else has been done, use the method below. */
-+# ifdef INHIBIT_STRING_HEADER
-+# if !(defined HAVE_BZERO && defined HAVE_BCOPY)
-+# if !defined bzero && !defined bcopy
-+# undef INHIBIT_STRING_HEADER
-+# endif
-+# endif
-+# endif
-+
-+/* This is the normal way of making sure we have a bcopy and a bzero.
-+ This is used in most programs--a few other programs avoid this
-+ by defining INHIBIT_STRING_HEADER. */
-+# ifndef INHIBIT_STRING_HEADER
-+# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC
-+# include <string.h>
-+# ifndef bzero
-+# ifndef _LIBC
-+# define bzero(s, n) (memset (s, '\0', n), (s))
-+# else
-+# define bzero(s, n) __bzero (s, n)
-+# endif
-+# endif
-+# else
-+# include <strings.h>
-+# ifndef memcmp
-+# define memcmp(s1, s2, n) bcmp (s1, s2, n)
-+# endif
-+# ifndef memcpy
-+# define memcpy(d, s, n) (bcopy (s, d, n), (d))
-+# endif
-+# endif
-+# endif
-+
-+/* Define the syntax stuff for \<, \>, etc. */
-+
-+/* This must be nonzero for the wordchar and notwordchar pattern
-+ commands in re_match_2. */
-+# ifndef Sword
-+# define Sword 1
-+# endif
-+
-+# ifdef SWITCH_ENUM_BUG
-+# define SWITCH_ENUM_CAST(x) ((int)(x))
-+# else
-+# define SWITCH_ENUM_CAST(x) (x)
-+# endif
-+
-+# endif /* not emacs */
-+
-+# if defined _LIBC || HAVE_LIMITS_H
-+# include <limits.h>
-+# endif
-+
-+# ifndef MB_LEN_MAX
-+# define MB_LEN_MAX 1
-+# endif
-+
-+/* Get the interface, including the syntax bits. */
-+# include "regex.h"
-+
-+/* isalpha etc. are used for the character classes. */
-+# include <ctype.h>
-+
-+/* Jim Meyering writes:
-+
-+ "... Some ctype macros are valid only for character codes that
-+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
-+ using /bin/cc or gcc but without giving an ansi option). So, all
-+ ctype uses should be through macros like ISPRINT... If
-+ STDC_HEADERS is defined, then autoconf has verified that the ctype
-+ macros don't need to be guarded with references to isascii. ...
-+ Defining isascii to 1 should let any compiler worth its salt
-+ eliminate the && through constant folding."
-+ Solaris defines some of these symbols so we must undefine them first. */
-+
-+# undef ISASCII
-+# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
-+# define ISASCII(c) 1
-+# else
-+# define ISASCII(c) isascii(c)
-+# endif
-+
-+# ifdef isblank
-+# define ISBLANK(c) (ISASCII (c) && isblank (c))
-+# else
-+# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
-+# endif
-+# ifdef isgraph
-+# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
-+# else
-+# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
-+# endif
-+
-+# undef ISPRINT
-+# define ISPRINT(c) (ISASCII (c) && isprint (c))
-+# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
-+# define ISALNUM(c) (ISASCII (c) && isalnum (c))
-+# define ISALPHA(c) (ISASCII (c) && isalpha (c))
-+# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
-+# define ISLOWER(c) (ISASCII (c) && islower (c))
-+# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
-+# define ISSPACE(c) (ISASCII (c) && isspace (c))
-+# define ISUPPER(c) (ISASCII (c) && isupper (c))
-+# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
-+
-+# ifdef _tolower
-+# define TOLOWER(c) _tolower(c)
-+# else
-+# define TOLOWER(c) tolower(c)
-+# endif
-+
-+# ifndef NULL
-+# define NULL (void *)0
-+# endif
-+
-+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
-+ since ours (we hope) works properly with all combinations of
-+ machines, compilers, `char' and `unsigned char' argument types.
-+ (Per Bothner suggested the basic approach.) */
-+# undef SIGN_EXTEND_CHAR
-+# if __STDC__
-+# define SIGN_EXTEND_CHAR(c) ((signed char) (c))
-+# else /* not __STDC__ */
-+/* As in Harbison and Steele. */
-+# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
-+# endif
-+
-+# ifndef emacs
-+/* How many characters in the character set. */
-+# define CHAR_SET_SIZE 256
-+
-+# ifdef SYNTAX_TABLE
-+
-+extern char *re_syntax_table;
-+
-+# else /* not SYNTAX_TABLE */
-+
-+static char re_syntax_table[CHAR_SET_SIZE];
-+
-+static void init_syntax_once (void);
-+
-+static void
-+init_syntax_once (void)
-+{
-+ register int c;
-+ static int done = 0;
-+
-+ if (done)
-+ return;
-+ bzero (re_syntax_table, sizeof re_syntax_table);
-+
-+ for (c = 0; c < CHAR_SET_SIZE; ++c)
-+ if (ISALNUM (c))
-+ re_syntax_table[c] = Sword;
-+
-+ re_syntax_table['_'] = Sword;
-+
-+ done = 1;
-+}
-+
-+# endif /* not SYNTAX_TABLE */
-+
-+# define SYNTAX(c) re_syntax_table[(unsigned char) (c)]
-+
-+# endif /* emacs */
-+
-+/* Integer type for pointers. */
-+# if !defined _LIBC && !defined HAVE_UINTPTR_T
-+typedef unsigned long int uintptr_t;
-+# endif
-+
-+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
-+ use `alloca' instead of `malloc'. This is because using malloc in
-+ re_search* or re_match* could cause memory leaks when C-g is used in
-+ Emacs; also, malloc is slower and causes storage fragmentation. On
-+ the other hand, malloc is more portable, and easier to debug.
-+
-+ Because we sometimes use alloca, some routines have to be macros,
-+ not functions -- `alloca'-allocated space disappears at the end of the
-+ function it is called in. */
-+
-+# ifdef REGEX_MALLOC
-+
-+# define REGEX_ALLOCATE malloc
-+# define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
-+# define REGEX_FREE free
-+
-+# else /* not REGEX_MALLOC */
-+
-+/* Emacs already defines alloca, sometimes. */
-+# ifndef alloca
-+
-+/* Make alloca work the best possible way. */
-+# ifdef __GNUC__
-+# define alloca __builtin_alloca
-+# else /* not __GNUC__ */
-+# if HAVE_ALLOCA_H
-+# include <alloca.h>
-+# endif /* HAVE_ALLOCA_H */
-+# endif /* not __GNUC__ */
-+
-+# endif /* not alloca */
-+
-+# define REGEX_ALLOCATE alloca
-+
-+/* Assumes a `char *destination' variable. */
-+# define REGEX_REALLOCATE(source, osize, nsize) \
-+ (destination = (char *) alloca (nsize), \
-+ memcpy (destination, source, osize))
-+
-+/* No need to do anything to free, after alloca. */
-+# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */
-+
-+# endif /* not REGEX_MALLOC */
-+
-+/* Define how to allocate the failure stack. */
-+
-+# if defined REL_ALLOC && defined REGEX_MALLOC
-+
-+# define REGEX_ALLOCATE_STACK(size) \
-+ r_alloc (&failure_stack_ptr, (size))
-+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
-+ r_re_alloc (&failure_stack_ptr, (nsize))
-+# define REGEX_FREE_STACK(ptr) \
-+ r_alloc_free (&failure_stack_ptr)
-+
-+# else /* not using relocating allocator */
-+
-+# ifdef REGEX_MALLOC
-+
-+# define REGEX_ALLOCATE_STACK malloc
-+# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
-+# define REGEX_FREE_STACK free
-+
-+# else /* not REGEX_MALLOC */
-+
-+# define REGEX_ALLOCATE_STACK alloca
-+
-+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
-+ REGEX_REALLOCATE (source, osize, nsize)
-+/* No need to explicitly free anything. */
-+# define REGEX_FREE_STACK(arg)
-+
-+# endif /* not REGEX_MALLOC */
-+# endif /* not using relocating allocator */
-+
-+
-+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
-+ `string1' or just past its end. This works if PTR is NULL, which is
-+ a good thing. */
-+# define FIRST_STRING_P(ptr) \
-+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
-+
-+/* (Re)Allocate N items of type T using malloc, or fail. */
-+# define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
-+# define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
-+# define RETALLOC_IF(addr, n, t) \
-+ if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
-+# define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
-+
-+# define BYTEWIDTH 8 /* In bits. */
-+
-+# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
-+
-+# undef MAX
-+# undef MIN
-+# define MAX(a, b) ((a) > (b) ? (a) : (b))
-+# define MIN(a, b) ((a) < (b) ? (a) : (b))
-+
-+typedef char boolean;
-+# define false 0
-+# define true 1
-+
-+static reg_errcode_t byte_regex_compile (const char *pattern, size_t size,
-+ reg_syntax_t syntax,
-+ struct re_pattern_buffer *bufp);
-+
-+static int byte_re_match_2_internal (struct re_pattern_buffer *bufp,
-+ const char *string1, int size1,
-+ const char *string2, int size2,
-+ int pos,
-+ struct re_registers *regs,
-+ int stop);
-+static int byte_re_search_2 (struct re_pattern_buffer *bufp,
-+ const char *string1, int size1,
-+ const char *string2, int size2,
-+ int startpos, int range,
-+ struct re_registers *regs, int stop);
-+static int byte_re_compile_fastmap (struct re_pattern_buffer *bufp);
-+
-+#ifdef MBS_SUPPORT
-+static reg_errcode_t wcs_regex_compile (const char *pattern, size_t size,
-+ reg_syntax_t syntax,
-+ struct re_pattern_buffer *bufp);
-+
-+
-+static int wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
-+ const char *cstring1, int csize1,
-+ const char *cstring2, int csize2,
-+ int pos,
-+ struct re_registers *regs,
-+ int stop,
-+ wchar_t *string1, int size1,
-+ wchar_t *string2, int size2,
-+ int *mbs_offset1, int *mbs_offset2);
-+static int wcs_re_search_2 (struct re_pattern_buffer *bufp,
-+ const char *string1, int size1,
-+ const char *string2, int size2,
-+ int startpos, int range,
-+ struct re_registers *regs, int stop);
-+static int wcs_re_compile_fastmap (struct re_pattern_buffer *bufp);
-+#endif
-+
-+/* These are the command codes that appear in compiled regular
-+ expressions. Some opcodes are followed by argument bytes. A
-+ command code can specify any interpretation whatsoever for its
-+ arguments. Zero bytes may appear in the compiled regular expression. */
-+
-+typedef enum
-+{
-+ no_op = 0,
-+
-+ /* Succeed right away--no more backtracking. */
-+ succeed,
-+
-+ /* Followed by one byte giving n, then by n literal bytes. */
-+ exactn,
-+
-+# ifdef MBS_SUPPORT
-+ /* Same as exactn, but contains binary data. */
-+ exactn_bin,
-+# endif
-+
-+ /* Matches any (more or less) character. */
-+ anychar,
-+
-+ /* Matches any one char belonging to specified set. First
-+ following byte is number of bitmap bytes. Then come bytes
-+ for a bitmap saying which chars are in. Bits in each byte
-+ are ordered low-bit-first. A character is in the set if its
-+ bit is 1. A character too large to have a bit in the map is
-+ automatically not in the set. */
-+ /* ifdef MBS_SUPPORT, following element is length of character
-+ classes, length of collating symbols, length of equivalence
-+ classes, length of character ranges, and length of characters.
-+ Next, character class element, collating symbols elements,
-+ equivalence class elements, range elements, and character
-+ elements follow.
-+ See regex_compile function. */
-+ charset,
-+
-+ /* Same parameters as charset, but match any character that is
-+ not one of those specified. */
-+ charset_not,
-+
-+ /* Start remembering the text that is matched, for storing in a
-+ register. Followed by one byte with the register number, in
-+ the range 0 to one less than the pattern buffer's re_nsub
-+ field. Then followed by one byte with the number of groups
-+ inner to this one. (This last has to be part of the
-+ start_memory only because we need it in the on_failure_jump
-+ of re_match_2.) */
-+ start_memory,
-+
-+ /* Stop remembering the text that is matched and store it in a
-+ memory register. Followed by one byte with the register
-+ number, in the range 0 to one less than `re_nsub' in the
-+ pattern buffer, and one byte with the number of inner groups,
-+ just like `start_memory'. (We need the number of inner
-+ groups here because we don't have any easy way of finding the
-+ corresponding start_memory when we're at a stop_memory.) */
-+ stop_memory,
-+
-+ /* Match a duplicate of something remembered. Followed by one
-+ byte containing the register number. */
-+ duplicate,
-+
-+ /* Fail unless at beginning of line. */
-+ begline,
-+
-+ /* Fail unless at end of line. */
-+ endline,
-+
-+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
-+ of string to be matched (if not). */
-+ begbuf,
-+
-+ /* Analogously, for end of buffer/string. */
-+ endbuf,
-+
-+ /* Followed by two byte relative address to which to jump. */
-+ jump,
-+
-+ /* Same as jump, but marks the end of an alternative. */
-+ jump_past_alt,
-+
-+ /* Followed by two-byte relative address of place to resume at
-+ in case of failure. */
-+ /* ifdef MBS_SUPPORT, the size of address is 1. */
-+ on_failure_jump,
-+
-+ /* Like on_failure_jump, but pushes a placeholder instead of the
-+ current string position when executed. */
-+ on_failure_keep_string_jump,
-+
-+ /* Throw away latest failure point and then jump to following
-+ two-byte relative address. */
-+ /* ifdef MBS_SUPPORT, the size of address is 1. */
-+ pop_failure_jump,
-+
-+ /* Change to pop_failure_jump if know won't have to backtrack to
-+ match; otherwise change to jump. This is used to jump
-+ back to the beginning of a repeat. If what follows this jump
-+ clearly won't match what the repeat does, such that we can be
-+ sure that there is no use backtracking out of repetitions
-+ already matched, then we change it to a pop_failure_jump.
-+ Followed by two-byte address. */
-+ /* ifdef MBS_SUPPORT, the size of address is 1. */
-+ maybe_pop_jump,
-+
-+ /* Jump to following two-byte address, and push a dummy failure
-+ point. This failure point will be thrown away if an attempt
-+ is made to use it for a failure. A `+' construct makes this
-+ before the first repeat. Also used as an intermediary kind
-+ of jump when compiling an alternative. */
-+ /* ifdef MBS_SUPPORT, the size of address is 1. */
-+ dummy_failure_jump,
-+
-+ /* Push a dummy failure point and continue. Used at the end of
-+ alternatives. */
-+ push_dummy_failure,
-+
-+ /* Followed by two-byte relative address and two-byte number n.
-+ After matching N times, jump to the address upon failure. */
-+ /* ifdef MBS_SUPPORT, the size of address is 1. */
-+ succeed_n,
-+
-+ /* Followed by two-byte relative address, and two-byte number n.
-+ Jump to the address N times, then fail. */
-+ /* ifdef MBS_SUPPORT, the size of address is 1. */
-+ jump_n,
-+
-+ /* Set the following two-byte relative address to the
-+ subsequent two-byte number. The address *includes* the two
-+ bytes of number. */
-+ /* ifdef MBS_SUPPORT, the size of address is 1. */
-+ set_number_at,
-+
-+ wordchar, /* Matches any word-constituent character. */
-+ notwordchar, /* Matches any char that is not a word-constituent. */
-+
-+ wordbeg, /* Succeeds if at word beginning. */
-+ wordend, /* Succeeds if at word end. */
-+
-+ wordbound, /* Succeeds if at a word boundary. */
-+ notwordbound /* Succeeds if not at a word boundary. */
-+
-+# ifdef emacs
-+ ,before_dot, /* Succeeds if before point. */
-+ at_dot, /* Succeeds if at point. */
-+ after_dot, /* Succeeds if after point. */
-+
-+ /* Matches any character whose syntax is specified. Followed by
-+ a byte which contains a syntax code, e.g., Sword. */
-+ syntaxspec,
-+
-+ /* Matches any character whose syntax is not that specified. */
-+ notsyntaxspec
-+# endif /* emacs */
-+} re_opcode_t;
-+#endif /* not INSIDE_RECURSION */
-+
-+
-+#ifdef BYTE
-+# define CHAR_T char
-+# define UCHAR_T unsigned char
-+# define COMPILED_BUFFER_VAR bufp->buffer
-+# define OFFSET_ADDRESS_SIZE 2
-+# define PREFIX(name) byte_##name
-+# define ARG_PREFIX(name) name
-+# define PUT_CHAR(c) putchar (c)
-+# include <locale/weight.h>
-+# define FINDIDX findidx
-+#else
-+# ifdef WCHAR
-+# define CHAR_T wchar_t
-+# define UCHAR_T wchar_t
-+# define COMPILED_BUFFER_VAR wc_buffer
-+# define OFFSET_ADDRESS_SIZE 1 /* the size which STORE_NUMBER macro use */
-+# define CHAR_CLASS_SIZE ((__alignof__(wctype_t)+sizeof(wctype_t))/sizeof(CHAR_T)+1)
-+# define PREFIX(name) wcs_##name
-+# define ARG_PREFIX(name) c##name
-+/* Should we use wide stream?? */
-+# define PUT_CHAR(c) printf ("%C", c);
-+# define TRUE 1
-+# define FALSE 0
-+# define findidx findidxwc
-+# include <locale/weightwc.h>
-+# undef findidx
-+# define FINDIDX findidxwc
-+# else
-+# ifdef MBS_SUPPORT
-+# define WCHAR
-+# define INSIDE_RECURSION
-+# include "xregex.c"
-+# undef INSIDE_RECURSION
-+# endif
-+# define BYTE
-+# define INSIDE_RECURSION
-+# include "xregex.c"
-+# undef INSIDE_RECURSION
-+# endif
-+#endif
-+
-+#ifdef INSIDE_RECURSION
-+/* Common operations on the compiled pattern. */
-+
-+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
-+/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */
-+
-+# ifdef WCHAR
-+# define STORE_NUMBER(destination, number) \
-+ do { \
-+ *(destination) = (UCHAR_T)(number); \
-+ } while (0)
-+# else /* BYTE */
-+# define STORE_NUMBER(destination, number) \
-+ do { \
-+ (destination)[0] = (number) & 0377; \
-+ (destination)[1] = (number) >> 8; \
-+ } while (0)
-+# endif /* WCHAR */
-+
-+/* Same as STORE_NUMBER, except increment DESTINATION to
-+ the byte after where the number is stored. Therefore, DESTINATION
-+ must be an lvalue. */
-+/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */
-+
-+# define STORE_NUMBER_AND_INCR(destination, number) \
-+ do { \
-+ STORE_NUMBER (destination, number); \
-+ (destination) += OFFSET_ADDRESS_SIZE; \
-+ } while (0)
-+
-+/* Put into DESTINATION a number stored in two contiguous bytes starting
-+ at SOURCE. */
-+/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */
-+
-+# ifdef WCHAR
-+# define EXTRACT_NUMBER(destination, source) \
-+ do { \
-+ (destination) = *(source); \
-+ } while (0)
-+# else /* BYTE */
-+# define EXTRACT_NUMBER(destination, source) \
-+ do { \
-+ (destination) = *(source) & 0377; \
-+ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
-+ } while (0)
-+# endif
-+
-+# ifdef DEBUG
-+static void PREFIX(extract_number) (int *dest, UCHAR_T *source);
-+static void
-+PREFIX(extract_number) (int *dest, UCHAR_T *source)
-+{
-+# ifdef WCHAR
-+ *dest = *source;
-+# else /* BYTE */
-+ int temp = SIGN_EXTEND_CHAR (*(source + 1));
-+ *dest = *source & 0377;
-+ *dest += temp << 8;
-+# endif
-+}
-+
-+# ifndef EXTRACT_MACROS /* To debug the macros. */
-+# undef EXTRACT_NUMBER
-+# define EXTRACT_NUMBER(dest, src) PREFIX(extract_number) (&dest, src)
-+# endif /* not EXTRACT_MACROS */
-+
-+# endif /* DEBUG */
-+
-+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
-+ SOURCE must be an lvalue. */
-+
-+# define EXTRACT_NUMBER_AND_INCR(destination, source) \
-+ do { \
-+ EXTRACT_NUMBER (destination, source); \
-+ (source) += OFFSET_ADDRESS_SIZE; \
-+ } while (0)
-+
-+# ifdef DEBUG
-+static void PREFIX(extract_number_and_incr) (int *destination,
-+ UCHAR_T **source);
-+static void
-+PREFIX(extract_number_and_incr) (int *destination, UCHAR_T **source)
-+{
-+ PREFIX(extract_number) (destination, *source);
-+ *source += OFFSET_ADDRESS_SIZE;
-+}
-+
-+# ifndef EXTRACT_MACROS
-+# undef EXTRACT_NUMBER_AND_INCR
-+# define EXTRACT_NUMBER_AND_INCR(dest, src) \
-+ PREFIX(extract_number_and_incr) (&dest, &src)
-+# endif /* not EXTRACT_MACROS */
-+
-+# endif /* DEBUG */
-+
-+
-+
-+/* If DEBUG is defined, Regex prints many voluminous messages about what
-+ it is doing (if the variable `debug' is nonzero). If linked with the
-+ main program in `iregex.c', you can enter patterns and strings
-+ interactively. And if linked with the main program in `main.c' and
-+ the other test files, you can run the already-written tests. */
-+
-+# ifdef DEBUG
-+
-+# ifndef DEFINED_ONCE
-+
-+/* We use standard I/O for debugging. */
-+# include <stdio.h>
-+
-+/* It is useful to test things that ``must'' be true when debugging. */
-+# include <assert.h>
-+
-+static int debug;
-+
-+# define DEBUG_STATEMENT(e) e
-+# define DEBUG_PRINT1(x) if (debug) printf (x)
-+# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
-+# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
-+# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
-+# endif /* not DEFINED_ONCE */
-+
-+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
-+ if (debug) PREFIX(print_partial_compiled_pattern) (s, e)
-+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
-+ if (debug) PREFIX(print_double_string) (w, s1, sz1, s2, sz2)
-+
-+
-+/* Print the fastmap in human-readable form. */
-+
-+# ifndef DEFINED_ONCE
-+void
-+print_fastmap (char *fastmap)
-+{
-+ unsigned was_a_range = 0;
-+ unsigned i = 0;
-+
-+ while (i < (1 << BYTEWIDTH))
-+ {
-+ if (fastmap[i++])
-+ {
-+ was_a_range = 0;
-+ putchar (i - 1);
-+ while (i < (1 << BYTEWIDTH) && fastmap[i])
-+ {
-+ was_a_range = 1;
-+ i++;
-+ }
-+ if (was_a_range)
-+ {
-+ printf ("-");
-+ putchar (i - 1);
-+ }
-+ }
-+ }
-+ putchar ('\n');
-+}
-+# endif /* not DEFINED_ONCE */
-+
-+
-+/* Print a compiled pattern string in human-readable form, starting at
-+ the START pointer into it and ending just before the pointer END. */
-+
-+void
-+PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end)
-+{
-+ int mcnt, mcnt2;
-+ UCHAR_T *p1;
-+ UCHAR_T *p = start;
-+ UCHAR_T *pend = end;
-+
-+ if (start == NULL)
-+ {
-+ printf ("(null)\n");
-+ return;
-+ }
-+
-+ /* Loop over pattern commands. */
-+ while (p < pend)
-+ {
-+# ifdef _LIBC
-+ printf ("%td:\t", p - start);
-+# else
-+ printf ("%ld:\t", (long int) (p - start));
-+# endif
-+
-+ switch ((re_opcode_t) *p++)
-+ {
-+ case no_op:
-+ printf ("/no_op");
-+ break;
-+
-+ case exactn:
-+ mcnt = *p++;
-+ printf ("/exactn/%d", mcnt);
-+ do
-+ {
-+ putchar ('/');
-+ PUT_CHAR (*p++);
-+ }
-+ while (--mcnt);
-+ break;
-+
-+# ifdef MBS_SUPPORT
-+ case exactn_bin:
-+ mcnt = *p++;
-+ printf ("/exactn_bin/%d", mcnt);
-+ do
-+ {
-+ printf("/%lx", (long int) *p++);
-+ }
-+ while (--mcnt);
-+ break;
-+# endif /* MBS_SUPPORT */
-+
-+ case start_memory:
-+ mcnt = *p++;
-+ printf ("/start_memory/%d/%ld", mcnt, (long int) *p++);
-+ break;
-+
-+ case stop_memory:
-+ mcnt = *p++;
-+ printf ("/stop_memory/%d/%ld", mcnt, (long int) *p++);
-+ break;
-+
-+ case duplicate:
-+ printf ("/duplicate/%ld", (long int) *p++);
-+ break;
-+
-+ case anychar:
-+ printf ("/anychar");
-+ break;
-+
-+ case charset:
-+ case charset_not:
-+ {
-+# ifdef WCHAR
-+ int i, length;
-+ wchar_t *workp = p;
-+ printf ("/charset [%s",
-+ (re_opcode_t) *(workp - 1) == charset_not ? "^" : "");
-+ p += 5;
-+ length = *workp++; /* the length of char_classes */
-+ for (i=0 ; i<length ; i++)
-+ printf("[:%lx:]", (long int) *p++);
-+ length = *workp++; /* the length of collating_symbol */
-+ for (i=0 ; i<length ;)
-+ {
-+ printf("[.");
-+ while(*p != 0)
-+ PUT_CHAR((i++,*p++));
-+ i++,p++;
-+ printf(".]");
-+ }
-+ length = *workp++; /* the length of equivalence_class */
-+ for (i=0 ; i<length ;)
-+ {
-+ printf("[=");
-+ while(*p != 0)
-+ PUT_CHAR((i++,*p++));
-+ i++,p++;
-+ printf("=]");
-+ }
-+ length = *workp++; /* the length of char_range */
-+ for (i=0 ; i<length ; i++)
-+ {
-+ wchar_t range_start = *p++;
-+ wchar_t range_end = *p++;
-+ printf("%C-%C", range_start, range_end);
-+ }
-+ length = *workp++; /* the length of char */
-+ for (i=0 ; i<length ; i++)
-+ printf("%C", *p++);
-+ putchar (']');
-+# else
-+ register int c, last = -100;
-+ register int in_range = 0;
-+
-+ printf ("/charset [%s",
-+ (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
-+
-+ assert (p + *p < pend);
-+
-+ for (c = 0; c < 256; c++)
-+ if (c / 8 < *p
-+ && (p[1 + (c/8)] & (1 << (c % 8))))
-+ {
-+ /* Are we starting a range? */
-+ if (last + 1 == c && ! in_range)
-+ {
-+ putchar ('-');
-+ in_range = 1;
-+ }
-+ /* Have we broken a range? */
-+ else if (last + 1 != c && in_range)
-+ {
-+ putchar (last);
-+ in_range = 0;
-+ }
-+
-+ if (! in_range)
-+ putchar (c);
-+
-+ last = c;
-+ }
-+
-+ if (in_range)
-+ putchar (last);
-+
-+ putchar (']');
-+
-+ p += 1 + *p;
-+# endif /* WCHAR */
-+ }
-+ break;
-+
-+ case begline:
-+ printf ("/begline");
-+ break;
-+
-+ case endline:
-+ printf ("/endline");
-+ break;
-+
-+ case on_failure_jump:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+# ifdef _LIBC
-+ printf ("/on_failure_jump to %td", p + mcnt - start);
-+# else
-+ printf ("/on_failure_jump to %ld", (long int) (p + mcnt - start));
-+# endif
-+ break;
-+
-+ case on_failure_keep_string_jump:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+# ifdef _LIBC
-+ printf ("/on_failure_keep_string_jump to %td", p + mcnt - start);
-+# else
-+ printf ("/on_failure_keep_string_jump to %ld",
-+ (long int) (p + mcnt - start));
-+# endif
-+ break;
-+
-+ case dummy_failure_jump:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+# ifdef _LIBC
-+ printf ("/dummy_failure_jump to %td", p + mcnt - start);
-+# else
-+ printf ("/dummy_failure_jump to %ld", (long int) (p + mcnt - start));
-+# endif
-+ break;
-+
-+ case push_dummy_failure:
-+ printf ("/push_dummy_failure");
-+ break;
-+
-+ case maybe_pop_jump:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+# ifdef _LIBC
-+ printf ("/maybe_pop_jump to %td", p + mcnt - start);
-+# else
-+ printf ("/maybe_pop_jump to %ld", (long int) (p + mcnt - start));
-+# endif
-+ break;
-+
-+ case pop_failure_jump:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+# ifdef _LIBC
-+ printf ("/pop_failure_jump to %td", p + mcnt - start);
-+# else
-+ printf ("/pop_failure_jump to %ld", (long int) (p + mcnt - start));
-+# endif
-+ break;
-+
-+ case jump_past_alt:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+# ifdef _LIBC
-+ printf ("/jump_past_alt to %td", p + mcnt - start);
-+# else
-+ printf ("/jump_past_alt to %ld", (long int) (p + mcnt - start));
-+# endif
-+ break;
-+
-+ case jump:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+# ifdef _LIBC
-+ printf ("/jump to %td", p + mcnt - start);
-+# else
-+ printf ("/jump to %ld", (long int) (p + mcnt - start));
-+# endif
-+ break;
-+
-+ case succeed_n:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+ p1 = p + mcnt;
-+ PREFIX(extract_number_and_incr) (&mcnt2, &p);
-+# ifdef _LIBC
-+ printf ("/succeed_n to %td, %d times", p1 - start, mcnt2);
-+# else
-+ printf ("/succeed_n to %ld, %d times",
-+ (long int) (p1 - start), mcnt2);
-+# endif
-+ break;
-+
-+ case jump_n:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+ p1 = p + mcnt;
-+ PREFIX(extract_number_and_incr) (&mcnt2, &p);
-+ printf ("/jump_n to %d, %d times", p1 - start, mcnt2);
-+ break;
-+
-+ case set_number_at:
-+ PREFIX(extract_number_and_incr) (&mcnt, &p);
-+ p1 = p + mcnt;
-+ PREFIX(extract_number_and_incr) (&mcnt2, &p);
-+# ifdef _LIBC
-+ printf ("/set_number_at location %td to %d", p1 - start, mcnt2);
-+# else
-+ printf ("/set_number_at location %ld to %d",
-+ (long int) (p1 - start), mcnt2);
-+# endif
-+ break;
-+
-+ case wordbound:
-+ printf ("/wordbound");
-+ break;
-+
-+ case notwordbound:
-+ printf ("/notwordbound");
-+ break;
-+
-+ case wordbeg:
-+ printf ("/wordbeg");
-+ break;
-+
-+ case wordend:
-+ printf ("/wordend");
-+ break;
-+
-+# ifdef emacs
-+ case before_dot:
-+ printf ("/before_dot");
-+ break;
-+
-+ case at_dot:
-+ printf ("/at_dot");
-+ break;
-+
-+ case after_dot:
-+ printf ("/after_dot");
-+ break;
-+
-+ case syntaxspec:
-+ printf ("/syntaxspec");
-+ mcnt = *p++;
-+ printf ("/%d", mcnt);
-+ break;
-+
-+ case notsyntaxspec:
-+ printf ("/notsyntaxspec");
-+ mcnt = *p++;
-+ printf ("/%d", mcnt);
-+ break;
-+# endif /* emacs */
-+
-+ case wordchar:
-+ printf ("/wordchar");
-+ break;
-+
-+ case notwordchar:
-+ printf ("/notwordchar");
-+ break;
-+
-+ case begbuf:
-+ printf ("/begbuf");
-+ break;
-+
-+ case endbuf:
-+ printf ("/endbuf");
-+ break;
-+
-+ default:
-+ printf ("?%ld", (long int) *(p-1));
-+ }
-+
-+ putchar ('\n');
-+ }
-+
-+# ifdef _LIBC
-+ printf ("%td:\tend of pattern.\n", p - start);
-+# else
-+ printf ("%ld:\tend of pattern.\n", (long int) (p - start));
-+# endif
-+}
-+
-+
-+void
-+PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp)
-+{
-+ UCHAR_T *buffer = (UCHAR_T*) bufp->buffer;
-+
-+ PREFIX(print_partial_compiled_pattern) (buffer, buffer
-+ + bufp->used / sizeof(UCHAR_T));
-+ printf ("%ld bytes used/%ld bytes allocated.\n",
-+ bufp->used, bufp->allocated);
-+
-+ if (bufp->fastmap_accurate && bufp->fastmap)
-+ {
-+ printf ("fastmap: ");
-+ print_fastmap (bufp->fastmap);
-+ }
-+
-+# ifdef _LIBC
-+ printf ("re_nsub: %Zd\t", bufp->re_nsub);
-+# else
-+ printf ("re_nsub: %ld\t", (long int) bufp->re_nsub);
-+# endif
-+ printf ("regs_alloc: %d\t", bufp->regs_allocated);
-+ printf ("can_be_null: %d\t", bufp->can_be_null);
-+ printf ("newline_anchor: %d\n", bufp->newline_anchor);
-+ printf ("no_sub: %d\t", bufp->no_sub);
-+ printf ("not_bol: %d\t", bufp->not_bol);
-+ printf ("not_eol: %d\t", bufp->not_eol);
-+ printf ("syntax: %lx\n", bufp->syntax);
-+ /* Perhaps we should print the translate table? */
-+}
-+
-+
-+void
-+PREFIX(print_double_string) (const CHAR_T *where, const CHAR_T *string1,
-+ int size1, const CHAR_T *string2, int size2)
-+{
-+ int this_char;
-+
-+ if (where == NULL)
-+ printf ("(null)");
-+ else
-+ {
-+ int cnt;
-+
-+ if (FIRST_STRING_P (where))
-+ {
-+ for (this_char = where - string1; this_char < size1; this_char++)
-+ PUT_CHAR (string1[this_char]);
-+
-+ where = string2;
-+ }
-+
-+ cnt = 0;
-+ for (this_char = where - string2; this_char < size2; this_char++)
-+ {
-+ PUT_CHAR (string2[this_char]);
-+ if (++cnt > 100)
-+ {
-+ fputs ("...", stdout);
-+ break;
-+ }
-+ }
-+ }
-+}
-+
-+# ifndef DEFINED_ONCE
-+void
-+printchar (int c)
-+{
-+ putc (c, stderr);
-+}
-+# endif
-+
-+# else /* not DEBUG */
-+
-+# ifndef DEFINED_ONCE
-+# undef assert
-+# define assert(e)
-+
-+# define DEBUG_STATEMENT(e)
-+# define DEBUG_PRINT1(x)
-+# define DEBUG_PRINT2(x1, x2)
-+# define DEBUG_PRINT3(x1, x2, x3)
-+# define DEBUG_PRINT4(x1, x2, x3, x4)
-+# endif /* not DEFINED_ONCE */
-+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
-+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
-+
-+# endif /* not DEBUG */
-+
-+
-+
-+# ifdef WCHAR
-+/* This convert a multibyte string to a wide character string.
-+ And write their correspondances to offset_buffer(see below)
-+ and write whether each wchar_t is binary data to is_binary.
-+ This assume invalid multibyte sequences as binary data.
-+ We assume offset_buffer and is_binary is already allocated
-+ enough space. */
-+
-+static size_t convert_mbs_to_wcs (CHAR_T *dest, const unsigned char* src,
-+ size_t len, int *offset_buffer,
-+ char *is_binary);
-+static size_t
-+convert_mbs_to_wcs (CHAR_T *dest, const unsigned char*src, size_t len,
-+ int *offset_buffer, char *is_binary)
-+ /* It hold correspondances between src(char string) and
-+ dest(wchar_t string) for optimization.
-+ e.g. src = "xxxyzz"
-+ dest = {'X', 'Y', 'Z'}
-+ (each "xxx", "y" and "zz" represent one multibyte character
-+ corresponding to 'X', 'Y' and 'Z'.)
-+ offset_buffer = {0, 0+3("xxx"), 0+3+1("y"), 0+3+1+2("zz")}
-+ = {0, 3, 4, 6}
-+ */
-+{
-+ wchar_t *pdest = dest;
-+ const unsigned char *psrc = src;
-+ size_t wc_count = 0;
-+
-+ mbstate_t mbs;
-+ int i, consumed;
-+ size_t mb_remain = len;
-+ size_t mb_count = 0;
-+
-+ /* Initialize the conversion state. */
-+ memset (&mbs, 0, sizeof (mbstate_t));
-+
-+ offset_buffer[0] = 0;
-+ for( ; mb_remain > 0 ; ++wc_count, ++pdest, mb_remain -= consumed,
-+ psrc += consumed)
-+ {
-+#ifdef _LIBC
-+ consumed = __mbrtowc (pdest, psrc, mb_remain, &mbs);
-+#else
-+ consumed = mbrtowc (pdest, psrc, mb_remain, &mbs);
-+#endif
-+
-+ if (consumed <= 0)
-+ /* failed to convert. maybe src contains binary data.
-+ So we consume 1 byte manualy. */
-+ {
-+ *pdest = *psrc;
-+ consumed = 1;
-+ is_binary[wc_count] = TRUE;
-+ }
-+ else
-+ is_binary[wc_count] = FALSE;
-+ /* In sjis encoding, we use yen sign as escape character in
-+ place of reverse solidus. So we convert 0x5c(yen sign in
-+ sjis) to not 0xa5(yen sign in UCS2) but 0x5c(reverse
-+ solidus in UCS2). */
-+ if (consumed == 1 && (int) *psrc == 0x5c && (int) *pdest == 0xa5)
-+ *pdest = (wchar_t) *psrc;
-+
-+ offset_buffer[wc_count + 1] = mb_count += consumed;
-+ }
-+
-+ /* Fill remain of the buffer with sentinel. */
-+ for (i = wc_count + 1 ; i <= len ; i++)
-+ offset_buffer[i] = mb_count + 1;
-+
-+ return wc_count;
-+}
-+
-+# endif /* WCHAR */
-+
-+#else /* not INSIDE_RECURSION */
-+
-+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
-+ also be assigned to arbitrarily: each pattern buffer stores its own
-+ syntax, so it can be changed between regex compilations. */
-+/* This has no initializer because initialized variables in Emacs
-+ become read-only after dumping. */
-+reg_syntax_t re_syntax_options;
-+
-+
-+/* Specify the precise syntax of regexps for compilation. This provides
-+ for compatibility for various utilities which historically have
-+ different, incompatible syntaxes.
-+
-+ The argument SYNTAX is a bit mask comprised of the various bits
-+ defined in regex.h. We return the old syntax. */
-+
-+reg_syntax_t
-+re_set_syntax (reg_syntax_t syntax)
-+{
-+ reg_syntax_t ret = re_syntax_options;
-+
-+ re_syntax_options = syntax;
-+# ifdef DEBUG
-+ if (syntax & RE_DEBUG)
-+ debug = 1;
-+ else if (debug) /* was on but now is not */
-+ debug = 0;
-+# endif /* DEBUG */
-+ return ret;
-+}
-+# ifdef _LIBC
-+weak_alias (__re_set_syntax, re_set_syntax)
-+# endif
-+
-+/* 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[] =
-+ {
-+ gettext_noop ("Success"), /* REG_NOERROR */
-+ gettext_noop ("No match"), /* REG_NOMATCH */
-+ gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
-+ gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
-+ gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
-+ gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
-+ gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
-+ gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */
-+ gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
-+ gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
-+ gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
-+ gettext_noop ("Invalid range end"), /* REG_ERANGE */
-+ gettext_noop ("Memory exhausted"), /* REG_ESPACE */
-+ gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
-+ gettext_noop ("Premature end of regular expression"), /* REG_EEND */
-+ gettext_noop ("Regular expression too big"), /* REG_ESIZE */
-+ gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
-+ };
-+
-+#endif /* INSIDE_RECURSION */
-+
-+#ifndef DEFINED_ONCE
-+/* Avoiding alloca during matching, to placate r_alloc. */
-+
-+/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
-+ searching and matching functions should not call alloca. On some
-+ systems, alloca is implemented in terms of malloc, and if we're
-+ using the relocating allocator routines, then malloc could cause a
-+ relocation, which might (if the strings being searched are in the
-+ ralloc heap) shift the data out from underneath the regexp
-+ routines.
-+
-+ Here's another reason to avoid allocation: Emacs
-+ processes input from X in a signal handler; processing X input may
-+ call malloc; if input arrives while a matching routine is calling
-+ malloc, then we're scrod. But Emacs can't just block input while
-+ calling matching routines; then we don't notice interrupts when
-+ they come in. So, Emacs blocks input around all regexp calls
-+ except the matching calls, which it leaves unprotected, in the
-+ faith that they will not malloc. */
-+
-+/* Normally, this is fine. */
-+# define MATCH_MAY_ALLOCATE
-+
-+/* When using GNU C, we are not REALLY using the C alloca, no matter
-+ what config.h may say. So don't take precautions for it. */
-+# ifdef __GNUC__
-+# undef C_ALLOCA
-+# endif
-+
-+/* The match routines may not allocate if (1) they would do it with malloc
-+ and (2) it's not safe for them to use malloc.
-+ Note that if REL_ALLOC is defined, matching would not use malloc for the
-+ failure stack, but we would still use it for the register vectors;
-+ so REL_ALLOC should not affect this. */
-+# if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs
-+# undef MATCH_MAY_ALLOCATE
-+# endif
-+#endif /* not DEFINED_ONCE */
-+
-+#ifdef INSIDE_RECURSION
-+/* Failure stack declarations and macros; both re_compile_fastmap and
-+ re_match_2 use a failure stack. These have to be macros because of
-+ REGEX_ALLOCATE_STACK. */
-+
-+
-+/* Number of failure points for which to initially allocate space
-+ when matching. If this number is exceeded, we allocate more
-+ space, so it is not a hard limit. */
-+# ifndef INIT_FAILURE_ALLOC
-+# define INIT_FAILURE_ALLOC 5
-+# endif
-+
-+/* Roughly the maximum number of failure points on the stack. Would be
-+ exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
-+ This is a variable only so users of regex can assign to it; we never
-+ change it ourselves. */
-+
-+
-+# ifndef DEFINED_ONCE
-+
-+# ifdef INT_IS_16BIT
-+# define RE_M_F_TYPE long int
-+# else
-+# define RE_M_F_TYPE int
-+# endif /* INT_IS_16BIT */
-+
-+# ifdef MATCH_MAY_ALLOCATE
-+/* 4400 was enough to cause a crash on Alpha OSF/1,
-+ whose default stack limit is 2mb. */
-+# define RE_M_F_DEFAULT 4000
-+# else
-+# define RE_M_F_DEFAULT 2000
-+# endif /* MATCH_MAY_ALLOCATE */
-+
-+# 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.")
-+RE_M_F_TYPE re_max_failures = RE_M_F_DEFAULT;
-+# else
-+RE_M_F_TYPE re_max_failures attribute_hidden = RE_M_F_DEFAULT;
-+# endif /* SHLIB_COMPAT */
-+
-+# undef RE_M_F_TYPE
-+# undef RE_M_F_DEFAULT
-+
-+# endif /* DEFINED_ONCE */
-+
-+# ifdef INT_IS_16BIT
-+
-+union PREFIX(fail_stack_elt)
-+{
-+ UCHAR_T *pointer;
-+ long int integer;
-+};
-+
-+typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
-+
-+typedef struct
-+{
-+ PREFIX(fail_stack_elt_t) *stack;
-+ unsigned long int size;
-+ unsigned long int avail; /* Offset of next open position. */
-+} PREFIX(fail_stack_type);
-+
-+# else /* not INT_IS_16BIT */
-+
-+union PREFIX(fail_stack_elt)
-+{
-+ UCHAR_T *pointer;
-+ int integer;
-+};
-+
-+typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
-+
-+typedef struct
-+{
-+ PREFIX(fail_stack_elt_t) *stack;
-+ unsigned size;
-+ unsigned avail; /* Offset of next open position. */
-+} PREFIX(fail_stack_type);
-+
-+# endif /* INT_IS_16BIT */
-+
-+# ifndef DEFINED_ONCE
-+# define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
-+# define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
-+# define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
-+# endif
-+
-+
-+/* Define macros to initialize and free the failure stack.
-+ Do `return -2' if the alloc fails. */
-+
-+# ifdef MATCH_MAY_ALLOCATE
-+# define INIT_FAIL_STACK() \
-+ do { \
-+ fail_stack.stack = (PREFIX(fail_stack_elt_t) *) \
-+ REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (PREFIX(fail_stack_elt_t))); \
-+ \
-+ if (fail_stack.stack == NULL) \
-+ return -2; \
-+ \
-+ fail_stack.size = INIT_FAILURE_ALLOC; \
-+ fail_stack.avail = 0; \
-+ } while (0)
-+
-+# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack)
-+# else
-+# define INIT_FAIL_STACK() \
-+ do { \
-+ fail_stack.avail = 0; \
-+ } while (0)
-+
-+# define RESET_FAIL_STACK()
-+# endif
-+
-+
-+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
-+
-+ Return 1 if succeeds, and 0 if either ran out of memory
-+ allocating space for it or it was already too large.
-+
-+ REGEX_REALLOCATE_STACK requires `destination' be declared. */
-+
-+# define DOUBLE_FAIL_STACK(fail_stack) \
-+ ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \
-+ ? 0 \
-+ : ((fail_stack).stack = (PREFIX(fail_stack_elt_t) *) \
-+ REGEX_REALLOCATE_STACK ((fail_stack).stack, \
-+ (fail_stack).size * sizeof (PREFIX(fail_stack_elt_t)), \
-+ ((fail_stack).size << 1) * sizeof (PREFIX(fail_stack_elt_t))),\
-+ \
-+ (fail_stack).stack == NULL \
-+ ? 0 \
-+ : ((fail_stack).size <<= 1, \
-+ 1)))
-+
-+
-+/* Push pointer POINTER on FAIL_STACK.
-+ Return 1 if was able to do so and 0 if ran out of memory allocating
-+ space to do so. */
-+# define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \
-+ ((FAIL_STACK_FULL () \
-+ && !DOUBLE_FAIL_STACK (FAIL_STACK)) \
-+ ? 0 \
-+ : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \
-+ 1))
-+
-+/* Push a pointer value onto the failure stack.
-+ Assumes the variable `fail_stack'. Probably should only
-+ be called from within `PUSH_FAILURE_POINT'. */
-+# define PUSH_FAILURE_POINTER(item) \
-+ fail_stack.stack[fail_stack.avail++].pointer = (UCHAR_T *) (item)
-+
-+/* This pushes an integer-valued item onto the failure stack.
-+ Assumes the variable `fail_stack'. Probably should only
-+ be called from within `PUSH_FAILURE_POINT'. */
-+# define PUSH_FAILURE_INT(item) \
-+ fail_stack.stack[fail_stack.avail++].integer = (item)
-+
-+/* Push a fail_stack_elt_t value onto the failure stack.
-+ Assumes the variable `fail_stack'. Probably should only
-+ be called from within `PUSH_FAILURE_POINT'. */
-+# define PUSH_FAILURE_ELT(item) \
-+ fail_stack.stack[fail_stack.avail++] = (item)
-+
-+/* These three POP... operations complement the three PUSH... operations.
-+ All assume that `fail_stack' is nonempty. */
-+# define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
-+# define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
-+# define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
-+
-+/* Used to omit pushing failure point id's when we're not debugging. */
-+# ifdef DEBUG
-+# define DEBUG_PUSH PUSH_FAILURE_INT
-+# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
-+# else
-+# define DEBUG_PUSH(item)
-+# define DEBUG_POP(item_addr)
-+# endif
-+
-+
-+/* Push the information about the state we will need
-+ if we ever fail back to it.
-+
-+ Requires variables fail_stack, regstart, regend, reg_info, and
-+ num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination'
-+ be declared.
-+
-+ Does `return FAILURE_CODE' if runs out of memory. */
-+
-+# define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
-+ do { \
-+ char *destination; \
-+ /* Must be int, so when we don't save any registers, the arithmetic \
-+ of 0 + -1 isn't done as unsigned. */ \
-+ /* Can't be int, since there is not a shred of a guarantee that int \
-+ is wide enough to hold a value of something to which pointer can \
-+ be assigned */ \
-+ active_reg_t this_reg; \
-+ \
-+ DEBUG_STATEMENT (failure_id++); \
-+ DEBUG_STATEMENT (nfailure_points_pushed++); \
-+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
-+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
-+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
-+ \
-+ DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \
-+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
-+ \
-+ /* Ensure we have enough space allocated for what we will push. */ \
-+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
-+ { \
-+ if (!DOUBLE_FAIL_STACK (fail_stack)) \
-+ return failure_code; \
-+ \
-+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
-+ (fail_stack).size); \
-+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
-+ } \
-+ \
-+ /* Push the info, starting with the registers. */ \
-+ DEBUG_PRINT1 ("\n"); \
-+ \
-+ if (1) \
-+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
-+ this_reg++) \
-+ { \
-+ DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \
-+ DEBUG_STATEMENT (num_regs_pushed++); \
-+ \
-+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
-+ PUSH_FAILURE_POINTER (regstart[this_reg]); \
-+ \
-+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
-+ PUSH_FAILURE_POINTER (regend[this_reg]); \
-+ \
-+ DEBUG_PRINT2 (" info: %p\n ", \
-+ reg_info[this_reg].word.pointer); \
-+ DEBUG_PRINT2 (" match_null=%d", \
-+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
-+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
-+ DEBUG_PRINT2 (" matched_something=%d", \
-+ MATCHED_SOMETHING (reg_info[this_reg])); \
-+ DEBUG_PRINT2 (" ever_matched=%d", \
-+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
-+ DEBUG_PRINT1 ("\n"); \
-+ PUSH_FAILURE_ELT (reg_info[this_reg].word); \
-+ } \
-+ \
-+ DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\
-+ PUSH_FAILURE_INT (lowest_active_reg); \
-+ \
-+ DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\
-+ PUSH_FAILURE_INT (highest_active_reg); \
-+ \
-+ DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \
-+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
-+ PUSH_FAILURE_POINTER (pattern_place); \
-+ \
-+ DEBUG_PRINT2 (" Pushing string %p: `", string_place); \
-+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
-+ size2); \
-+ DEBUG_PRINT1 ("'\n"); \
-+ PUSH_FAILURE_POINTER (string_place); \
-+ \
-+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
-+ DEBUG_PUSH (failure_id); \
-+ } while (0)
-+
-+# ifndef DEFINED_ONCE
-+/* This is the number of items that are pushed and popped on the stack
-+ for each register. */
-+# define NUM_REG_ITEMS 3
-+
-+/* Individual items aside from the registers. */
-+# ifdef DEBUG
-+# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
-+# else
-+# define NUM_NONREG_ITEMS 4
-+# endif
-+
-+/* We push at most this many items on the stack. */
-+/* We used to use (num_regs - 1), which is the number of registers
-+ this regexp will save; but that was changed to 5
-+ to avoid stack overflow for a regexp with lots of parens. */
-+# define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
-+
-+/* We actually push this many items. */
-+# define NUM_FAILURE_ITEMS \
-+ (((0 \
-+ ? 0 : highest_active_reg - lowest_active_reg + 1) \
-+ * NUM_REG_ITEMS) \
-+ + NUM_NONREG_ITEMS)
-+
-+/* How many items can still be added to the stack without overflowing it. */
-+# define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
-+# endif /* not DEFINED_ONCE */
-+
-+
-+/* Pops what PUSH_FAIL_STACK pushes.
-+
-+ We restore into the parameters, all of which should be lvalues:
-+ STR -- the saved data position.
-+ PAT -- the saved pattern position.
-+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
-+ REGSTART, REGEND -- arrays of string positions.
-+ REG_INFO -- array of information about each subexpression.
-+
-+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
-+ `pend', `string1', `size1', `string2', and `size2'. */
-+# define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
-+{ \
-+ DEBUG_STATEMENT (unsigned failure_id;) \
-+ active_reg_t this_reg; \
-+ const UCHAR_T *string_temp; \
-+ \
-+ assert (!FAIL_STACK_EMPTY ()); \
-+ \
-+ /* Remove failure points and point to how many regs pushed. */ \
-+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
-+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
-+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
-+ \
-+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
-+ \
-+ DEBUG_POP (&failure_id); \
-+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
-+ \
-+ /* If the saved string location is NULL, it came from an \
-+ on_failure_keep_string_jump opcode, and we want to throw away the \
-+ saved NULL, thus retaining our current position in the string. */ \
-+ string_temp = POP_FAILURE_POINTER (); \
-+ if (string_temp != NULL) \
-+ str = (const CHAR_T *) string_temp; \
-+ \
-+ DEBUG_PRINT2 (" Popping string %p: `", str); \
-+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
-+ DEBUG_PRINT1 ("'\n"); \
-+ \
-+ pat = (UCHAR_T *) POP_FAILURE_POINTER (); \
-+ DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \
-+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
-+ \
-+ /* Restore register info. */ \
-+ high_reg = (active_reg_t) POP_FAILURE_INT (); \
-+ DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \
-+ \
-+ low_reg = (active_reg_t) POP_FAILURE_INT (); \
-+ DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \
-+ \
-+ if (1) \
-+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
-+ { \
-+ DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \
-+ \
-+ reg_info[this_reg].word = POP_FAILURE_ELT (); \
-+ DEBUG_PRINT2 (" info: %p\n", \
-+ reg_info[this_reg].word.pointer); \
-+ \
-+ regend[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER (); \
-+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
-+ \
-+ regstart[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER (); \
-+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
-+ } \
-+ else \
-+ { \
-+ for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
-+ { \
-+ reg_info[this_reg].word.integer = 0; \
-+ regend[this_reg] = 0; \
-+ regstart[this_reg] = 0; \
-+ } \
-+ highest_active_reg = high_reg; \
-+ } \
-+ \
-+ set_regs_matched_done = 0; \
-+ DEBUG_STATEMENT (nfailure_points_popped++); \
-+} /* POP_FAILURE_POINT */
-+
-+/* Structure for per-register (a.k.a. per-group) information.
-+ Other register information, such as the
-+ starting and ending positions (which are addresses), and the list of
-+ inner groups (which is a bits list) are maintained in separate
-+ variables.
-+
-+ We are making a (strictly speaking) nonportable assumption here: that
-+ the compiler will pack our bit fields into something that fits into
-+ the type of `word', i.e., is something that fits into one item on the
-+ failure stack. */
-+
-+
-+/* Declarations and macros for re_match_2. */
-+
-+typedef union
-+{
-+ PREFIX(fail_stack_elt_t) word;
-+ struct
-+ {
-+ /* This field is one if this group can match the empty string,
-+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
-+# define MATCH_NULL_UNSET_VALUE 3
-+ unsigned match_null_string_p : 2;
-+ unsigned is_active : 1;
-+ unsigned matched_something : 1;
-+ unsigned ever_matched_something : 1;
-+ } bits;
-+} PREFIX(register_info_type);
-+
-+# ifndef DEFINED_ONCE
-+# define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
-+# define IS_ACTIVE(R) ((R).bits.is_active)
-+# define MATCHED_SOMETHING(R) ((R).bits.matched_something)
-+# define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
-+
-+
-+/* Call this when have matched a real character; it sets `matched' flags
-+ for the subexpressions which we are currently inside. Also records
-+ that those subexprs have matched. */
-+# define SET_REGS_MATCHED() \
-+ do \
-+ { \
-+ if (!set_regs_matched_done) \
-+ { \
-+ active_reg_t r; \
-+ set_regs_matched_done = 1; \
-+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
-+ { \
-+ MATCHED_SOMETHING (reg_info[r]) \
-+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
-+ = 1; \
-+ } \
-+ } \
-+ } \
-+ while (0)
-+# endif /* not DEFINED_ONCE */
-+
-+/* Registers are set to a sentinel when they haven't yet matched. */
-+static CHAR_T PREFIX(reg_unset_dummy);
-+# define REG_UNSET_VALUE (&PREFIX(reg_unset_dummy))
-+# define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
-+
-+/* Subroutine declarations and macros for regex_compile. */
-+static void PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg);
-+static void PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc,
-+ int arg1, int arg2);
-+static void PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc,
-+ int arg, UCHAR_T *end);
-+static void PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc,
-+ int arg1, int arg2, UCHAR_T *end);
-+static boolean PREFIX(at_begline_loc_p) (const CHAR_T *pattern,
-+ const CHAR_T *p,
-+ reg_syntax_t syntax);
-+static boolean PREFIX(at_endline_loc_p) (const CHAR_T *p,
-+ const CHAR_T *pend,
-+ reg_syntax_t syntax);
-+# ifdef WCHAR
-+static reg_errcode_t wcs_compile_range (CHAR_T range_start,
-+ const CHAR_T **p_ptr,
-+ const CHAR_T *pend,
-+ char *translate,
-+ reg_syntax_t syntax,
-+ UCHAR_T *b,
-+ CHAR_T *char_set);
-+static void insert_space (int num, CHAR_T *loc, CHAR_T *end);
-+# else /* BYTE */
-+static reg_errcode_t byte_compile_range (unsigned int range_start,
-+ const char **p_ptr,
-+ const char *pend,
-+ RE_TRANSLATE_TYPE translate,
-+ reg_syntax_t syntax,
-+ unsigned char *b);
-+# endif /* WCHAR */
-+
-+/* Fetch the next character in the uncompiled pattern---translating it
-+ if necessary. Also cast from a signed character in the constant
-+ string passed to us by the user to an unsigned char that we can use
-+ as an array index (in, e.g., `translate'). */
-+/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
-+ because it is impossible to allocate 4GB array for some encodings
-+ which have 4 byte character_set like UCS4. */
-+# ifndef PATFETCH
-+# ifdef WCHAR
-+# define PATFETCH(c) \
-+ do {if (p == pend) return REG_EEND; \
-+ c = (UCHAR_T) *p++; \
-+ if (translate && (c <= 0xff)) c = (UCHAR_T) translate[c]; \
-+ } while (0)
-+# else /* BYTE */
-+# define PATFETCH(c) \
-+ do {if (p == pend) return REG_EEND; \
-+ c = (unsigned char) *p++; \
-+ if (translate) c = (unsigned char) translate[c]; \
-+ } while (0)
-+# endif /* WCHAR */
-+# endif
-+
-+/* Fetch the next character in the uncompiled pattern, with no
-+ translation. */
-+# define PATFETCH_RAW(c) \
-+ do {if (p == pend) return REG_EEND; \
-+ c = (UCHAR_T) *p++; \
-+ } while (0)
-+
-+/* Go backwards one character in the pattern. */
-+# define PATUNFETCH p--
-+
-+
-+/* If `translate' is non-null, return translate[D], else just D. We
-+ cast the subscript to translate because some data is declared as
-+ `char *', to avoid warnings when a string constant is passed. But
-+ when we use a character as a subscript we must make it unsigned. */
-+/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
-+ because it is impossible to allocate 4GB array for some encodings
-+ which have 4 byte character_set like UCS4. */
-+
-+# ifndef TRANSLATE
-+# ifdef WCHAR
-+# define TRANSLATE(d) \
-+ ((translate && ((UCHAR_T) (d)) <= 0xff) \
-+ ? (char) translate[(unsigned char) (d)] : (d))
-+# else /* BYTE */
-+# define TRANSLATE(d) \
-+ (translate ? (char) translate[(unsigned char) (d)] : (char) (d))
-+# endif /* WCHAR */
-+# endif
-+
-+
-+/* Macros for outputting the compiled pattern into `buffer'. */
-+
-+/* If the buffer isn't allocated when it comes in, use this. */
-+# define INIT_BUF_SIZE (32 * sizeof(UCHAR_T))
-+
-+/* Make sure we have at least N more bytes of space in buffer. */
-+# ifdef WCHAR
-+# define GET_BUFFER_SPACE(n) \
-+ while (((unsigned long)b - (unsigned long)COMPILED_BUFFER_VAR \
-+ + (n)*sizeof(CHAR_T)) > bufp->allocated) \
-+ EXTEND_BUFFER ()
-+# else /* BYTE */
-+# define GET_BUFFER_SPACE(n) \
-+ while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \
-+ EXTEND_BUFFER ()
-+# endif /* WCHAR */
-+
-+/* Make sure we have one more byte of buffer space and then add C to it. */
-+# define BUF_PUSH(c) \
-+ do { \
-+ GET_BUFFER_SPACE (1); \
-+ *b++ = (UCHAR_T) (c); \
-+ } while (0)
-+
-+
-+/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
-+# define BUF_PUSH_2(c1, c2) \
-+ do { \
-+ GET_BUFFER_SPACE (2); \
-+ *b++ = (UCHAR_T) (c1); \
-+ *b++ = (UCHAR_T) (c2); \
-+ } while (0)
-+
-+
-+/* As with BUF_PUSH_2, except for three bytes. */
-+# define BUF_PUSH_3(c1, c2, c3) \
-+ do { \
-+ GET_BUFFER_SPACE (3); \
-+ *b++ = (UCHAR_T) (c1); \
-+ *b++ = (UCHAR_T) (c2); \
-+ *b++ = (UCHAR_T) (c3); \
-+ } while (0)
-+
-+/* Store a jump with opcode OP at LOC to location TO. We store a
-+ relative address offset by the three bytes the jump itself occupies. */
-+# define STORE_JUMP(op, loc, to) \
-+ PREFIX(store_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)))
-+
-+/* Likewise, for a two-argument jump. */
-+# define STORE_JUMP2(op, loc, to, arg) \
-+ PREFIX(store_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), arg)
-+
-+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
-+# define INSERT_JUMP(op, loc, to) \
-+ PREFIX(insert_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), b)
-+
-+/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
-+# define INSERT_JUMP2(op, loc, to, arg) \
-+ PREFIX(insert_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)),\
-+ arg, b)
-+
-+/* This is not an arbitrary limit: the arguments which represent offsets
-+ into the pattern are two bytes long. So if 2^16 bytes turns out to
-+ be too small, many things would have to change. */
-+/* Any other compiler which, like MSC, has allocation limit below 2^16
-+ bytes will have to use approach similar to what was done below for
-+ MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up
-+ reallocating to 0 bytes. Such thing is not going to work too well.
-+ You have been warned!! */
-+# ifndef DEFINED_ONCE
-+# if defined _MSC_VER && !defined WIN32
-+/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
-+ The REALLOC define eliminates a flurry of conversion warnings,
-+ but is not required. */
-+# define MAX_BUF_SIZE 65500L
-+# define REALLOC(p,s) realloc ((p), (size_t) (s))
-+# else
-+# define MAX_BUF_SIZE (1L << 16)
-+# define REALLOC(p,s) realloc ((p), (s))
-+# endif
-+
-+/* Extend the buffer by twice its current size via realloc and
-+ reset the pointers that pointed into the old block to point to the
-+ correct places in the new one. If extending the buffer results in it
-+ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
-+# ifndef __BOUNDED_POINTERS__
-+# define __BOUNDED_POINTERS__ 0
-+# endif
-+# if __BOUNDED_POINTERS__
-+# define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated)
-+# define MOVE_BUFFER_POINTER(P) \
-+ (__ptrlow (P) += incr, SET_HIGH_BOUND (P), __ptrvalue (P) += incr)
-+# define ELSE_EXTEND_BUFFER_HIGH_BOUND \
-+ else \
-+ { \
-+ SET_HIGH_BOUND (b); \
-+ SET_HIGH_BOUND (begalt); \
-+ if (fixup_alt_jump) \
-+ SET_HIGH_BOUND (fixup_alt_jump); \
-+ if (laststart) \
-+ SET_HIGH_BOUND (laststart); \
-+ if (pending_exact) \
-+ SET_HIGH_BOUND (pending_exact); \
-+ }
-+# else
-+# define MOVE_BUFFER_POINTER(P) (P) += incr
-+# define ELSE_EXTEND_BUFFER_HIGH_BOUND
-+# endif
-+# endif /* not DEFINED_ONCE */
-+
-+# ifdef WCHAR
-+# define EXTEND_BUFFER() \
-+ do { \
-+ UCHAR_T *old_buffer = COMPILED_BUFFER_VAR; \
-+ int wchar_count; \
-+ if (bufp->allocated + sizeof(UCHAR_T) > MAX_BUF_SIZE) \
-+ return REG_ESIZE; \
-+ bufp->allocated <<= 1; \
-+ if (bufp->allocated > MAX_BUF_SIZE) \
-+ bufp->allocated = MAX_BUF_SIZE; \
-+ /* How many characters the new buffer can have? */ \
-+ wchar_count = bufp->allocated / sizeof(UCHAR_T); \
-+ if (wchar_count == 0) wchar_count = 1; \
-+ /* Truncate the buffer to CHAR_T align. */ \
-+ bufp->allocated = wchar_count * sizeof(UCHAR_T); \
-+ RETALLOC (COMPILED_BUFFER_VAR, wchar_count, UCHAR_T); \
-+ bufp->buffer = (char*)COMPILED_BUFFER_VAR; \
-+ if (COMPILED_BUFFER_VAR == NULL) \
-+ return REG_ESPACE; \
-+ /* If the buffer moved, move all the pointers into it. */ \
-+ if (old_buffer != COMPILED_BUFFER_VAR) \
-+ { \
-+ int incr = COMPILED_BUFFER_VAR - old_buffer; \
-+ MOVE_BUFFER_POINTER (b); \
-+ MOVE_BUFFER_POINTER (begalt); \
-+ if (fixup_alt_jump) \
-+ MOVE_BUFFER_POINTER (fixup_alt_jump); \
-+ if (laststart) \
-+ MOVE_BUFFER_POINTER (laststart); \
-+ if (pending_exact) \
-+ MOVE_BUFFER_POINTER (pending_exact); \
-+ } \
-+ ELSE_EXTEND_BUFFER_HIGH_BOUND \
-+ } while (0)
-+# else /* BYTE */
-+# define EXTEND_BUFFER() \
-+ do { \
-+ UCHAR_T *old_buffer = COMPILED_BUFFER_VAR; \
-+ if (bufp->allocated == MAX_BUF_SIZE) \
-+ return REG_ESIZE; \
-+ bufp->allocated <<= 1; \
-+ if (bufp->allocated > MAX_BUF_SIZE) \
-+ bufp->allocated = MAX_BUF_SIZE; \
-+ bufp->buffer = (UCHAR_T *) REALLOC (COMPILED_BUFFER_VAR, \
-+ bufp->allocated); \
-+ if (COMPILED_BUFFER_VAR == NULL) \
-+ return REG_ESPACE; \
-+ /* If the buffer moved, move all the pointers into it. */ \
-+ if (old_buffer != COMPILED_BUFFER_VAR) \
-+ { \
-+ int incr = COMPILED_BUFFER_VAR - old_buffer; \
-+ MOVE_BUFFER_POINTER (b); \
-+ MOVE_BUFFER_POINTER (begalt); \
-+ if (fixup_alt_jump) \
-+ MOVE_BUFFER_POINTER (fixup_alt_jump); \
-+ if (laststart) \
-+ MOVE_BUFFER_POINTER (laststart); \
-+ if (pending_exact) \
-+ MOVE_BUFFER_POINTER (pending_exact); \
-+ } \
-+ ELSE_EXTEND_BUFFER_HIGH_BOUND \
-+ } while (0)
-+# endif /* WCHAR */
-+
-+# ifndef DEFINED_ONCE
-+/* Since we have one byte reserved for the register number argument to
-+ {start,stop}_memory, the maximum number of groups we can report
-+ things about is what fits in that byte. */
-+# define MAX_REGNUM 255
-+
-+/* But patterns can have more than `MAX_REGNUM' registers. We just
-+ ignore the excess. */
-+typedef unsigned regnum_t;
-+
-+
-+/* Macros for the compile stack. */
-+
-+/* Since offsets can go either forwards or backwards, this type needs to
-+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
-+/* int may be not enough when sizeof(int) == 2. */
-+typedef long pattern_offset_t;
-+
-+typedef struct
-+{
-+ pattern_offset_t begalt_offset;
-+ pattern_offset_t fixup_alt_jump;
-+ pattern_offset_t inner_group_offset;
-+ pattern_offset_t laststart_offset;
-+ regnum_t regnum;
-+} compile_stack_elt_t;
-+
-+
-+typedef struct
-+{
-+ compile_stack_elt_t *stack;
-+ unsigned size;
-+ unsigned avail; /* Offset of next open position. */
-+} compile_stack_type;
-+
-+
-+# define INIT_COMPILE_STACK_SIZE 32
-+
-+# define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
-+# define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
-+
-+/* The next available element. */
-+# define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
-+
-+# endif /* not DEFINED_ONCE */
-+
-+/* Set the bit for character C in a list. */
-+# ifndef DEFINED_ONCE
-+# define SET_LIST_BIT(c) \
-+ (b[((unsigned char) (c)) / BYTEWIDTH] \
-+ |= 1 << (((unsigned char) c) % BYTEWIDTH))
-+# endif /* DEFINED_ONCE */
-+
-+/* Get the next unsigned number in the uncompiled pattern. */
-+# define GET_UNSIGNED_NUMBER(num) \
-+ { \
-+ while (p != pend) \
-+ { \
-+ PATFETCH (c); \
-+ if (c < '0' || c > '9') \
-+ break; \
-+ if (num <= RE_DUP_MAX) \
-+ { \
-+ if (num < 0) \
-+ num = 0; \
-+ num = num * 10 + c - '0'; \
-+ } \
-+ } \
-+ }
-+
-+# ifndef DEFINED_ONCE
-+# if 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
-+# 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
-+# endif /* DEFINED_ONCE */
-+
-+# ifndef MATCH_MAY_ALLOCATE
-+
-+/* If we cannot allocate large objects within re_match_2_internal,
-+ we make the fail stack and register vectors global.
-+ The fail stack, we grow to the maximum size when a regexp
-+ is compiled.
-+ The register vectors, we adjust in size each time we
-+ compile a regexp, according to the number of registers it needs. */
-+
-+static PREFIX(fail_stack_type) fail_stack;
-+
-+/* Size with which the following vectors are currently allocated.
-+ That is so we can make them bigger as needed,
-+ but never make them smaller. */
-+# ifdef DEFINED_ONCE
-+static int regs_allocated_size;
-+
-+static const char ** regstart, ** regend;
-+static const char ** old_regstart, ** old_regend;
-+static const char **best_regstart, **best_regend;
-+static const char **reg_dummy;
-+# endif /* DEFINED_ONCE */
-+
-+static PREFIX(register_info_type) *PREFIX(reg_info);
-+static PREFIX(register_info_type) *PREFIX(reg_info_dummy);
-+
-+/* Make the register vectors big enough for NUM_REGS registers,
-+ but don't make them smaller. */
-+
-+static void
-+PREFIX(regex_grow_registers) (int num_regs)
-+{
-+ if (num_regs > regs_allocated_size)
-+ {
-+ RETALLOC_IF (regstart, num_regs, const char *);
-+ RETALLOC_IF (regend, num_regs, const char *);
-+ RETALLOC_IF (old_regstart, num_regs, const char *);
-+ RETALLOC_IF (old_regend, num_regs, const char *);
-+ RETALLOC_IF (best_regstart, num_regs, const char *);
-+ RETALLOC_IF (best_regend, num_regs, const char *);
-+ RETALLOC_IF (PREFIX(reg_info), num_regs, PREFIX(register_info_type));
-+ RETALLOC_IF (reg_dummy, num_regs, const char *);
-+ RETALLOC_IF (PREFIX(reg_info_dummy), num_regs, PREFIX(register_info_type));
-+
-+ regs_allocated_size = num_regs;
-+ }
-+}
-+
-+# endif /* not MATCH_MAY_ALLOCATE */
-+
-+# ifndef DEFINED_ONCE
-+static boolean group_in_compile_stack (compile_stack_type compile_stack,
-+ regnum_t regnum);
-+# endif /* not DEFINED_ONCE */
-+
-+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
-+ Returns one of error codes defined in `regex.h', or zero for success.
-+
-+ Assumes the `allocated' (and perhaps `buffer') and `translate'
-+ fields are set in BUFP on entry.
-+
-+ If it succeeds, results are put in BUFP (if it returns an error, the
-+ contents of BUFP are undefined):
-+ `buffer' is the compiled pattern;
-+ `syntax' is set to SYNTAX;
-+ `used' is set to the length of the compiled pattern;
-+ `fastmap_accurate' is zero;
-+ `re_nsub' is the number of subexpressions in PATTERN;
-+ `not_bol' and `not_eol' are zero;
-+
-+ The `fastmap' and `newline_anchor' fields are neither
-+ examined nor set. */
-+
-+/* Return, freeing storage we allocated. */
-+# ifdef WCHAR
-+# define FREE_STACK_RETURN(value) \
-+ return (free(pattern), free(mbs_offset), free(is_binary), free (compile_stack.stack), value)
-+# else
-+# define FREE_STACK_RETURN(value) \
-+ return (free (compile_stack.stack), value)
-+# endif /* WCHAR */
-+
-+static reg_errcode_t
-+PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
-+ size_t ARG_PREFIX(size), reg_syntax_t syntax,
-+ struct re_pattern_buffer *bufp)
-+{
-+ /* We fetch characters from PATTERN here. Even though PATTERN is
-+ `char *' (i.e., signed), we declare these variables as unsigned, so
-+ they can be reliably used as array indices. */
-+ register UCHAR_T c, c1;
-+
-+#ifdef WCHAR
-+ /* A temporary space to keep wchar_t pattern and compiled pattern. */
-+ CHAR_T *pattern, *COMPILED_BUFFER_VAR;
-+ size_t size;
-+ /* offset buffer for optimization. See convert_mbs_to_wc. */
-+ int *mbs_offset = NULL;
-+ /* It hold whether each wchar_t is binary data or not. */
-+ char *is_binary = NULL;
-+ /* A flag whether exactn is handling binary data or not. */
-+ char is_exactn_bin = FALSE;
-+#endif /* WCHAR */
-+
-+ /* A random temporary spot in PATTERN. */
-+ const CHAR_T *p1;
-+
-+ /* Points to the end of the buffer, where we should append. */
-+ register UCHAR_T *b;
-+
-+ /* Keeps track of unclosed groups. */
-+ compile_stack_type compile_stack;
-+
-+ /* Points to the current (ending) position in the pattern. */
-+#ifdef WCHAR
-+ const CHAR_T *p;
-+ const CHAR_T *pend;
-+#else /* BYTE */
-+ const CHAR_T *p = pattern;
-+ const CHAR_T *pend = pattern + size;
-+#endif /* WCHAR */
-+
-+ /* How to translate the characters in the pattern. */
-+ RE_TRANSLATE_TYPE translate = bufp->translate;
-+
-+ /* Address of the count-byte of the most recently inserted `exactn'
-+ command. This makes it possible to tell if a new exact-match
-+ character can be added to that command or if the character requires
-+ a new `exactn' command. */
-+ UCHAR_T *pending_exact = 0;
-+
-+ /* Address of start of the most recently finished expression.
-+ This tells, e.g., postfix * where to find the start of its
-+ operand. Reset at the beginning of groups and alternatives. */
-+ UCHAR_T *laststart = 0;
-+
-+ /* Address of beginning of regexp, or inside of last group. */
-+ UCHAR_T *begalt;
-+
-+ /* Address of the place where a forward jump should go to the end of
-+ the containing expression. Each alternative of an `or' -- except the
-+ last -- ends with a forward jump of this sort. */
-+ UCHAR_T *fixup_alt_jump = 0;
-+
-+ /* Counts open-groups as they are encountered. Remembered for the
-+ matching close-group on the compile stack, so the same register
-+ number is put in the stop_memory as the start_memory. */
-+ regnum_t regnum = 0;
-+
-+#ifdef WCHAR
-+ /* Initialize the wchar_t PATTERN and offset_buffer. */
-+ p = pend = pattern = TALLOC(csize + 1, CHAR_T);
-+ mbs_offset = TALLOC(csize + 1, int);
-+ is_binary = TALLOC(csize + 1, char);
-+ if (pattern == NULL || mbs_offset == NULL || is_binary == NULL)
-+ {
-+ free(pattern);
-+ free(mbs_offset);
-+ free(is_binary);
-+ return REG_ESPACE;
-+ }
-+ pattern[csize] = L'\0'; /* sentinel */
-+ size = convert_mbs_to_wcs(pattern, cpattern, csize, mbs_offset, is_binary);
-+ pend = p + size;
-+ if (size < 0)
-+ {
-+ free(pattern);
-+ free(mbs_offset);
-+ free(is_binary);
-+ return REG_BADPAT;
-+ }
-+#endif
-+
-+#ifdef DEBUG
-+ DEBUG_PRINT1 ("\nCompiling pattern: ");
-+ if (debug)
-+ {
-+ unsigned debug_count;
-+
-+ for (debug_count = 0; debug_count < size; debug_count++)
-+ PUT_CHAR (pattern[debug_count]);
-+ putchar ('\n');
-+ }
-+#endif /* DEBUG */
-+
-+ /* Initialize the compile stack. */
-+ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
-+ if (compile_stack.stack == NULL)
-+ {
-+#ifdef WCHAR
-+ free(pattern);
-+ free(mbs_offset);
-+ free(is_binary);
-+#endif
-+ return REG_ESPACE;
-+ }
-+
-+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
-+ compile_stack.avail = 0;
-+
-+ /* Initialize the pattern buffer. */
-+ bufp->syntax = syntax;
-+ bufp->fastmap_accurate = 0;
-+ bufp->not_bol = bufp->not_eol = 0;
-+
-+ /* Set `used' to zero, so that if we return an error, the pattern
-+ printer (for debugging) will think there's no pattern. We reset it
-+ at the end. */
-+ bufp->used = 0;
-+
-+ /* Always count groups, whether or not bufp->no_sub is set. */
-+ bufp->re_nsub = 0;
-+
-+#if !defined emacs && !defined SYNTAX_TABLE
-+ /* Initialize the syntax table. */
-+ init_syntax_once ();
-+#endif
-+
-+ if (bufp->allocated == 0)
-+ {
-+ if (bufp->buffer)
-+ { /* 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. */
-+#ifdef WCHAR
-+ /* Free bufp->buffer and allocate an array for wchar_t pattern
-+ buffer. */
-+ free(bufp->buffer);
-+ COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE/sizeof(UCHAR_T),
-+ UCHAR_T);
-+#else
-+ RETALLOC (COMPILED_BUFFER_VAR, INIT_BUF_SIZE, UCHAR_T);
-+#endif /* WCHAR */
-+ }
-+ else
-+ { /* Caller did not allocate a buffer. Do it for them. */
-+ COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE / sizeof(UCHAR_T),
-+ UCHAR_T);
-+ }
-+
-+ if (!COMPILED_BUFFER_VAR) FREE_STACK_RETURN (REG_ESPACE);
-+#ifdef WCHAR
-+ bufp->buffer = (char*)COMPILED_BUFFER_VAR;
-+#endif /* WCHAR */
-+ bufp->allocated = INIT_BUF_SIZE;
-+ }
-+#ifdef WCHAR
-+ else
-+ COMPILED_BUFFER_VAR = (UCHAR_T*) bufp->buffer;
-+#endif
-+
-+ begalt = b = COMPILED_BUFFER_VAR;
-+
-+ /* Loop through the uncompiled pattern until we're at the end. */
-+ while (p != pend)
-+ {
-+ PATFETCH (c);
-+
-+ switch (c)
-+ {
-+ case '^':
-+ {
-+ if ( /* If at start of pattern, it's an operator. */
-+ p == pattern + 1
-+ /* If context independent, it's an operator. */
-+ || syntax & RE_CONTEXT_INDEP_ANCHORS
-+ /* Otherwise, depends on what's come before. */
-+ || PREFIX(at_begline_loc_p) (pattern, p, syntax))
-+ BUF_PUSH (begline);
-+ else
-+ goto normal_char;
-+ }
-+ break;
-+
-+
-+ case '$':
-+ {
-+ if ( /* If at end of pattern, it's an operator. */
-+ p == pend
-+ /* If context independent, it's an operator. */
-+ || syntax & RE_CONTEXT_INDEP_ANCHORS
-+ /* Otherwise, depends on what's next. */
-+ || PREFIX(at_endline_loc_p) (p, pend, syntax))
-+ BUF_PUSH (endline);
-+ else
-+ goto normal_char;
-+ }
-+ break;
-+
-+
-+ case '+':
-+ case '?':
-+ if ((syntax & RE_BK_PLUS_QM)
-+ || (syntax & RE_LIMITED_OPS))
-+ goto normal_char;
-+ handle_plus:
-+ case '*':
-+ /* If there is no previous pattern... */
-+ if (!laststart)
-+ {
-+ if (syntax & RE_CONTEXT_INVALID_OPS)
-+ FREE_STACK_RETURN (REG_BADRPT);
-+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
-+ goto normal_char;
-+ }
-+
-+ {
-+ /* Are we optimizing this jump? */
-+ boolean keep_string_p = false;
-+
-+ /* 1 means zero (many) matches is allowed. */
-+ char zero_times_ok = 0, many_times_ok = 0;
-+
-+ /* If there is a sequence of repetition chars, collapse it
-+ down to just one (the right one). We can't combine
-+ interval operators with these because of, e.g., `a{2}*',
-+ which should only match an even number of `a's. */
-+
-+ for (;;)
-+ {
-+ zero_times_ok |= c != '+';
-+ many_times_ok |= c != '?';
-+
-+ if (p == pend)
-+ break;
-+
-+ PATFETCH (c);
-+
-+ if (c == '*'
-+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
-+ ;
-+
-+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
-+ {
-+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
-+
-+ PATFETCH (c1);
-+ if (!(c1 == '+' || c1 == '?'))
-+ {
-+ PATUNFETCH;
-+ PATUNFETCH;
-+ break;
-+ }
-+
-+ c = c1;
-+ }
-+ else
-+ {
-+ PATUNFETCH;
-+ break;
-+ }
-+
-+ /* If we get here, we found another repeat character. */
-+ }
-+
-+ /* Star, etc. applied to an empty pattern is equivalent
-+ to an empty pattern. */
-+ if (!laststart)
-+ break;
-+
-+ /* Now we know whether or not zero matches is allowed
-+ and also whether or not two or more matches is allowed. */
-+ if (many_times_ok)
-+ { /* More than one repetition is allowed, so put in at the
-+ end a backward relative jump from `b' to before the next
-+ jump we're going to put in below (which jumps from
-+ laststart to after this jump).
-+
-+ But if we are at the `*' in the exact sequence `.*\n',
-+ insert an unconditional jump backwards to the .,
-+ instead of the beginning of the loop. This way we only
-+ push a failure point once, instead of every time
-+ through the loop. */
-+ assert (p - 1 > pattern);
-+
-+ /* Allocate the space for the jump. */
-+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
-+
-+ /* We know we are not at the first character of the pattern,
-+ because laststart was nonzero. And we've already
-+ incremented `p', by the way, to be the character after
-+ the `*'. Do we have to do something analogous here
-+ for null bytes, because of RE_DOT_NOT_NULL? */
-+ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
-+ && zero_times_ok
-+ && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
-+ && !(syntax & RE_DOT_NEWLINE))
-+ { /* We have .*\n. */
-+ STORE_JUMP (jump, b, laststart);
-+ keep_string_p = true;
-+ }
-+ else
-+ /* Anything else. */
-+ STORE_JUMP (maybe_pop_jump, b, laststart -
-+ (1 + OFFSET_ADDRESS_SIZE));
-+
-+ /* We've added more stuff to the buffer. */
-+ b += 1 + OFFSET_ADDRESS_SIZE;
-+ }
-+
-+ /* On failure, jump from laststart to b + 3, which will be the
-+ end of the buffer after this jump is inserted. */
-+ /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE' instead of
-+ 'b + 3'. */
-+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
-+ INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
-+ : on_failure_jump,
-+ laststart, b + 1 + OFFSET_ADDRESS_SIZE);
-+ pending_exact = 0;
-+ b += 1 + OFFSET_ADDRESS_SIZE;
-+
-+ if (!zero_times_ok)
-+ {
-+ /* At least one repetition is required, so insert a
-+ `dummy_failure_jump' before the initial
-+ `on_failure_jump' instruction of the loop. This
-+ effects a skip over that instruction the first time
-+ we hit that loop. */
-+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
-+ INSERT_JUMP (dummy_failure_jump, laststart, laststart +
-+ 2 + 2 * OFFSET_ADDRESS_SIZE);
-+ b += 1 + OFFSET_ADDRESS_SIZE;
-+ }
-+ }
-+ break;
-+
-+
-+ case '.':
-+ laststart = b;
-+ BUF_PUSH (anychar);
-+ break;
-+
-+
-+ case '[':
-+ {
-+ boolean had_char_class = false;
-+#ifdef WCHAR
-+ CHAR_T range_start = 0xffffffff;
-+#else
-+ unsigned int range_start = 0xffffffff;
-+#endif
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+#ifdef WCHAR
-+ /* We assume a charset(_not) structure as a wchar_t array.
-+ charset[0] = (re_opcode_t) charset(_not)
-+ charset[1] = l (= length of char_classes)
-+ charset[2] = m (= length of collating_symbols)
-+ charset[3] = n (= length of equivalence_classes)
-+ charset[4] = o (= length of char_ranges)
-+ charset[5] = p (= length of chars)
-+
-+ charset[6] = char_class (wctype_t)
-+ charset[6+CHAR_CLASS_SIZE] = char_class (wctype_t)
-+ ...
-+ charset[l+5] = char_class (wctype_t)
-+
-+ charset[l+6] = collating_symbol (wchar_t)
-+ ...
-+ charset[l+m+5] = collating_symbol (wchar_t)
-+ ifdef _LIBC we use the index if
-+ _NL_COLLATE_SYMB_EXTRAMB instead of
-+ wchar_t string.
-+
-+ charset[l+m+6] = equivalence_classes (wchar_t)
-+ ...
-+ charset[l+m+n+5] = equivalence_classes (wchar_t)
-+ ifdef _LIBC we use the index in
-+ _NL_COLLATE_WEIGHT instead of
-+ wchar_t string.
-+
-+ charset[l+m+n+6] = range_start
-+ charset[l+m+n+7] = range_end
-+ ...
-+ charset[l+m+n+2o+4] = range_start
-+ charset[l+m+n+2o+5] = range_end
-+ ifdef _LIBC we use the value looked up
-+ in _NL_COLLATE_COLLSEQ instead of
-+ wchar_t character.
-+
-+ charset[l+m+n+2o+6] = char
-+ ...
-+ charset[l+m+n+2o+p+5] = char
-+
-+ */
-+
-+ /* We need at least 6 spaces: the opcode, the length of
-+ char_classes, the length of collating_symbols, the length of
-+ equivalence_classes, the length of char_ranges, the length of
-+ chars. */
-+ GET_BUFFER_SPACE (6);
-+
-+ /* Save b as laststart. And We use laststart as the pointer
-+ to the first element of the charset here.
-+ In other words, laststart[i] indicates charset[i]. */
-+ laststart = b;
-+
-+ /* We test `*p == '^' twice, instead of using an if
-+ statement, so we only need one BUF_PUSH. */
-+ BUF_PUSH (*p == '^' ? charset_not : charset);
-+ if (*p == '^')
-+ p++;
-+
-+ /* Push the length of char_classes, the length of
-+ collating_symbols, the length of equivalence_classes, the
-+ length of char_ranges and the length of chars. */
-+ BUF_PUSH_3 (0, 0, 0);
-+ BUF_PUSH_2 (0, 0);
-+
-+ /* Remember the first position in the bracket expression. */
-+ p1 = p;
-+
-+ /* charset_not matches newline according to a syntax bit. */
-+ if ((re_opcode_t) b[-6] == charset_not
-+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
-+ {
-+ BUF_PUSH('\n');
-+ laststart[5]++; /* Update the length of characters */
-+ }
-+
-+ /* Read in characters and ranges, setting map bits. */
-+ for (;;)
-+ {
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ PATFETCH (c);
-+
-+ /* \ might escape characters inside [...] and [^...]. */
-+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
-+ {
-+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
-+
-+ PATFETCH (c1);
-+ BUF_PUSH(c1);
-+ laststart[5]++; /* Update the length of chars */
-+ range_start = c1;
-+ continue;
-+ }
-+
-+ /* Could be the end of the bracket expression. If it's
-+ not (i.e., when the bracket expression is `[]' so
-+ far), the ']' character bit gets set way below. */
-+ if (c == ']' && p != p1 + 1)
-+ break;
-+
-+ /* Look ahead to see if it's a range when the last thing
-+ was a character class. */
-+ if (had_char_class && c == '-' && *p != ']')
-+ FREE_STACK_RETURN (REG_ERANGE);
-+
-+ /* Look ahead to see if it's a range when the last thing
-+ was a character: if this is a hyphen not at the
-+ beginning or the end of a list, then it's the range
-+ operator. */
-+ if (c == '-'
-+ && !(p - 2 >= pattern && p[-2] == '[')
-+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
-+ && *p != ']')
-+ {
-+ reg_errcode_t ret;
-+ /* Allocate the space for range_start and range_end. */
-+ GET_BUFFER_SPACE (2);
-+ /* Update the pointer to indicate end of buffer. */
-+ b += 2;
-+ ret = wcs_compile_range (range_start, &p, pend, translate,
-+ syntax, b, laststart);
-+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
-+ range_start = 0xffffffff;
-+ }
-+ else if (p[0] == '-' && p[1] != ']')
-+ { /* This handles ranges made up of characters only. */
-+ reg_errcode_t ret;
-+
-+ /* Move past the `-'. */
-+ PATFETCH (c1);
-+ /* Allocate the space for range_start and range_end. */
-+ GET_BUFFER_SPACE (2);
-+ /* Update the pointer to indicate end of buffer. */
-+ b += 2;
-+ ret = wcs_compile_range (c, &p, pend, translate, syntax, b,
-+ laststart);
-+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
-+ range_start = 0xffffffff;
-+ }
-+
-+ /* See if we're at the beginning of a possible character
-+ class. */
-+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
-+ { /* Leave room for the null. */
-+ char str[CHAR_CLASS_MAX_LENGTH + 1];
-+
-+ PATFETCH (c);
-+ c1 = 0;
-+
-+ /* If pattern is `[[:'. */
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ for (;;)
-+ {
-+ PATFETCH (c);
-+ if ((c == ':' && *p == ']') || p == pend)
-+ break;
-+ if (c1 < CHAR_CLASS_MAX_LENGTH)
-+ str[c1++] = c;
-+ else
-+ /* This is in any case an invalid class name. */
-+ str[0] = '\0';
-+ }
-+ str[c1] = '\0';
-+
-+ /* If isn't a word bracketed by `[:' and `:]':
-+ undo the ending character, the letters, and leave
-+ the leading `:' and `[' (but store them as character). */
-+ if (c == ':' && *p == ']')
-+ {
-+ wctype_t wt;
-+ uintptr_t alignedp;
-+
-+ /* Query the character class as wctype_t. */
-+ wt = IS_CHAR_CLASS (str);
-+ if (wt == 0)
-+ FREE_STACK_RETURN (REG_ECTYPE);
-+
-+ /* Throw away the ] at the end of the character
-+ class. */
-+ PATFETCH (c);
-+
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ /* Allocate the space for character class. */
-+ GET_BUFFER_SPACE(CHAR_CLASS_SIZE);
-+ /* Update the pointer to indicate end of buffer. */
-+ b += CHAR_CLASS_SIZE;
-+ /* Move data which follow character classes
-+ not to violate the data. */
-+ insert_space(CHAR_CLASS_SIZE,
-+ laststart + 6 + laststart[1],
-+ b - 1);
-+ alignedp = ((uintptr_t)(laststart + 6 + laststart[1])
-+ + __alignof__(wctype_t) - 1)
-+ & ~(uintptr_t)(__alignof__(wctype_t) - 1);
-+ /* Store the character class. */
-+ *((wctype_t*)alignedp) = wt;
-+ /* Update length of char_classes */
-+ laststart[1] += CHAR_CLASS_SIZE;
-+
-+ had_char_class = true;
-+ }
-+ else
-+ {
-+ c1++;
-+ while (c1--)
-+ PATUNFETCH;
-+ BUF_PUSH ('[');
-+ BUF_PUSH (':');
-+ laststart[5] += 2; /* Update the length of characters */
-+ range_start = ':';
-+ had_char_class = false;
-+ }
-+ }
-+ else if (syntax & RE_CHAR_CLASSES && c == '[' && (*p == '='
-+ || *p == '.'))
-+ {
-+ CHAR_T str[128]; /* Should be large enough. */
-+ CHAR_T delim = *p; /* '=' or '.' */
-+# ifdef _LIBC
-+ uint32_t nrules =
-+ _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-+# endif
-+ PATFETCH (c);
-+ c1 = 0;
-+
-+ /* If pattern is `[[=' or '[[.'. */
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ for (;;)
-+ {
-+ PATFETCH (c);
-+ if ((c == delim && *p == ']') || p == pend)
-+ break;
-+ if (c1 < sizeof (str) - 1)
-+ str[c1++] = c;
-+ else
-+ /* This is in any case an invalid class name. */
-+ str[0] = '\0';
-+ }
-+ str[c1] = '\0';
-+
-+ if (c == delim && *p == ']' && str[0] != '\0')
-+ {
-+ unsigned int i, offset;
-+ /* If we have no collation data we use the default
-+ collation in which each character is in a class
-+ by itself. It also means that ASCII is the
-+ character set and therefore we cannot have character
-+ with more than one byte in the multibyte
-+ representation. */
-+
-+ /* If not defined _LIBC, we push the name and
-+ `\0' for the sake of matching performance. */
-+ int datasize = c1 + 1;
-+
-+# ifdef _LIBC
-+ int32_t idx = 0;
-+ if (nrules == 0)
-+# endif
-+ {
-+ if (c1 != 1)
-+ FREE_STACK_RETURN (REG_ECOLLATE);
-+ }
-+# ifdef _LIBC
-+ else
-+ {
-+ const int32_t *table;
-+ const int32_t *weights;
-+ const int32_t *extra;
-+ const int32_t *indirect;
-+ wint_t *cp;
-+
-+ if(delim == '=')
-+ {
-+ /* We push the index for equivalence class. */
-+ cp = (wint_t*)str;
-+
-+ table = (const int32_t *)
-+ _NL_CURRENT (LC_COLLATE,
-+ _NL_COLLATE_TABLEWC);
-+ weights = (const int32_t *)
-+ _NL_CURRENT (LC_COLLATE,
-+ _NL_COLLATE_WEIGHTWC);
-+ extra = (const wint_t *)
-+ _NL_CURRENT (LC_COLLATE,
-+ _NL_COLLATE_EXTRAWC);
-+ indirect = (const int32_t *)
-+ _NL_CURRENT (LC_COLLATE,
-+ _NL_COLLATE_INDIRECTWC);
-+
-+ idx = FINDIDX (table, indirect, extra, &cp, 1);
-+ if (idx == 0 || cp < (wint_t*) str + c1)
-+ /* This is no valid character. */
-+ FREE_STACK_RETURN (REG_ECOLLATE);
-+
-+ str[0] = (wchar_t)idx;
-+ }
-+ else /* delim == '.' */
-+ {
-+ /* We push collation sequence value
-+ for collating symbol. */
-+ int32_t table_size;
-+ const int32_t *symb_table;
-+ const unsigned char *extra;
-+ int32_t idx;
-+ int32_t elem;
-+ int32_t second;
-+ int32_t hash;
-+ char char_str[c1];
-+
-+ /* 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 (i = 0; i < c1; ++i)
-+ char_str[i] = str[i];
-+
-+ 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 (char_str, c1);
-+
-+ idx = 0;
-+ elem = hash % table_size;
-+ second = hash % (table_size - 2);
-+ while (symb_table[2 * elem] != 0)
-+ {
-+ /* First compare the hashing value. */
-+ if (symb_table[2 * elem] == hash
-+ && c1 == extra[symb_table[2 * elem + 1]]
-+ && memcmp (char_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;
-+ }
-+
-+ if (symb_table[2 * elem] != 0)
-+ {
-+ /* Compute the index of the byte sequence
-+ in the table. */
-+ idx += 1 + extra[idx];
-+ /* Adjust for the alignment. */
-+ idx = (idx + 3) & ~3;
-+
-+ str[0] = (wchar_t) idx + 4;
-+ }
-+ else if (symb_table[2 * elem] == 0 && c1 == 1)
-+ {
-+ /* No valid character. Match it as a
-+ single byte character. */
-+ had_char_class = false;
-+ BUF_PUSH(str[0]);
-+ /* Update the length of characters */
-+ laststart[5]++;
-+ range_start = str[0];
-+
-+ /* Throw away the ] at the end of the
-+ collating symbol. */
-+ PATFETCH (c);
-+ /* exit from the switch block. */
-+ continue;
-+ }
-+ else
-+ FREE_STACK_RETURN (REG_ECOLLATE);
-+ }
-+ datasize = 1;
-+ }
-+# endif
-+ /* Throw away the ] at the end of the equivalence
-+ class (or collating symbol). */
-+ PATFETCH (c);
-+
-+ /* Allocate the space for the equivalence class
-+ (or collating symbol) (and '\0' if needed). */
-+ GET_BUFFER_SPACE(datasize);
-+ /* Update the pointer to indicate end of buffer. */
-+ b += datasize;
-+
-+ if (delim == '=')
-+ { /* equivalence class */
-+ /* Calculate the offset of char_ranges,
-+ which is next to equivalence_classes. */
-+ offset = laststart[1] + laststart[2]
-+ + laststart[3] +6;
-+ /* Insert space. */
-+ insert_space(datasize, laststart + offset, b - 1);
-+
-+ /* Write the equivalence_class and \0. */
-+ for (i = 0 ; i < datasize ; i++)
-+ laststart[offset + i] = str[i];
-+
-+ /* Update the length of equivalence_classes. */
-+ laststart[3] += datasize;
-+ had_char_class = true;
-+ }
-+ else /* delim == '.' */
-+ { /* collating symbol */
-+ /* Calculate the offset of the equivalence_classes,
-+ which is next to collating_symbols. */
-+ offset = laststart[1] + laststart[2] + 6;
-+ /* Insert space and write the collationg_symbol
-+ and \0. */
-+ insert_space(datasize, laststart + offset, b-1);
-+ for (i = 0 ; i < datasize ; i++)
-+ laststart[offset + i] = str[i];
-+
-+ /* In re_match_2_internal if range_start < -1, we
-+ assume -range_start is the offset of the
-+ collating symbol which is specified as
-+ the character of the range start. So we assign
-+ -(laststart[1] + laststart[2] + 6) to
-+ range_start. */
-+ range_start = -(laststart[1] + laststart[2] + 6);
-+ /* Update the length of collating_symbol. */
-+ laststart[2] += datasize;
-+ had_char_class = false;
-+ }
-+ }
-+ else
-+ {
-+ c1++;
-+ while (c1--)
-+ PATUNFETCH;
-+ BUF_PUSH ('[');
-+ BUF_PUSH (delim);
-+ laststart[5] += 2; /* Update the length of characters */
-+ range_start = delim;
-+ had_char_class = false;
-+ }
-+ }
-+ else
-+ {
-+ had_char_class = false;
-+ BUF_PUSH(c);
-+ laststart[5]++; /* Update the length of characters */
-+ range_start = c;
-+ }
-+ }
-+
-+#else /* BYTE */
-+ /* Ensure that we have enough space to push a charset: the
-+ opcode, the length count, and the bitset; 34 bytes in all. */
-+ GET_BUFFER_SPACE (34);
-+
-+ laststart = b;
-+
-+ /* We test `*p == '^' twice, instead of using an if
-+ statement, so we only need one BUF_PUSH. */
-+ BUF_PUSH (*p == '^' ? charset_not : charset);
-+ if (*p == '^')
-+ p++;
-+
-+ /* Remember the first position in the bracket expression. */
-+ p1 = p;
-+
-+ /* Push the number of bytes in the bitmap. */
-+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
-+
-+ /* Clear the whole map. */
-+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
-+
-+ /* charset_not matches newline according to a syntax bit. */
-+ if ((re_opcode_t) b[-2] == charset_not
-+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
-+ SET_LIST_BIT ('\n');
-+
-+ /* Read in characters and ranges, setting map bits. */
-+ for (;;)
-+ {
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ PATFETCH (c);
-+
-+ /* \ might escape characters inside [...] and [^...]. */
-+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
-+ {
-+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
-+
-+ PATFETCH (c1);
-+ SET_LIST_BIT (c1);
-+ range_start = c1;
-+ continue;
-+ }
-+
-+ /* Could be the end of the bracket expression. If it's
-+ not (i.e., when the bracket expression is `[]' so
-+ far), the ']' character bit gets set way below. */
-+ if (c == ']' && p != p1 + 1)
-+ break;
-+
-+ /* Look ahead to see if it's a range when the last thing
-+ was a character class. */
-+ if (had_char_class && c == '-' && *p != ']')
-+ FREE_STACK_RETURN (REG_ERANGE);
-+
-+ /* Look ahead to see if it's a range when the last thing
-+ was a character: if this is a hyphen not at the
-+ beginning or the end of a list, then it's the range
-+ operator. */
-+ if (c == '-'
-+ && !(p - 2 >= pattern && p[-2] == '[')
-+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
-+ && *p != ']')
-+ {
-+ reg_errcode_t ret
-+ = byte_compile_range (range_start, &p, pend, translate,
-+ syntax, b);
-+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
-+ range_start = 0xffffffff;
-+ }
-+
-+ else if (p[0] == '-' && p[1] != ']')
-+ { /* This handles ranges made up of characters only. */
-+ reg_errcode_t ret;
-+
-+ /* Move past the `-'. */
-+ PATFETCH (c1);
-+
-+ ret = byte_compile_range (c, &p, pend, translate, syntax, b);
-+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
-+ range_start = 0xffffffff;
-+ }
-+
-+ /* See if we're at the beginning of a possible character
-+ class. */
-+
-+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
-+ { /* Leave room for the null. */
-+ char str[CHAR_CLASS_MAX_LENGTH + 1];
-+
-+ PATFETCH (c);
-+ c1 = 0;
-+
-+ /* If pattern is `[[:'. */
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ for (;;)
-+ {
-+ PATFETCH (c);
-+ if ((c == ':' && *p == ']') || p == pend)
-+ break;
-+ if (((int) c1) < CHAR_CLASS_MAX_LENGTH)
-+ str[c1++] = c;
-+ else
-+ /* This is in any case an invalid class name. */
-+ str[0] = '\0';
-+ }
-+ str[c1] = '\0';
-+
-+ /* If isn't a word bracketed by `[:' and `:]':
-+ undo the ending character, the letters, and leave
-+ the leading `:' and `[' (but set bits for them). */
-+ if (c == ':' && *p == ']')
-+ {
-+# if WIDE_CHAR_SUPPORT
-+ boolean is_lower = STREQ (str, "lower");
-+ boolean is_upper = STREQ (str, "upper");
-+ wctype_t wt;
-+ int ch;
-+
-+ wt = IS_CHAR_CLASS (str);
-+ if (wt == 0)
-+ FREE_STACK_RETURN (REG_ECTYPE);
-+
-+ /* Throw away the ] at the end of the character
-+ class. */
-+ PATFETCH (c);
-+
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
-+ {
-+# ifdef _LIBC
-+ if (__iswctype (__btowc (ch), wt))
-+ SET_LIST_BIT (ch);
-+# else
-+ if (iswctype (btowc (ch), wt))
-+ SET_LIST_BIT (ch);
-+# endif
-+
-+ if (translate && (is_upper || is_lower)
-+ && (ISUPPER (ch) || ISLOWER (ch)))
-+ SET_LIST_BIT (ch);
-+ }
-+
-+ had_char_class = true;
-+# else
-+ int ch;
-+ boolean is_alnum = STREQ (str, "alnum");
-+ boolean is_alpha = STREQ (str, "alpha");
-+ boolean is_blank = STREQ (str, "blank");
-+ boolean is_cntrl = STREQ (str, "cntrl");
-+ boolean is_digit = STREQ (str, "digit");
-+ boolean is_graph = STREQ (str, "graph");
-+ boolean is_lower = STREQ (str, "lower");
-+ boolean is_print = STREQ (str, "print");
-+ boolean is_punct = STREQ (str, "punct");
-+ boolean is_space = STREQ (str, "space");
-+ boolean is_upper = STREQ (str, "upper");
-+ boolean is_xdigit = STREQ (str, "xdigit");
-+
-+ if (!IS_CHAR_CLASS (str))
-+ FREE_STACK_RETURN (REG_ECTYPE);
-+
-+ /* Throw away the ] at the end of the character
-+ class. */
-+ PATFETCH (c);
-+
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
-+ {
-+ /* This was split into 3 if's to
-+ avoid an arbitrary limit in some compiler. */
-+ if ( (is_alnum && ISALNUM (ch))
-+ || (is_alpha && ISALPHA (ch))
-+ || (is_blank && ISBLANK (ch))
-+ || (is_cntrl && ISCNTRL (ch)))
-+ SET_LIST_BIT (ch);
-+ if ( (is_digit && ISDIGIT (ch))
-+ || (is_graph && ISGRAPH (ch))
-+ || (is_lower && ISLOWER (ch))
-+ || (is_print && ISPRINT (ch)))
-+ SET_LIST_BIT (ch);
-+ if ( (is_punct && ISPUNCT (ch))
-+ || (is_space && ISSPACE (ch))
-+ || (is_upper && ISUPPER (ch))
-+ || (is_xdigit && ISXDIGIT (ch)))
-+ SET_LIST_BIT (ch);
-+ if ( translate && (is_upper || is_lower)
-+ && (ISUPPER (ch) || ISLOWER (ch)))
-+ SET_LIST_BIT (ch);
-+ }
-+ had_char_class = true;
-+# endif /* libc || wctype.h */
-+ }
-+ else
-+ {
-+ c1++;
-+ while (c1--)
-+ PATUNFETCH;
-+ SET_LIST_BIT ('[');
-+ SET_LIST_BIT (':');
-+ range_start = ':';
-+ had_char_class = false;
-+ }
-+ }
-+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '=')
-+ {
-+ unsigned char str[MB_LEN_MAX + 1];
-+# ifdef _LIBC
-+ uint32_t nrules =
-+ _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-+# endif
-+
-+ PATFETCH (c);
-+ c1 = 0;
-+
-+ /* If pattern is `[[='. */
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ for (;;)
-+ {
-+ PATFETCH (c);
-+ if ((c == '=' && *p == ']') || p == pend)
-+ break;
-+ if (c1 < MB_LEN_MAX)
-+ str[c1++] = c;
-+ else
-+ /* This is in any case an invalid class name. */
-+ str[0] = '\0';
-+ }
-+ str[c1] = '\0';
-+
-+ if (c == '=' && *p == ']' && str[0] != '\0')
-+ {
-+ /* If we have no collation data we use the default
-+ collation in which each character is in a class
-+ by itself. It also means that ASCII is the
-+ character set and therefore we cannot have character
-+ with more than one byte in the multibyte
-+ representation. */
-+# ifdef _LIBC
-+ if (nrules == 0)
-+# endif
-+ {
-+ if (c1 != 1)
-+ FREE_STACK_RETURN (REG_ECOLLATE);
-+
-+ /* Throw away the ] at the end of the equivalence
-+ class. */
-+ PATFETCH (c);
-+
-+ /* Set the bit for the character. */
-+ SET_LIST_BIT (str[0]);
-+ }
-+# ifdef _LIBC
-+ else
-+ {
-+ /* Try to match the byte sequence in `str' against
-+ those known to the collate implementation.
-+ First find out whether the bytes in `str' are
-+ actually from exactly one character. */
-+ const int32_t *table;
-+ const unsigned char *weights;
-+ const unsigned char *extra;
-+ const int32_t *indirect;
-+ int32_t idx;
-+ const unsigned char *cp = str;
-+ int ch;
-+
-+ 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);
-+ idx = FINDIDX (table, indirect, extra, &cp, 1);
-+ if (idx == 0 || cp < str + c1)
-+ /* This is no valid character. */
-+ FREE_STACK_RETURN (REG_ECOLLATE);
-+
-+ /* Throw away the ] at the end of the equivalence
-+ class. */
-+ PATFETCH (c);
-+
-+ /* Now we have to go throught the whole table
-+ and find all characters which have the same
-+ first level weight.
-+
-+ XXX Note that this is not entirely correct.
-+ we would have to match multibyte sequences
-+ but this is not possible with the current
-+ implementation. */
-+ for (ch = 1; ch < 256; ++ch)
-+ /* XXX This test would have to be changed if we
-+ would allow matching multibyte sequences. */
-+ if (table[ch] > 0)
-+ {
-+ int32_t idx2 = table[ch];
-+ size_t len = weights[idx2];
-+
-+ /* Test whether the lenghts match. */
-+ if (weights[idx] == len)
-+ {
-+ /* They do. New compare the bytes of
-+ the weight. */
-+ size_t cnt = 0;
-+
-+ while (cnt < len
-+ && (weights[idx + 1 + cnt]
-+ == weights[idx2 + 1 + cnt]))
-+ ++cnt;
-+
-+ if (cnt == len)
-+ /* They match. Mark the character as
-+ acceptable. */
-+ SET_LIST_BIT (ch);
-+ }
-+ }
-+ }
-+# endif
-+ had_char_class = true;
-+ }
-+ else
-+ {
-+ c1++;
-+ while (c1--)
-+ PATUNFETCH;
-+ SET_LIST_BIT ('[');
-+ SET_LIST_BIT ('=');
-+ range_start = '=';
-+ had_char_class = false;
-+ }
-+ }
-+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '.')
-+ {
-+ unsigned char str[128]; /* Should be large enough. */
-+# ifdef _LIBC
-+ uint32_t nrules =
-+ _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-+# endif
-+
-+ PATFETCH (c);
-+ c1 = 0;
-+
-+ /* If pattern is `[[.'. */
-+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-+
-+ for (;;)
-+ {
-+ PATFETCH (c);
-+ if ((c == '.' && *p == ']') || p == pend)
-+ break;
-+ if (c1 < sizeof (str))
-+ str[c1++] = c;
-+ else
-+ /* This is in any case an invalid class name. */
-+ str[0] = '\0';
-+ }
-+ str[c1] = '\0';
-+
-+ if (c == '.' && *p == ']' && str[0] != '\0')
-+ {
-+ /* If we have no collation data we use the default
-+ collation in which each character is the name
-+ for its own class which contains only the one
-+ character. It also means that ASCII is the
-+ character set and therefore we cannot have character
-+ with more than one byte in the multibyte
-+ representation. */
-+# ifdef _LIBC
-+ if (nrules == 0)
-+# endif
-+ {
-+ if (c1 != 1)
-+ FREE_STACK_RETURN (REG_ECOLLATE);
-+
-+ /* Throw away the ] at the end of the equivalence
-+ class. */
-+ PATFETCH (c);
-+
-+ /* Set the bit for the character. */
-+ SET_LIST_BIT (str[0]);
-+ range_start = ((const unsigned char *) str)[0];
-+ }
-+# ifdef _LIBC
-+ else
-+ {
-+ /* Try to match the byte sequence in `str' against
-+ those known to the collate implementation.
-+ First find out whether the bytes in `str' are
-+ actually from exactly one character. */
-+ int32_t table_size;
-+ const int32_t *symb_table;
-+ const unsigned char *extra;
-+ int32_t idx;
-+ int32_t elem;
-+ int32_t second;
-+ int32_t hash;
-+
-+ 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 ((const char *) str, c1);
-+
-+ idx = 0;
-+ elem = hash % table_size;
-+ second = hash % (table_size - 2);
-+ while (symb_table[2 * elem] != 0)
-+ {
-+ /* 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;
-+ }
-+
-+ if (symb_table[2 * elem] == 0)
-+ /* This is no valid character. */
-+ FREE_STACK_RETURN (REG_ECOLLATE);
-+
-+ /* Throw away the ] at the end of the equivalence
-+ class. */
-+ PATFETCH (c);
-+
-+ /* Now add the multibyte character(s) we found
-+ to the accept list.
-+
-+ XXX Note that this is not entirely correct.
-+ we would have to match multibyte sequences
-+ but this is not possible with the current
-+ implementation. Also, we have to match
-+ collating symbols, which expand to more than
-+ one file, as a whole and not allow the
-+ individual bytes. */
-+ c1 = extra[idx++];
-+ if (c1 == 1)
-+ range_start = extra[idx];
-+ while (c1-- > 0)
-+ {
-+ SET_LIST_BIT (extra[idx]);
-+ ++idx;
-+ }
-+ }
-+# endif
-+ had_char_class = false;
-+ }
-+ else
-+ {
-+ c1++;
-+ while (c1--)
-+ PATUNFETCH;
-+ SET_LIST_BIT ('[');
-+ SET_LIST_BIT ('.');
-+ range_start = '.';
-+ had_char_class = false;
-+ }
-+ }
-+ else
-+ {
-+ had_char_class = false;
-+ SET_LIST_BIT (c);
-+ range_start = c;
-+ }
-+ }
-+
-+ /* Discard any (non)matching list bytes that are all 0 at the
-+ end of the map. Decrease the map-length byte too. */
-+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
-+ b[-1]--;
-+ b += b[-1];
-+#endif /* WCHAR */
-+ }
-+ break;
-+
-+
-+ case '(':
-+ if (syntax & RE_NO_BK_PARENS)
-+ goto handle_open;
-+ else
-+ goto normal_char;
-+
-+
-+ case ')':
-+ if (syntax & RE_NO_BK_PARENS)
-+ goto handle_close;
-+ else
-+ goto normal_char;
-+
-+
-+ case '\n':
-+ if (syntax & RE_NEWLINE_ALT)
-+ goto handle_alt;
-+ else
-+ goto normal_char;
-+
-+
-+ case '|':
-+ if (syntax & RE_NO_BK_VBAR)
-+ goto handle_alt;
-+ else
-+ goto normal_char;
-+
-+
-+ case '{':
-+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
-+ goto handle_interval;
-+ else
-+ goto normal_char;
-+
-+
-+ case '\\':
-+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
-+
-+ /* Do not translate the character after the \, so that we can
-+ distinguish, e.g., \B from \b, even if we normally would
-+ translate, e.g., B to b. */
-+ PATFETCH_RAW (c);
-+
-+ switch (c)
-+ {
-+ case '(':
-+ if (syntax & RE_NO_BK_PARENS)
-+ goto normal_backslash;
-+
-+ handle_open:
-+ bufp->re_nsub++;
-+ regnum++;
-+
-+ if (COMPILE_STACK_FULL)
-+ {
-+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
-+ compile_stack_elt_t);
-+ if (compile_stack.stack == NULL) return REG_ESPACE;
-+
-+ compile_stack.size <<= 1;
-+ }
-+
-+ /* These are the values to restore when we hit end of this
-+ group. They are all relative offsets, so that if the
-+ whole pattern moves because of realloc, they will still
-+ be valid. */
-+ COMPILE_STACK_TOP.begalt_offset = begalt - COMPILED_BUFFER_VAR;
-+ COMPILE_STACK_TOP.fixup_alt_jump
-+ = fixup_alt_jump ? fixup_alt_jump - COMPILED_BUFFER_VAR + 1 : 0;
-+ COMPILE_STACK_TOP.laststart_offset = b - COMPILED_BUFFER_VAR;
-+ COMPILE_STACK_TOP.regnum = regnum;
-+
-+ /* We will eventually replace the 0 with the number of
-+ groups inner to this one. But do not push a
-+ start_memory for groups beyond the last one we can
-+ represent in the compiled pattern. */
-+ if (regnum <= MAX_REGNUM)
-+ {
-+ COMPILE_STACK_TOP.inner_group_offset = b
-+ - COMPILED_BUFFER_VAR + 2;
-+ BUF_PUSH_3 (start_memory, regnum, 0);
-+ }
-+
-+ compile_stack.avail++;
-+
-+ fixup_alt_jump = 0;
-+ laststart = 0;
-+ begalt = b;
-+ /* If we've reached MAX_REGNUM groups, then this open
-+ won't actually generate any code, so we'll have to
-+ clear pending_exact explicitly. */
-+ pending_exact = 0;
-+ break;
-+
-+
-+ case ')':
-+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
-+
-+ if (COMPILE_STACK_EMPTY)
-+ {
-+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
-+ goto normal_backslash;
-+ else
-+ FREE_STACK_RETURN (REG_ERPAREN);
-+ }
-+
-+ handle_close:
-+ if (fixup_alt_jump)
-+ { /* Push a dummy failure point at the end of the
-+ alternative for a possible future
-+ `pop_failure_jump' to pop. See comments at
-+ `push_dummy_failure' in `re_match_2'. */
-+ BUF_PUSH (push_dummy_failure);
-+
-+ /* We allocated space for this jump when we assigned
-+ to `fixup_alt_jump', in the `handle_alt' case below. */
-+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
-+ }
-+
-+ /* See similar code for backslashed left paren above. */
-+ if (COMPILE_STACK_EMPTY)
-+ {
-+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
-+ goto normal_char;
-+ else
-+ FREE_STACK_RETURN (REG_ERPAREN);
-+ }
-+
-+ /* Since we just checked for an empty stack above, this
-+ ``can't happen''. */
-+ assert (compile_stack.avail != 0);
-+ {
-+ /* We don't just want to restore into `regnum', because
-+ later groups should continue to be numbered higher,
-+ as in `(ab)c(de)' -- the second group is #2. */
-+ regnum_t this_group_regnum;
-+
-+ compile_stack.avail--;
-+ begalt = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.begalt_offset;
-+ fixup_alt_jump
-+ = COMPILE_STACK_TOP.fixup_alt_jump
-+ ? COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.fixup_alt_jump - 1
-+ : 0;
-+ laststart = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.laststart_offset;
-+ this_group_regnum = COMPILE_STACK_TOP.regnum;
-+ /* If we've reached MAX_REGNUM groups, then this open
-+ won't actually generate any code, so we'll have to
-+ clear pending_exact explicitly. */
-+ pending_exact = 0;
-+
-+ /* We're at the end of the group, so now we know how many
-+ groups were inside this one. */
-+ if (this_group_regnum <= MAX_REGNUM)
-+ {
-+ UCHAR_T *inner_group_loc
-+ = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.inner_group_offset;
-+
-+ *inner_group_loc = regnum - this_group_regnum;
-+ BUF_PUSH_3 (stop_memory, this_group_regnum,
-+ regnum - this_group_regnum);
-+ }
-+ }
-+ break;
-+
-+
-+ case '|': /* `\|'. */
-+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
-+ goto normal_backslash;
-+ handle_alt:
-+ if (syntax & RE_LIMITED_OPS)
-+ goto normal_char;
-+
-+ /* Insert before the previous alternative a jump which
-+ jumps to this alternative if the former fails. */
-+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
-+ INSERT_JUMP (on_failure_jump, begalt,
-+ b + 2 + 2 * OFFSET_ADDRESS_SIZE);
-+ pending_exact = 0;
-+ b += 1 + OFFSET_ADDRESS_SIZE;
-+
-+ /* The alternative before this one has a jump after it
-+ which gets executed if it gets matched. Adjust that
-+ jump so it will jump to this alternative's analogous
-+ jump (put in below, which in turn will jump to the next
-+ (if any) alternative's such jump, etc.). The last such
-+ jump jumps to the correct final destination. A picture:
-+ _____ _____
-+ | | | |
-+ | v | v
-+ a | b | c
-+
-+ If we are at `b', then fixup_alt_jump right now points to a
-+ three-byte space after `a'. We'll put in the jump, set
-+ fixup_alt_jump to right after `b', and leave behind three
-+ bytes which we'll fill in when we get to after `c'. */
-+
-+ if (fixup_alt_jump)
-+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
-+
-+ /* Mark and leave space for a jump after this alternative,
-+ to be filled in later either by next alternative or
-+ when know we're at the end of a series of alternatives. */
-+ fixup_alt_jump = b;
-+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
-+ b += 1 + OFFSET_ADDRESS_SIZE;
-+
-+ laststart = 0;
-+ begalt = b;
-+ break;
-+
-+
-+ case '{':
-+ /* If \{ is a literal. */
-+ if (!(syntax & RE_INTERVALS)
-+ /* If we're at `\{' and it's not the open-interval
-+ operator. */
-+ || (syntax & RE_NO_BK_BRACES))
-+ goto normal_backslash;
-+
-+ handle_interval:
-+ {
-+ /* If got here, then the syntax allows intervals. */
-+
-+ /* At least (most) this many matches must be made. */
-+ int lower_bound = -1, upper_bound = -1;
-+
-+ /* Place in the uncompiled pattern (i.e., just after
-+ the '{') to go back to if the interval is invalid. */
-+ const CHAR_T *beg_interval = p;
-+
-+ if (p == pend)
-+ goto invalid_interval;
-+
-+ GET_UNSIGNED_NUMBER (lower_bound);
-+
-+ if (c == ',')
-+ {
-+ GET_UNSIGNED_NUMBER (upper_bound);
-+ if (upper_bound < 0)
-+ upper_bound = RE_DUP_MAX;
-+ }
-+ else
-+ /* Interval such as `{1}' => match exactly once. */
-+ upper_bound = lower_bound;
-+
-+ if (! (0 <= lower_bound && lower_bound <= upper_bound))
-+ goto invalid_interval;
-+
-+ if (!(syntax & RE_NO_BK_BRACES))
-+ {
-+ if (c != '\\' || p == pend)
-+ goto invalid_interval;
-+ PATFETCH (c);
-+ }
-+
-+ if (c != '}')
-+ goto invalid_interval;
-+
-+ /* If it's invalid to have no preceding re. */
-+ if (!laststart)
-+ {
-+ if (syntax & RE_CONTEXT_INVALID_OPS
-+ && !(syntax & RE_INVALID_INTERVAL_ORD))
-+ FREE_STACK_RETURN (REG_BADRPT);
-+ else if (syntax & RE_CONTEXT_INDEP_OPS)
-+ laststart = b;
-+ else
-+ goto unfetch_interval;
-+ }
-+
-+ /* We just parsed a valid interval. */
-+
-+ if (RE_DUP_MAX < upper_bound)
-+ FREE_STACK_RETURN (REG_BADBR);
-+
-+ /* If the upper bound is zero, don't want to succeed at
-+ all; jump from `laststart' to `b + 3', which will be
-+ the end of the buffer after we insert the jump. */
-+ /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE'
-+ instead of 'b + 3'. */
-+ if (upper_bound == 0)
-+ {
-+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
-+ INSERT_JUMP (jump, laststart, b + 1
-+ + OFFSET_ADDRESS_SIZE);
-+ b += 1 + OFFSET_ADDRESS_SIZE;
-+ }
-+
-+ /* Otherwise, we have a nontrivial interval. When
-+ we're all done, the pattern will look like:
-+ set_number_at <jump count> <upper bound>
-+ set_number_at <succeed_n count> <lower bound>
-+ succeed_n <after jump addr> <succeed_n count>
-+ <body of loop>
-+ jump_n <succeed_n addr> <jump count>
-+ (The upper bound and `jump_n' are omitted if
-+ `upper_bound' is 1, though.) */
-+ else
-+ { /* If the upper bound is > 1, we need to insert
-+ more at the end of the loop. */
-+ unsigned nbytes = 2 + 4 * OFFSET_ADDRESS_SIZE +
-+ (upper_bound > 1) * (2 + 4 * OFFSET_ADDRESS_SIZE);
-+
-+ GET_BUFFER_SPACE (nbytes);
-+
-+ /* Initialize lower bound of the `succeed_n', even
-+ though it will be set during matching by its
-+ attendant `set_number_at' (inserted next),
-+ because `re_compile_fastmap' needs to know.
-+ Jump to the `jump_n' we might insert below. */
-+ INSERT_JUMP2 (succeed_n, laststart,
-+ b + 1 + 2 * OFFSET_ADDRESS_SIZE
-+ + (upper_bound > 1) * (1 + 2 * OFFSET_ADDRESS_SIZE)
-+ , lower_bound);
-+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
-+
-+ /* Code to initialize the lower bound. Insert
-+ before the `succeed_n'. The `5' is the last two
-+ bytes of this `set_number_at', plus 3 bytes of
-+ the following `succeed_n'. */
-+ /* ifdef WCHAR, The '1+2*OFFSET_ADDRESS_SIZE'
-+ is the 'set_number_at', plus '1+OFFSET_ADDRESS_SIZE'
-+ of the following `succeed_n'. */
-+ PREFIX(insert_op2) (set_number_at, laststart, 1
-+ + 2 * OFFSET_ADDRESS_SIZE, lower_bound, b);
-+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
-+
-+ if (upper_bound > 1)
-+ { /* More than one repetition is allowed, so
-+ append a backward jump to the `succeed_n'
-+ that starts this interval.
-+
-+ When we've reached this during matching,
-+ we'll have matched the interval once, so
-+ jump back only `upper_bound - 1' times. */
-+ STORE_JUMP2 (jump_n, b, laststart
-+ + 2 * OFFSET_ADDRESS_SIZE + 1,
-+ upper_bound - 1);
-+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
-+
-+ /* The location we want to set is the second
-+ parameter of the `jump_n'; that is `b-2' as
-+ an absolute address. `laststart' will be
-+ the `set_number_at' we're about to insert;
-+ `laststart+3' the number to set, the source
-+ for the relative address. But we are
-+ inserting into the middle of the pattern --
-+ so everything is getting moved up by 5.
-+ Conclusion: (b - 2) - (laststart + 3) + 5,
-+ i.e., b - laststart.
-+
-+ We insert this at the beginning of the loop
-+ so that if we fail during matching, we'll
-+ reinitialize the bounds. */
-+ PREFIX(insert_op2) (set_number_at, laststart,
-+ b - laststart,
-+ upper_bound - 1, b);
-+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
-+ }
-+ }
-+ pending_exact = 0;
-+ break;
-+
-+ invalid_interval:
-+ if (!(syntax & RE_INVALID_INTERVAL_ORD))
-+ FREE_STACK_RETURN (p == pend ? REG_EBRACE : REG_BADBR);
-+ unfetch_interval:
-+ /* Match the characters as literals. */
-+ p = beg_interval;
-+ c = '{';
-+ if (syntax & RE_NO_BK_BRACES)
-+ goto normal_char;
-+ else
-+ goto normal_backslash;
-+ }
-+
-+#ifdef emacs
-+ /* There is no way to specify the before_dot and after_dot
-+ operators. rms says this is ok. --karl */
-+ case '=':
-+ BUF_PUSH (at_dot);
-+ break;
-+
-+ case 's':
-+ laststart = b;
-+ PATFETCH (c);
-+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
-+ break;
-+
-+ case 'S':
-+ laststart = b;
-+ PATFETCH (c);
-+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
-+ break;
-+#endif /* emacs */
-+
-+
-+ case 'w':
-+ if (syntax & RE_NO_GNU_OPS)
-+ goto normal_char;
-+ laststart = b;
-+ BUF_PUSH (wordchar);
-+ break;
-+
-+
-+ case 'W':
-+ if (syntax & RE_NO_GNU_OPS)
-+ goto normal_char;
-+ laststart = b;
-+ BUF_PUSH (notwordchar);
-+ break;
-+
-+
-+ case '<':
-+ if (syntax & RE_NO_GNU_OPS)
-+ goto normal_char;
-+ BUF_PUSH (wordbeg);
-+ break;
-+
-+ case '>':
-+ if (syntax & RE_NO_GNU_OPS)
-+ goto normal_char;
-+ BUF_PUSH (wordend);
-+ break;
-+
-+ case 'b':
-+ if (syntax & RE_NO_GNU_OPS)
-+ goto normal_char;
-+ BUF_PUSH (wordbound);
-+ break;
-+
-+ case 'B':
-+ if (syntax & RE_NO_GNU_OPS)
-+ goto normal_char;
-+ BUF_PUSH (notwordbound);
-+ break;
-+
-+ case '`':
-+ if (syntax & RE_NO_GNU_OPS)
-+ goto normal_char;
-+ BUF_PUSH (begbuf);
-+ break;
-+
-+ case '\'':
-+ if (syntax & RE_NO_GNU_OPS)
-+ goto normal_char;
-+ BUF_PUSH (endbuf);
-+ 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)
-+ goto normal_char;
-+
-+ c1 = c - '0';
-+
-+ if (c1 > regnum)
-+ FREE_STACK_RETURN (REG_ESUBREG);
-+
-+ /* Can't back reference to a subexpression if inside of it. */
-+ if (group_in_compile_stack (compile_stack, (regnum_t) c1))
-+ goto normal_char;
-+
-+ laststart = b;
-+ BUF_PUSH_2 (duplicate, c1);
-+ break;
-+
-+
-+ case '+':
-+ case '?':
-+ if (syntax & RE_BK_PLUS_QM)
-+ goto handle_plus;
-+ else
-+ goto normal_backslash;
-+
-+ default:
-+ normal_backslash:
-+ /* You might think it would be useful for \ to mean
-+ not to translate; but if we don't translate it
-+ it will never match anything. */
-+ c = TRANSLATE (c);
-+ goto normal_char;
-+ }
-+ break;
-+
-+
-+ default:
-+ /* Expects the character in `c'. */
-+ normal_char:
-+ /* If no exactn currently being built. */
-+ if (!pending_exact
-+#ifdef WCHAR
-+ /* If last exactn handle binary(or character) and
-+ new exactn handle character(or binary). */
-+ || is_exactn_bin != is_binary[p - 1 - pattern]
-+#endif /* WCHAR */
-+
-+ /* If last exactn not at current position. */
-+ || pending_exact + *pending_exact + 1 != b
-+
-+ /* We have only one byte following the exactn for the count. */
-+ || *pending_exact == (1 << BYTEWIDTH) - 1
-+
-+ /* If followed by a repetition operator. */
-+ || *p == '*' || *p == '^'
-+ || ((syntax & RE_BK_PLUS_QM)
-+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
-+ : (*p == '+' || *p == '?'))
-+ || ((syntax & RE_INTERVALS)
-+ && ((syntax & RE_NO_BK_BRACES)
-+ ? *p == '{'
-+ : (p[0] == '\\' && p[1] == '{'))))
-+ {
-+ /* Start building a new exactn. */
-+
-+ laststart = b;
-+
-+#ifdef WCHAR
-+ /* Is this exactn binary data or character? */
-+ is_exactn_bin = is_binary[p - 1 - pattern];
-+ if (is_exactn_bin)
-+ BUF_PUSH_2 (exactn_bin, 0);
-+ else
-+ BUF_PUSH_2 (exactn, 0);
-+#else
-+ BUF_PUSH_2 (exactn, 0);
-+#endif /* WCHAR */
-+ pending_exact = b - 1;
-+ }
-+
-+ BUF_PUSH (c);
-+ (*pending_exact)++;
-+ break;
-+ } /* switch (c) */
-+ } /* while p != pend */
-+
-+
-+ /* Through the pattern now. */
-+
-+ if (fixup_alt_jump)
-+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
-+
-+ if (!COMPILE_STACK_EMPTY)
-+ FREE_STACK_RETURN (REG_EPAREN);
-+
-+ /* If we don't want backtracking, force success
-+ the first time we reach the end of the compiled pattern. */
-+ if (syntax & RE_NO_POSIX_BACKTRACKING)
-+ BUF_PUSH (succeed);
-+
-+#ifdef WCHAR
-+ free (pattern);
-+ free (mbs_offset);
-+ free (is_binary);
-+#endif
-+ free (compile_stack.stack);
-+
-+ /* We have succeeded; set the length of the buffer. */
-+#ifdef WCHAR
-+ bufp->used = (uintptr_t) b - (uintptr_t) COMPILED_BUFFER_VAR;
-+#else
-+ bufp->used = b - bufp->buffer;
-+#endif
-+
-+#ifdef DEBUG
-+ if (debug)
-+ {
-+ DEBUG_PRINT1 ("\nCompiled pattern: \n");
-+ PREFIX(print_compiled_pattern) (bufp);
-+ }
-+#endif /* DEBUG */
-+
-+#ifndef MATCH_MAY_ALLOCATE
-+ /* Initialize the failure stack to the largest possible stack. This
-+ isn't necessary unless we're trying to avoid calling alloca in
-+ the search and match routines. */
-+ {
-+ int num_regs = bufp->re_nsub + 1;
-+
-+ /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
-+ is strictly greater than re_max_failures, the largest possible stack
-+ is 2 * re_max_failures failure points. */
-+ if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
-+ {
-+ fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
-+
-+# ifdef emacs
-+ if (! fail_stack.stack)
-+ fail_stack.stack
-+ = (PREFIX(fail_stack_elt_t) *) xmalloc (fail_stack.size
-+ * sizeof (PREFIX(fail_stack_elt_t)));
-+ else
-+ fail_stack.stack
-+ = (PREFIX(fail_stack_elt_t) *) xrealloc (fail_stack.stack,
-+ (fail_stack.size
-+ * sizeof (PREFIX(fail_stack_elt_t))));
-+# else /* not emacs */
-+ if (! fail_stack.stack)
-+ fail_stack.stack
-+ = (PREFIX(fail_stack_elt_t) *) malloc (fail_stack.size
-+ * sizeof (PREFIX(fail_stack_elt_t)));
-+ else
-+ fail_stack.stack
-+ = (PREFIX(fail_stack_elt_t) *) realloc (fail_stack.stack,
-+ (fail_stack.size
-+ * sizeof (PREFIX(fail_stack_elt_t))));
-+# endif /* not emacs */
-+ }
-+
-+ PREFIX(regex_grow_registers) (num_regs);
-+ }
-+#endif /* not MATCH_MAY_ALLOCATE */
-+
-+ return REG_NOERROR;
-+} /* regex_compile */
-+
-+/* Subroutines for `regex_compile'. */
-+
-+/* Store OP at LOC followed by two-byte integer parameter ARG. */
-+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
-+
-+static void
-+PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg)
-+{
-+ *loc = (UCHAR_T) op;
-+ STORE_NUMBER (loc + 1, arg);
-+}
-+
-+
-+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
-+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
-+
-+static void
-+PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, int arg2)
-+{
-+ *loc = (UCHAR_T) op;
-+ STORE_NUMBER (loc + 1, arg1);
-+ STORE_NUMBER (loc + 1 + OFFSET_ADDRESS_SIZE, arg2);
-+}
-+
-+
-+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
-+ for OP followed by two-byte integer parameter ARG. */
-+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
-+
-+static void
-+PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, int arg, UCHAR_T *end)
-+{
-+ register UCHAR_T *pfrom = end;
-+ register UCHAR_T *pto = end + 1 + OFFSET_ADDRESS_SIZE;
-+
-+ while (pfrom != loc)
-+ *--pto = *--pfrom;
-+
-+ PREFIX(store_op1) (op, loc, arg);
-+}
-+
-+
-+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
-+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
-+
-+static void
-+PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, int arg1,
-+ int arg2, UCHAR_T *end)
-+{
-+ register UCHAR_T *pfrom = end;
-+ register UCHAR_T *pto = end + 1 + 2 * OFFSET_ADDRESS_SIZE;
-+
-+ while (pfrom != loc)
-+ *--pto = *--pfrom;
-+
-+ PREFIX(store_op2) (op, loc, arg1, arg2);
-+}
-+
-+
-+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
-+ after an alternative or a begin-subexpression. We assume there is at
-+ least one character before the ^. */
-+
-+static boolean
-+PREFIX(at_begline_loc_p) (const CHAR_T *pattern, const CHAR_T *p,
-+ reg_syntax_t syntax)
-+{
-+ const CHAR_T *prev = p - 2;
-+ boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
-+
-+ return
-+ /* After a subexpression? */
-+ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
-+ /* After an alternative? */
-+ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
-+}
-+
-+
-+/* The dual of at_begline_loc_p. This one is for $. We assume there is
-+ at least one character after the $, i.e., `P < PEND'. */
-+
-+static boolean
-+PREFIX(at_endline_loc_p) (const CHAR_T *p, const CHAR_T *pend,
-+ reg_syntax_t syntax)
-+{
-+ const CHAR_T *next = p;
-+ boolean next_backslash = *next == '\\';
-+ const CHAR_T *next_next = p + 1 < pend ? p + 1 : 0;
-+
-+ return
-+ /* Before a subexpression? */
-+ (syntax & RE_NO_BK_PARENS ? *next == ')'
-+ : next_backslash && next_next && *next_next == ')')
-+ /* Before an alternative? */
-+ || (syntax & RE_NO_BK_VBAR ? *next == '|'
-+ : next_backslash && next_next && *next_next == '|');
-+}
-+
-+#else /* not INSIDE_RECURSION */
-+
-+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
-+ false if it's not. */
-+
-+static boolean
-+group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum)
-+{
-+ int this_element;
-+
-+ for (this_element = compile_stack.avail - 1;
-+ this_element >= 0;
-+ this_element--)
-+ if (compile_stack.stack[this_element].regnum == regnum)
-+ return true;
-+
-+ return false;
-+}
-+#endif /* not INSIDE_RECURSION */
-+
-+#ifdef INSIDE_RECURSION
-+
-+#ifdef WCHAR
-+/* This insert space, which size is "num", into the pattern at "loc".
-+ "end" must point the end of the allocated buffer. */
-+static void
-+insert_space (int num, CHAR_T *loc, CHAR_T *end)
-+{
-+ register CHAR_T *pto = end;
-+ register CHAR_T *pfrom = end - num;
-+
-+ while (pfrom >= loc)
-+ *pto-- = *pfrom--;
-+}
-+#endif /* WCHAR */
-+
-+#ifdef WCHAR
-+static reg_errcode_t
-+wcs_compile_range (CHAR_T range_start_char, const CHAR_T **p_ptr,
-+ const CHAR_T *pend, RE_TRANSLATE_TYPE translate,
-+ reg_syntax_t syntax, CHAR_T *b, CHAR_T *char_set)
-+{
-+ const CHAR_T *p = *p_ptr;
-+ CHAR_T range_start, range_end;
-+ reg_errcode_t ret;
-+# ifdef _LIBC
-+ uint32_t nrules;
-+ uint32_t start_val, end_val;
-+# endif
-+ if (p == pend)
-+ return REG_ERANGE;
-+
-+# ifdef _LIBC
-+ nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-+ if (nrules != 0)
-+ {
-+ const char *collseq = (const char *) _NL_CURRENT(LC_COLLATE,
-+ _NL_COLLATE_COLLSEQWC);
-+ const unsigned char *extra = (const unsigned char *)
-+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
-+
-+ if (range_start_char < -1)
-+ {
-+ /* range_start is a collating symbol. */
-+ int32_t *wextra;
-+ /* Retreive the index and get collation sequence value. */
-+ wextra = (int32_t*)(extra + char_set[-range_start_char]);
-+ start_val = wextra[1 + *wextra];
-+ }
-+ else
-+ start_val = collseq_table_lookup(collseq, TRANSLATE(range_start_char));
-+
-+ end_val = collseq_table_lookup (collseq, TRANSLATE (p[0]));
-+
-+ /* Report an error if the range is empty and the syntax prohibits
-+ this. */
-+ ret = ((syntax & RE_NO_EMPTY_RANGES)
-+ && (start_val > end_val))? REG_ERANGE : REG_NOERROR;
-+
-+ /* Insert space to the end of the char_ranges. */
-+ insert_space(2, b - char_set[5] - 2, b - 1);
-+ *(b - char_set[5] - 2) = (wchar_t)start_val;
-+ *(b - char_set[5] - 1) = (wchar_t)end_val;
-+ char_set[4]++; /* ranges_index */
-+ }
-+ else
-+# endif
-+ {
-+ range_start = (range_start_char >= 0)? TRANSLATE (range_start_char):
-+ range_start_char;
-+ range_end = TRANSLATE (p[0]);
-+ /* Report an error if the range is empty and the syntax prohibits
-+ this. */
-+ ret = ((syntax & RE_NO_EMPTY_RANGES)
-+ && (range_start > range_end))? REG_ERANGE : REG_NOERROR;
-+
-+ /* Insert space to the end of the char_ranges. */
-+ insert_space(2, b - char_set[5] - 2, b - 1);
-+ *(b - char_set[5] - 2) = range_start;
-+ *(b - char_set[5] - 1) = range_end;
-+ char_set[4]++; /* ranges_index */
-+ }
-+ /* Have to increment the pointer into the pattern string, so the
-+ caller isn't still at the ending character. */
-+ (*p_ptr)++;
-+
-+ return ret;
-+}
-+#else /* BYTE */
-+/* Read the ending character of a range (in a bracket expression) from the
-+ uncompiled pattern *P_PTR (which ends at PEND). We assume the
-+ starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
-+ Then we set the translation of all bits between the starting and
-+ ending characters (inclusive) in the compiled pattern B.
-+
-+ Return an error code.
-+
-+ We use these short variable names so we can use the same macros as
-+ `regex_compile' itself. */
-+
-+static reg_errcode_t
-+byte_compile_range (unsigned int range_start_char, const char **p_ptr,
-+ const char *pend, RE_TRANSLATE_TYPE translate,
-+ reg_syntax_t syntax, unsigned char *b)
-+{
-+ unsigned this_char;
-+ const char *p = *p_ptr;
-+ reg_errcode_t ret;
-+# if _LIBC
-+ const unsigned char *collseq;
-+ unsigned int start_colseq;
-+ unsigned int end_colseq;
-+# else
-+ unsigned end_char;
-+# endif
-+
-+ if (p == pend)
-+ return REG_ERANGE;
-+
-+ /* Have to increment the pointer into the pattern string, so the
-+ caller isn't still at the ending character. */
-+ (*p_ptr)++;
-+
-+ /* Report an error if the range is empty and the syntax prohibits this. */
-+ ret = syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
-+
-+# if _LIBC
-+ collseq = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
-+ _NL_COLLATE_COLLSEQMB);
-+
-+ start_colseq = collseq[(unsigned char) TRANSLATE (range_start_char)];
-+ end_colseq = collseq[(unsigned char) TRANSLATE (p[0])];
-+ for (this_char = 0; this_char <= (unsigned char) -1; ++this_char)
-+ {
-+ unsigned int this_colseq = collseq[(unsigned char) TRANSLATE (this_char)];
-+
-+ if (start_colseq <= this_colseq && this_colseq <= end_colseq)
-+ {
-+ SET_LIST_BIT (TRANSLATE (this_char));
-+ ret = REG_NOERROR;
-+ }
-+ }
-+# else
-+ /* Here we see why `this_char' has to be larger than an `unsigned
-+ char' -- we would otherwise go into an infinite loop, since all
-+ characters <= 0xff. */
-+ range_start_char = TRANSLATE (range_start_char);
-+ /* TRANSLATE(p[0]) is casted to char (not unsigned char) in TRANSLATE,
-+ and some compilers cast it to int implicitly, so following for_loop
-+ may fall to (almost) infinite loop.
-+ e.g. If translate[p[0]] = 0xff, end_char may equals to 0xffffffff.
-+ To avoid this, we cast p[0] to unsigned int and truncate it. */
-+ end_char = ((unsigned)TRANSLATE(p[0]) & ((1 << BYTEWIDTH) - 1));
-+
-+ for (this_char = range_start_char; this_char <= end_char; ++this_char)
-+ {
-+ SET_LIST_BIT (TRANSLATE (this_char));
-+ ret = REG_NOERROR;
-+ }
-+# endif
-+
-+ return ret;
-+}
-+#endif /* WCHAR */
-+
-+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
-+ BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
-+ characters can start a string that matches the pattern. This fastmap
-+ is used by re_search to skip quickly over impossible starting points.
-+
-+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
-+ area as BUFP->fastmap.
-+
-+ We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
-+ the pattern buffer.
-+
-+ Returns 0 if we succeed, -2 if an internal error. */
-+
-+#ifdef WCHAR
-+/* local function for re_compile_fastmap.
-+ truncate wchar_t character to char. */
-+static unsigned char truncate_wchar (CHAR_T c);
-+
-+static unsigned char
-+truncate_wchar (CHAR_T c)
-+{
-+ unsigned char buf[MB_CUR_MAX];
-+ mbstate_t state;
-+ int retval;
-+ memset (&state, '\0', sizeof (state));
-+# ifdef _LIBC
-+ retval = __wcrtomb (buf, c, &state);
-+# else
-+ retval = wcrtomb (buf, c, &state);
-+# endif
-+ return retval > 0 ? buf[0] : (unsigned char) c;
-+}
-+#endif /* WCHAR */
-+
-+static int
-+PREFIX(re_compile_fastmap) (struct re_pattern_buffer *bufp)
-+{
-+ int j, k;
-+#ifdef MATCH_MAY_ALLOCATE
-+ PREFIX(fail_stack_type) fail_stack;
-+#endif
-+#ifndef REGEX_MALLOC
-+ char *destination;
-+#endif
-+
-+ register char *fastmap = bufp->fastmap;
-+
-+#ifdef WCHAR
-+ /* We need to cast pattern to (wchar_t*), because we casted this compiled
-+ pattern to (char*) in regex_compile. */
-+ UCHAR_T *pattern = (UCHAR_T*)bufp->buffer;
-+ register UCHAR_T *pend = (UCHAR_T*) (bufp->buffer + bufp->used);
-+#else /* BYTE */
-+ UCHAR_T *pattern = bufp->buffer;
-+ register UCHAR_T *pend = pattern + bufp->used;
-+#endif /* WCHAR */
-+ UCHAR_T *p = pattern;
-+
-+#ifdef REL_ALLOC
-+ /* This holds the pointer to the failure stack, when
-+ it is allocated relocatably. */
-+ fail_stack_elt_t *failure_stack_ptr;
-+#endif
-+
-+ /* Assume that each path through the pattern can be null until
-+ proven otherwise. We set this false at the bottom of switch
-+ statement, to which we get only if a particular path doesn't
-+ match the empty string. */
-+ boolean path_can_be_null = true;
-+
-+ /* We aren't doing a `succeed_n' to begin with. */
-+ boolean succeed_n_p = false;
-+
-+ assert (fastmap != NULL && p != NULL);
-+
-+ INIT_FAIL_STACK ();
-+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
-+ bufp->fastmap_accurate = 1; /* It will be when we're done. */
-+ bufp->can_be_null = 0;
-+
-+ while (1)
-+ {
-+ if (p == pend || *p == (UCHAR_T) succeed)
-+ {
-+ /* We have reached the (effective) end of pattern. */
-+ if (!FAIL_STACK_EMPTY ())
-+ {
-+ bufp->can_be_null |= path_can_be_null;
-+
-+ /* Reset for next path. */
-+ path_can_be_null = true;
-+
-+ p = fail_stack.stack[--fail_stack.avail].pointer;
-+
-+ continue;
-+ }
-+ else
-+ break;
-+ }
-+
-+ /* We should never be about to go beyond the end of the pattern. */
-+ assert (p < pend);
-+
-+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
-+ {
-+
-+ /* I guess the idea here is to simply not bother with a fastmap
-+ if a backreference is used, since it's too hard to figure out
-+ the fastmap for the corresponding group. Setting
-+ `can_be_null' stops `re_search_2' from using the fastmap, so
-+ that is all we do. */
-+ case duplicate:
-+ bufp->can_be_null = 1;
-+ goto done;
-+
-+
-+ /* Following are the cases which match a character. These end
-+ with `break'. */
-+
-+#ifdef WCHAR
-+ case exactn:
-+ fastmap[truncate_wchar(p[1])] = 1;
-+ break;
-+#else /* BYTE */
-+ case exactn:
-+ fastmap[p[1]] = 1;
-+ break;
-+#endif /* WCHAR */
-+#ifdef MBS_SUPPORT
-+ case exactn_bin:
-+ fastmap[p[1]] = 1;
-+ break;
-+#endif
-+
-+#ifdef WCHAR
-+ /* It is hard to distinguish fastmap from (multi byte) characters
-+ which depends on current locale. */
-+ case charset:
-+ case charset_not:
-+ case wordchar:
-+ case notwordchar:
-+ bufp->can_be_null = 1;
-+ goto done;
-+#else /* BYTE */
-+ case charset:
-+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
-+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
-+ fastmap[j] = 1;
-+ break;
-+
-+
-+ case charset_not:
-+ /* Chars beyond end of map must be allowed. */
-+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
-+ fastmap[j] = 1;
-+
-+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
-+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
-+ fastmap[j] = 1;
-+ break;
-+
-+
-+ case wordchar:
-+ for (j = 0; j < (1 << BYTEWIDTH); j++)
-+ if (SYNTAX (j) == Sword)
-+ fastmap[j] = 1;
-+ break;
-+
-+
-+ case notwordchar:
-+ for (j = 0; j < (1 << BYTEWIDTH); j++)
-+ if (SYNTAX (j) != Sword)
-+ fastmap[j] = 1;
-+ break;
-+#endif /* WCHAR */
-+
-+ case anychar:
-+ {
-+ int fastmap_newline = fastmap['\n'];
-+
-+ /* `.' matches anything ... */
-+ for (j = 0; j < (1 << BYTEWIDTH); j++)
-+ fastmap[j] = 1;
-+
-+ /* ... except perhaps newline. */
-+ if (!(bufp->syntax & RE_DOT_NEWLINE))
-+ fastmap['\n'] = fastmap_newline;
-+
-+ /* Return if we have already set `can_be_null'; if we have,
-+ then the fastmap is irrelevant. Something's wrong here. */
-+ else if (bufp->can_be_null)
-+ goto done;
-+
-+ /* Otherwise, have to check alternative paths. */
-+ break;
-+ }
-+
-+#ifdef emacs
-+ case syntaxspec:
-+ k = *p++;
-+ for (j = 0; j < (1 << BYTEWIDTH); j++)
-+ if (SYNTAX (j) == (enum syntaxcode) k)
-+ fastmap[j] = 1;
-+ break;
-+
-+
-+ case notsyntaxspec:
-+ k = *p++;
-+ for (j = 0; j < (1 << BYTEWIDTH); j++)
-+ if (SYNTAX (j) != (enum syntaxcode) k)
-+ fastmap[j] = 1;
-+ break;
-+
-+
-+ /* All cases after this match the empty string. These end with
-+ `continue'. */
-+
-+
-+ case before_dot:
-+ case at_dot:
-+ case after_dot:
-+ continue;
-+#endif /* emacs */
-+
-+
-+ case no_op:
-+ case begline:
-+ case endline:
-+ case begbuf:
-+ case endbuf:
-+ case wordbound:
-+ case notwordbound:
-+ case wordbeg:
-+ case wordend:
-+ case push_dummy_failure:
-+ continue;
-+
-+
-+ case jump_n:
-+ case pop_failure_jump:
-+ case maybe_pop_jump:
-+ case jump:
-+ case jump_past_alt:
-+ case dummy_failure_jump:
-+ EXTRACT_NUMBER_AND_INCR (j, p);
-+ p += j;
-+ if (j > 0)
-+ continue;
-+
-+ /* Jump backward implies we just went through the body of a
-+ loop and matched nothing. Opcode jumped to should be
-+ `on_failure_jump' or `succeed_n'. Just treat it like an
-+ ordinary jump. For a * loop, it has pushed its failure
-+ point already; if so, discard that as redundant. */
-+ if ((re_opcode_t) *p != on_failure_jump
-+ && (re_opcode_t) *p != succeed_n)
-+ continue;
-+
-+ p++;
-+ EXTRACT_NUMBER_AND_INCR (j, p);
-+ p += j;
-+
-+ /* If what's on the stack is where we are now, pop it. */
-+ if (!FAIL_STACK_EMPTY ()
-+ && fail_stack.stack[fail_stack.avail - 1].pointer == p)
-+ fail_stack.avail--;
-+
-+ continue;
-+
-+
-+ case on_failure_jump:
-+ case on_failure_keep_string_jump:
-+ handle_on_failure_jump:
-+ EXTRACT_NUMBER_AND_INCR (j, p);
-+
-+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
-+ end of the pattern. We don't want to push such a point,
-+ since when we restore it above, entering the switch will
-+ increment `p' past the end of the pattern. We don't need
-+ to push such a point since we obviously won't find any more
-+ fastmap entries beyond `pend'. Such a pattern can match
-+ the null string, though. */
-+ if (p + j < pend)
-+ {
-+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
-+ {
-+ RESET_FAIL_STACK ();
-+ return -2;
-+ }
-+ }
-+ else
-+ bufp->can_be_null = 1;
-+
-+ if (succeed_n_p)
-+ {
-+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
-+ succeed_n_p = false;
-+ }
-+
-+ continue;
-+
-+
-+ case succeed_n:
-+ /* Get to the number of times to succeed. */
-+ p += OFFSET_ADDRESS_SIZE;
-+
-+ /* Increment p past the n for when k != 0. */
-+ EXTRACT_NUMBER_AND_INCR (k, p);
-+ if (k == 0)
-+ {
-+ p -= 2 * OFFSET_ADDRESS_SIZE;
-+ succeed_n_p = true; /* Spaghetti code alert. */
-+ goto handle_on_failure_jump;
-+ }
-+ continue;
-+
-+
-+ case set_number_at:
-+ p += 2 * OFFSET_ADDRESS_SIZE;
-+ continue;
-+
-+
-+ case start_memory:
-+ case stop_memory:
-+ p += 2;
-+ continue;
-+
-+
-+ default:
-+ abort (); /* We have listed all the cases. */
-+ } /* switch *p++ */
-+
-+ /* Getting here means we have found the possible starting
-+ characters for one path of the pattern -- and that the empty
-+ string does not match. We need not follow this path further.
-+ Instead, look at the next alternative (remembered on the
-+ stack), or quit if no more. The test at the top of the loop
-+ does these things. */
-+ path_can_be_null = false;
-+ p = pend;
-+ } /* while p */
-+
-+ /* Set `can_be_null' for the last path (also the first path, if the
-+ pattern is empty). */
-+ bufp->can_be_null |= path_can_be_null;
-+
-+ done:
-+ RESET_FAIL_STACK ();
-+ return 0;
-+}
-+
-+#else /* not INSIDE_RECURSION */
-+
-+int
-+re_compile_fastmap (struct re_pattern_buffer *bufp)
-+{
-+# ifdef MBS_SUPPORT
-+ if (MB_CUR_MAX != 1)
-+ return wcs_re_compile_fastmap(bufp);
-+ else
-+# endif
-+ return byte_re_compile_fastmap(bufp);
-+} /* re_compile_fastmap */
-+#ifdef _LIBC
-+weak_alias (__re_compile_fastmap, re_compile_fastmap)
-+#endif
-+
-+
-+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
-+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
-+ this memory for recording register information. STARTS and ENDS
-+ must be allocated using the malloc library routine, and must each
-+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
-+
-+ If NUM_REGS == 0, then subsequent matches should allocate their own
-+ register data.
-+
-+ Unless this function is called, the first search or match using
-+ PATTERN_BUFFER will allocate its own register data, without
-+ freeing the old data. */
-+
-+void
-+re_set_registers (struct re_pattern_buffer *bufp,
-+ struct re_registers *regs, unsigned num_regs,
-+ regoff_t *starts, regoff_t *ends)
-+{
-+ if (num_regs)
-+ {
-+ bufp->regs_allocated = REGS_REALLOCATE;
-+ regs->num_regs = num_regs;
-+ regs->start = starts;
-+ regs->end = ends;
-+ }
-+ else
-+ {
-+ bufp->regs_allocated = REGS_UNALLOCATED;
-+ regs->num_regs = 0;
-+ regs->start = regs->end = (regoff_t *) 0;
-+ }
-+}
-+#ifdef _LIBC
-+weak_alias (__re_set_registers, re_set_registers)
-+#endif
-+
-+/* Searching routines. */
-+
-+/* Like re_search_2, below, but only one string is specified, and
-+ doesn't let you say where to stop matching. */
-+
-+int
-+re_search (struct re_pattern_buffer *bufp, const char *string, int size,
-+ int startpos, int range, struct re_registers *regs)
-+{
-+ return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
-+ regs, size);
-+}
-+#ifdef _LIBC
-+weak_alias (__re_search, re_search)
-+#endif
-+
-+
-+/* Using the compiled pattern in BUFP->buffer, first tries to match the
-+ virtual concatenation of STRING1 and STRING2, starting first at index
-+ STARTPOS, then at STARTPOS + 1, and so on.
-+
-+ STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
-+
-+ RANGE is how far to scan while trying to match. RANGE = 0 means try
-+ only at STARTPOS; in general, the last start tried is STARTPOS +
-+ RANGE.
-+
-+ In REGS, return the indices of the virtual concatenation of STRING1
-+ and STRING2 that matched the entire BUFP->buffer and its contained
-+ subexpressions.
-+
-+ Do not consider matching one past the index STOP in the virtual
-+ concatenation of STRING1 and STRING2.
-+
-+ We return either the position in the strings at which the match was
-+ found, -1 if no match, or -2 if error (such as failure
-+ stack overflow). */
-+
-+int
-+re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
-+ const char *string2, int size2, int startpos, int range,
-+ struct re_registers *regs, int stop)
-+{
-+# ifdef MBS_SUPPORT
-+ if (MB_CUR_MAX != 1)
-+ return wcs_re_search_2 (bufp, string1, size1, string2, size2, startpos,
-+ range, regs, stop);
-+ else
-+# endif
-+ return byte_re_search_2 (bufp, string1, size1, string2, size2, startpos,
-+ range, regs, stop);
-+} /* re_search_2 */
-+#ifdef _LIBC
-+weak_alias (__re_search_2, re_search_2)
-+#endif
-+
-+#endif /* not INSIDE_RECURSION */
-+
-+#ifdef INSIDE_RECURSION
-+
-+#ifdef MATCH_MAY_ALLOCATE
-+# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL
-+#else
-+# define FREE_VAR(var) if (var) free (var); var = NULL
-+#endif
-+
-+#ifdef WCHAR
-+# define MAX_ALLOCA_SIZE 2000
-+
-+# define FREE_WCS_BUFFERS() \
-+ do { \
-+ if (size1 > MAX_ALLOCA_SIZE) \
-+ { \
-+ free (wcs_string1); \
-+ free (mbs_offset1); \
-+ } \
-+ else \
-+ { \
-+ FREE_VAR (wcs_string1); \
-+ FREE_VAR (mbs_offset1); \
-+ } \
-+ if (size2 > MAX_ALLOCA_SIZE) \
-+ { \
-+ free (wcs_string2); \
-+ free (mbs_offset2); \
-+ } \
-+ else \
-+ { \
-+ FREE_VAR (wcs_string2); \
-+ FREE_VAR (mbs_offset2); \
-+ } \
-+ } while (0)
-+
-+#endif
-+
-+
-+static int
-+PREFIX(re_search_2) (struct re_pattern_buffer *bufp, const char *string1,
-+ int size1, const char *string2, int size2,
-+ int startpos, int range,
-+ struct re_registers *regs, int stop)
-+{
-+ int val;
-+ register char *fastmap = bufp->fastmap;
-+ register RE_TRANSLATE_TYPE translate = bufp->translate;
-+ int total_size = size1 + size2;
-+ int endpos = startpos + range;
-+#ifdef WCHAR
-+ /* We need wchar_t* buffers correspond to cstring1, cstring2. */
-+ wchar_t *wcs_string1 = NULL, *wcs_string2 = NULL;
-+ /* We need the size of wchar_t buffers correspond to csize1, csize2. */
-+ int wcs_size1 = 0, wcs_size2 = 0;
-+ /* offset buffer for optimizatoin. See convert_mbs_to_wc. */
-+ int *mbs_offset1 = NULL, *mbs_offset2 = NULL;
-+ /* They hold whether each wchar_t is binary data or not. */
-+ char *is_binary = NULL;
-+#endif /* WCHAR */
-+
-+ /* Check for out-of-range STARTPOS. */
-+ if (startpos < 0 || startpos > total_size)
-+ return -1;
-+
-+ /* Fix up RANGE if it might eventually take us outside
-+ the virtual concatenation of STRING1 and STRING2.
-+ Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */
-+ if (endpos < 0)
-+ range = 0 - startpos;
-+ else if (endpos > total_size)
-+ range = total_size - startpos;
-+
-+ /* If the search isn't to be a backwards one, don't waste time in a
-+ search for a pattern that must be anchored. */
-+ if (bufp->used > 0 && range > 0
-+ && ((re_opcode_t) bufp->buffer[0] == begbuf
-+ /* `begline' is like `begbuf' if it cannot match at newlines. */
-+ || ((re_opcode_t) bufp->buffer[0] == begline
-+ && !bufp->newline_anchor)))
-+ {
-+ if (startpos > 0)
-+ return -1;
-+ else
-+ range = 1;
-+ }
-+
-+#ifdef emacs
-+ /* In a forward search for something that starts with \=.
-+ don't keep searching past point. */
-+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
-+ {
-+ range = PT - startpos;
-+ if (range <= 0)
-+ return -1;
-+ }
-+#endif /* emacs */
-+
-+ /* Update the fastmap now if not correct already. */
-+ if (fastmap && !bufp->fastmap_accurate)
-+ if (re_compile_fastmap (bufp) == -2)
-+ return -2;
-+
-+#ifdef WCHAR
-+ /* Allocate wchar_t array for wcs_string1 and wcs_string2 and
-+ fill them with converted string. */
-+ if (size1 != 0)
-+ {
-+ if (size1 > MAX_ALLOCA_SIZE)
-+ {
-+ wcs_string1 = TALLOC (size1 + 1, CHAR_T);
-+ mbs_offset1 = TALLOC (size1 + 1, int);
-+ is_binary = TALLOC (size1 + 1, char);
-+ }
-+ else
-+ {
-+ wcs_string1 = REGEX_TALLOC (size1 + 1, CHAR_T);
-+ mbs_offset1 = REGEX_TALLOC (size1 + 1, int);
-+ is_binary = REGEX_TALLOC (size1 + 1, char);
-+ }
-+ if (!wcs_string1 || !mbs_offset1 || !is_binary)
-+ {
-+ if (size1 > MAX_ALLOCA_SIZE)
-+ {
-+ free (wcs_string1);
-+ free (mbs_offset1);
-+ free (is_binary);
-+ }
-+ else
-+ {
-+ FREE_VAR (wcs_string1);
-+ FREE_VAR (mbs_offset1);
-+ FREE_VAR (is_binary);
-+ }
-+ return -2;
-+ }
-+ wcs_size1 = convert_mbs_to_wcs(wcs_string1, string1, size1,
-+ mbs_offset1, is_binary);
-+ wcs_string1[wcs_size1] = L'\0'; /* for a sentinel */
-+ if (size1 > MAX_ALLOCA_SIZE)
-+ free (is_binary);
-+ else
-+ FREE_VAR (is_binary);
-+ }
-+ if (size2 != 0)
-+ {
-+ if (size2 > MAX_ALLOCA_SIZE)
-+ {
-+ wcs_string2 = TALLOC (size2 + 1, CHAR_T);
-+ mbs_offset2 = TALLOC (size2 + 1, int);
-+ is_binary = TALLOC (size2 + 1, char);
-+ }
-+ else
-+ {
-+ wcs_string2 = REGEX_TALLOC (size2 + 1, CHAR_T);
-+ mbs_offset2 = REGEX_TALLOC (size2 + 1, int);
-+ is_binary = REGEX_TALLOC (size2 + 1, char);
-+ }
-+ if (!wcs_string2 || !mbs_offset2 || !is_binary)
-+ {
-+ FREE_WCS_BUFFERS ();
-+ if (size2 > MAX_ALLOCA_SIZE)
-+ free (is_binary);
-+ else
-+ FREE_VAR (is_binary);
-+ return -2;
-+ }
-+ wcs_size2 = convert_mbs_to_wcs(wcs_string2, string2, size2,
-+ mbs_offset2, is_binary);
-+ wcs_string2[wcs_size2] = L'\0'; /* for a sentinel */
-+ if (size2 > MAX_ALLOCA_SIZE)
-+ free (is_binary);
-+ else
-+ FREE_VAR (is_binary);
-+ }
-+#endif /* WCHAR */
-+
-+
-+ /* Loop through the string, looking for a place to start matching. */
-+ for (;;)
-+ {
-+ /* If a fastmap is supplied, skip quickly over characters that
-+ cannot be the start of a match. If the pattern can match the
-+ null string, however, we don't need to skip characters; we want
-+ the first null string. */
-+ if (fastmap && startpos < total_size && !bufp->can_be_null)
-+ {
-+ if (range > 0) /* Searching forwards. */
-+ {
-+ register const char *d;
-+ register int lim = 0;
-+ int irange = range;
-+
-+ if (startpos < size1 && startpos + range >= size1)
-+ lim = range - (size1 - startpos);
-+
-+ d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
-+
-+ /* Written out as an if-else to avoid testing `translate'
-+ inside the loop. */
-+ if (translate)
-+ while (range > lim
-+ && !fastmap[(unsigned char)
-+ translate[(unsigned char) *d++]])
-+ range--;
-+ else
-+ while (range > lim && !fastmap[(unsigned char) *d++])
-+ range--;
-+
-+ startpos += irange - range;
-+ }
-+ else /* Searching backwards. */
-+ {
-+ register CHAR_T c = (size1 == 0 || startpos >= size1
-+ ? string2[startpos - size1]
-+ : string1[startpos]);
-+
-+ if (!fastmap[(unsigned char) TRANSLATE (c)])
-+ goto advance;
-+ }
-+ }
-+
-+ /* If can't match the null string, and that's all we have left, fail. */
-+ if (range >= 0 && startpos == total_size && fastmap
-+ && !bufp->can_be_null)
-+ {
-+#ifdef WCHAR
-+ FREE_WCS_BUFFERS ();
-+#endif
-+ return -1;
-+ }
-+
-+#ifdef WCHAR
-+ val = wcs_re_match_2_internal (bufp, string1, size1, string2,
-+ size2, startpos, regs, stop,
-+ wcs_string1, wcs_size1,
-+ wcs_string2, wcs_size2,
-+ mbs_offset1, mbs_offset2);
-+#else /* BYTE */
-+ val = byte_re_match_2_internal (bufp, string1, size1, string2,
-+ size2, startpos, regs, stop);
-+#endif /* BYTE */
-+
-+#ifndef REGEX_MALLOC
-+# ifdef C_ALLOCA
-+ alloca (0);
-+# endif
-+#endif
-+
-+ if (val >= 0)
-+ {
-+#ifdef WCHAR
-+ FREE_WCS_BUFFERS ();
-+#endif
-+ return startpos;
-+ }
-+
-+ if (val == -2)
-+ {
-+#ifdef WCHAR
-+ FREE_WCS_BUFFERS ();
-+#endif
-+ return -2;
-+ }
-+
-+ advance:
-+ if (!range)
-+ break;
-+ else if (range > 0)
-+ {
-+ range--;
-+ startpos++;
-+ }
-+ else
-+ {
-+ range++;
-+ startpos--;
-+ }
-+ }
-+#ifdef WCHAR
-+ FREE_WCS_BUFFERS ();
-+#endif
-+ return -1;
-+}
-+
-+#ifdef WCHAR
-+/* This converts PTR, a pointer into one of the search wchar_t strings
-+ `string1' and `string2' into an multibyte string offset from the
-+ beginning of that string. We use mbs_offset to optimize.
-+ See convert_mbs_to_wcs. */
-+# define POINTER_TO_OFFSET(ptr) \
-+ (FIRST_STRING_P (ptr) \
-+ ? ((regoff_t)(mbs_offset1 != NULL? mbs_offset1[(ptr)-string1] : 0)) \
-+ : ((regoff_t)((mbs_offset2 != NULL? mbs_offset2[(ptr)-string2] : 0) \
-+ + csize1)))
-+#else /* BYTE */
-+/* This converts PTR, a pointer into one of the search strings `string1'
-+ and `string2' into an offset from the beginning of that string. */
-+# define POINTER_TO_OFFSET(ptr) \
-+ (FIRST_STRING_P (ptr) \
-+ ? ((regoff_t) ((ptr) - string1)) \
-+ : ((regoff_t) ((ptr) - string2 + size1)))
-+#endif /* WCHAR */
-+
-+/* Macros for dealing with the split strings in re_match_2. */
-+
-+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
-+
-+/* Call before fetching a character with *d. This switches over to
-+ string2 if necessary. */
-+#define PREFETCH() \
-+ while (d == dend) \
-+ { \
-+ /* End of string2 => fail. */ \
-+ if (dend == end_match_2) \
-+ goto fail; \
-+ /* End of string1 => advance to string2. */ \
-+ d = string2; \
-+ dend = end_match_2; \
-+ }
-+
-+/* Test if at very beginning or at very end of the virtual concatenation
-+ of `string1' and `string2'. If only one string, it's `string2'. */
-+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
-+#define AT_STRINGS_END(d) ((d) == end2)
-+
-+
-+/* Test if D points to a character which is word-constituent. We have
-+ two special cases to check for: if past the end of string1, look at
-+ the first character in string2; and if before the beginning of
-+ string2, look at the last character in string1. */
-+#ifdef WCHAR
-+/* Use internationalized API instead of SYNTAX. */
-+# define WORDCHAR_P(d) \
-+ (iswalnum ((wint_t)((d) == end1 ? *string2 \
-+ : (d) == string2 - 1 ? *(end1 - 1) : *(d))) != 0 \
-+ || ((d) == end1 ? *string2 \
-+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) == L'_')
-+#else /* BYTE */
-+# define WORDCHAR_P(d) \
-+ (SYNTAX ((d) == end1 ? *string2 \
-+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
-+ == Sword)
-+#endif /* WCHAR */
-+
-+/* Disabled due to a compiler bug -- see comment at case wordbound */
-+#if 0
-+/* Test if the character before D and the one at D differ with respect
-+ to being word-constituent. */
-+#define AT_WORD_BOUNDARY(d) \
-+ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
-+ || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
-+#endif
-+
-+/* Free everything we malloc. */
-+#ifdef MATCH_MAY_ALLOCATE
-+# ifdef WCHAR
-+# define FREE_VARIABLES() \
-+ do { \
-+ REGEX_FREE_STACK (fail_stack.stack); \
-+ FREE_VAR (regstart); \
-+ FREE_VAR (regend); \
-+ FREE_VAR (old_regstart); \
-+ FREE_VAR (old_regend); \
-+ FREE_VAR (best_regstart); \
-+ FREE_VAR (best_regend); \
-+ FREE_VAR (reg_info); \
-+ FREE_VAR (reg_dummy); \
-+ FREE_VAR (reg_info_dummy); \
-+ if (!cant_free_wcs_buf) \
-+ { \
-+ FREE_VAR (string1); \
-+ FREE_VAR (string2); \
-+ FREE_VAR (mbs_offset1); \
-+ FREE_VAR (mbs_offset2); \
-+ } \
-+ } while (0)
-+# else /* BYTE */
-+# define FREE_VARIABLES() \
-+ do { \
-+ REGEX_FREE_STACK (fail_stack.stack); \
-+ FREE_VAR (regstart); \
-+ FREE_VAR (regend); \
-+ FREE_VAR (old_regstart); \
-+ FREE_VAR (old_regend); \
-+ FREE_VAR (best_regstart); \
-+ FREE_VAR (best_regend); \
-+ FREE_VAR (reg_info); \
-+ FREE_VAR (reg_dummy); \
-+ FREE_VAR (reg_info_dummy); \
-+ } while (0)
-+# endif /* WCHAR */
-+#else
-+# ifdef WCHAR
-+# define FREE_VARIABLES() \
-+ do { \
-+ if (!cant_free_wcs_buf) \
-+ { \
-+ FREE_VAR (string1); \
-+ FREE_VAR (string2); \
-+ FREE_VAR (mbs_offset1); \
-+ FREE_VAR (mbs_offset2); \
-+ } \
-+ } while (0)
-+# else /* BYTE */
-+# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */
-+# endif /* WCHAR */
-+#endif /* not MATCH_MAY_ALLOCATE */
-+
-+/* These values must meet several constraints. They must not be valid
-+ register values; since we have a limit of 255 registers (because
-+ we use only one byte in the pattern for the register number), we can
-+ use numbers larger than 255. They must differ by 1, because of
-+ NUM_FAILURE_ITEMS above. And the value for the lowest register must
-+ be larger than the value for the highest register, so we do not try
-+ to actually save any registers when none are active. */
-+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
-+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
-+
-+#else /* not INSIDE_RECURSION */
-+/* Matching routines. */
-+
-+#ifndef emacs /* Emacs never uses this. */
-+/* re_match is like re_match_2 except it takes only a single string. */
-+
-+int
-+re_match (struct re_pattern_buffer *bufp, const char *string,
-+ int size, int pos, struct re_registers *regs)
-+{
-+ int result;
-+# ifdef MBS_SUPPORT
-+ if (MB_CUR_MAX != 1)
-+ result = wcs_re_match_2_internal (bufp, NULL, 0, string, size,
-+ pos, regs, size,
-+ NULL, 0, NULL, 0, NULL, NULL);
-+ else
-+# endif
-+ result = byte_re_match_2_internal (bufp, NULL, 0, string, size,
-+ pos, regs, size);
-+# ifndef REGEX_MALLOC
-+# ifdef C_ALLOCA
-+ alloca (0);
-+# endif
-+# endif
-+ return result;
-+}
-+# ifdef _LIBC
-+weak_alias (__re_match, re_match)
-+# endif
-+#endif /* not emacs */
-+
-+#endif /* not INSIDE_RECURSION */
-+
-+#ifdef INSIDE_RECURSION
-+static boolean PREFIX(group_match_null_string_p) (UCHAR_T **p,
-+ UCHAR_T *end,
-+ PREFIX(register_info_type) *reg_info);
-+static boolean PREFIX(alt_match_null_string_p) (UCHAR_T *p,
-+ UCHAR_T *end,
-+ PREFIX(register_info_type) *reg_info);
-+static boolean PREFIX(common_op_match_null_string_p) (UCHAR_T **p,
-+ UCHAR_T *end,
-+ PREFIX(register_info_type) *reg_info);
-+static int PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2,
-+ register int len,
-+ RE_TRANSLATE_TYPE translate);
-+#else /* not INSIDE_RECURSION */
-+
-+/* re_match_2 matches the compiled pattern in BUFP against the
-+ the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
-+ and SIZE2, respectively). We start matching at POS, and stop
-+ matching at STOP.
-+
-+ If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
-+ store offsets for the substring each group matched in REGS. See the
-+ documentation for exactly how many groups we fill.
-+
-+ We return -1 if no match, -2 if an internal error (such as the
-+ failure stack overflowing). Otherwise, we return the length of the
-+ matched substring. */
-+
-+int
-+re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
-+ const char *string2, int size2, int pos,
-+ struct re_registers *regs, int stop)
-+{
-+ int result;
-+# ifdef MBS_SUPPORT
-+ if (MB_CUR_MAX != 1)
-+ result = wcs_re_match_2_internal (bufp, string1, size1, string2, size2,
-+ pos, regs, stop,
-+ NULL, 0, NULL, 0, NULL, NULL);
-+ else
-+# endif
-+ result = byte_re_match_2_internal (bufp, string1, size1, string2, size2,
-+ pos, regs, stop);
-+
-+#ifndef REGEX_MALLOC
-+# ifdef C_ALLOCA
-+ alloca (0);
-+# endif
-+#endif
-+ return result;
-+}
-+#ifdef _LIBC
-+weak_alias (__re_match_2, re_match_2)
-+#endif
-+
-+#endif /* not INSIDE_RECURSION */
-+
-+#ifdef INSIDE_RECURSION
-+
-+#ifdef WCHAR
-+static int count_mbs_length (int *, int);
-+
-+/* This check the substring (from 0, to length) of the multibyte string,
-+ to which offset_buffer correspond. And count how many wchar_t_characters
-+ the substring occupy. We use offset_buffer to optimization.
-+ See convert_mbs_to_wcs. */
-+
-+static int
-+count_mbs_length(int *offset_buffer, int length)
-+{
-+ int upper, lower;
-+
-+ /* Check whether the size is valid. */
-+ if (length < 0)
-+ return -1;
-+
-+ if (offset_buffer == NULL)
-+ return 0;
-+
-+ /* If there are no multibyte character, offset_buffer[i] == i.
-+ Optmize for this case. */
-+ if (offset_buffer[length] == length)
-+ return length;
-+
-+ /* Set up upper with length. (because for all i, offset_buffer[i] >= i) */
-+ upper = length;
-+ lower = 0;
-+
-+ while (true)
-+ {
-+ int middle = (lower + upper) / 2;
-+ if (middle == lower || middle == upper)
-+ break;
-+ if (offset_buffer[middle] > length)
-+ upper = middle;
-+ else if (offset_buffer[middle] < length)
-+ lower = middle;
-+ else
-+ return middle;
-+ }
-+
-+ return -1;
-+}
-+#endif /* WCHAR */
-+
-+/* This is a separate function so that we can force an alloca cleanup
-+ afterwards. */
-+#ifdef WCHAR
-+static int
-+wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
-+ const char *cstring1, int csize1,
-+ const char *cstring2, int csize2,
-+ int pos,
-+ struct re_registers *regs,
-+ int stop,
-+ /* string1 == string2 == NULL means string1/2, size1/2 and
-+ mbs_offset1/2 need seting up in this function. */
-+ /* We need wchar_t* buffers correspond to cstring1, cstring2. */
-+ wchar_t *string1, int size1,
-+ wchar_t *string2, int size2,
-+ /* offset buffer for optimizatoin. See convert_mbs_to_wc. */
-+ int *mbs_offset1, int *mbs_offset2)
-+#else /* BYTE */
-+static int
-+byte_re_match_2_internal (struct re_pattern_buffer *bufp,
-+ const char *string1, int size1,
-+ const char *string2, int size2,
-+ int pos,
-+ struct re_registers *regs, int stop)
-+#endif /* BYTE */
-+{
-+ /* General temporaries. */
-+ int mcnt;
-+ UCHAR_T *p1;
-+#ifdef WCHAR
-+ /* They hold whether each wchar_t is binary data or not. */
-+ char *is_binary = NULL;
-+ /* If true, we can't free string1/2, mbs_offset1/2. */
-+ int cant_free_wcs_buf = 1;
-+#endif /* WCHAR */
-+
-+ /* Just past the end of the corresponding string. */
-+ const CHAR_T *end1, *end2;
-+
-+ /* Pointers into string1 and string2, just past the last characters in
-+ each to consider matching. */
-+ const CHAR_T *end_match_1, *end_match_2;
-+
-+ /* Where we are in the data, and the end of the current string. */
-+ const CHAR_T *d, *dend;
-+
-+ /* Where we are in the pattern, and the end of the pattern. */
-+#ifdef WCHAR
-+ UCHAR_T *pattern, *p;
-+ register UCHAR_T *pend;
-+#else /* BYTE */
-+ UCHAR_T *p = bufp->buffer;
-+ register UCHAR_T *pend = p + bufp->used;
-+#endif /* WCHAR */
-+
-+ /* Mark the opcode just after a start_memory, so we can test for an
-+ empty subpattern when we get to the stop_memory. */
-+ UCHAR_T *just_past_start_mem = 0;
-+
-+ /* We use this to map every character in the string. */
-+ RE_TRANSLATE_TYPE translate = bufp->translate;
-+
-+ /* Failure point stack. Each place that can handle a failure further
-+ down the line pushes a failure point on this stack. It consists of
-+ restart, regend, and reg_info for all registers corresponding to
-+ the subexpressions we're currently inside, plus the number of such
-+ registers, and, finally, two char *'s. The first char * is where
-+ to resume scanning the pattern; the second one is where to resume
-+ scanning the strings. If the latter is zero, the failure point is
-+ a ``dummy''; if a failure happens and the failure point is a dummy,
-+ it gets discarded and the next next one is tried. */
-+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
-+ PREFIX(fail_stack_type) fail_stack;
-+#endif
-+#ifdef DEBUG
-+ static unsigned failure_id;
-+ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
-+#endif
-+
-+#ifdef REL_ALLOC
-+ /* This holds the pointer to the failure stack, when
-+ it is allocated relocatably. */
-+ fail_stack_elt_t *failure_stack_ptr;
-+#endif
-+
-+ /* We fill all the registers internally, independent of what we
-+ return, for use in backreferences. The number here includes
-+ an element for register zero. */
-+ size_t num_regs = bufp->re_nsub + 1;
-+
-+ /* The currently active registers. */
-+ active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
-+ active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
-+
-+ /* Information on the contents of registers. These are pointers into
-+ the input strings; they record just what was matched (on this
-+ attempt) by a subexpression part of the pattern, that is, the
-+ regnum-th regstart pointer points to where in the pattern we began
-+ matching and the regnum-th regend points to right after where we
-+ stopped matching the regnum-th subexpression. (The zeroth register
-+ keeps track of what the whole pattern matches.) */
-+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
-+ const CHAR_T **regstart, **regend;
-+#endif
-+
-+ /* If a group that's operated upon by a repetition operator fails to
-+ match anything, then the register for its start will need to be
-+ restored because it will have been set to wherever in the string we
-+ are when we last see its open-group operator. Similarly for a
-+ register's end. */
-+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
-+ const CHAR_T **old_regstart, **old_regend;
-+#endif
-+
-+ /* The is_active field of reg_info helps us keep track of which (possibly
-+ nested) subexpressions we are currently in. The matched_something
-+ field of reg_info[reg_num] helps us tell whether or not we have
-+ matched any of the pattern so far this time through the reg_num-th
-+ subexpression. These two fields get reset each time through any
-+ loop their register is in. */
-+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
-+ PREFIX(register_info_type) *reg_info;
-+#endif
-+
-+ /* The following record the register info as found in the above
-+ variables when we find a match better than any we've seen before.
-+ This happens as we backtrack through the failure points, which in
-+ turn happens only if we have not yet matched the entire string. */
-+ unsigned best_regs_set = false;
-+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
-+ const CHAR_T **best_regstart, **best_regend;
-+#endif
-+
-+ /* Logically, this is `best_regend[0]'. But we don't want to have to
-+ allocate space for that if we're not allocating space for anything
-+ else (see below). Also, we never need info about register 0 for
-+ any of the other register vectors, and it seems rather a kludge to
-+ treat `best_regend' differently than the rest. So we keep track of
-+ the end of the best match so far in a separate variable. We
-+ initialize this to NULL so that when we backtrack the first time
-+ and need to test it, it's not garbage. */
-+ const CHAR_T *match_end = NULL;
-+
-+ /* This helps SET_REGS_MATCHED avoid doing redundant work. */
-+ int set_regs_matched_done = 0;
-+
-+ /* Used when we pop values we don't care about. */
-+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
-+ const CHAR_T **reg_dummy;
-+ PREFIX(register_info_type) *reg_info_dummy;
-+#endif
-+
-+#ifdef DEBUG
-+ /* Counts the total number of registers pushed. */
-+ unsigned num_regs_pushed = 0;
-+#endif
-+
-+ DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
-+
-+ INIT_FAIL_STACK ();
-+
-+#ifdef MATCH_MAY_ALLOCATE
-+ /* Do not bother to initialize all the register variables if there are
-+ no groups in the pattern, as it takes a fair amount of time. If
-+ there are groups, we include space for register 0 (the whole
-+ pattern), even though we never use it, since it simplifies the
-+ array indexing. We should fix this. */
-+ if (bufp->re_nsub)
-+ {
-+ regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
-+ regend = REGEX_TALLOC (num_regs, const CHAR_T *);
-+ old_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
-+ old_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
-+ best_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
-+ best_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
-+ reg_info = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
-+ reg_dummy = REGEX_TALLOC (num_regs, const CHAR_T *);
-+ reg_info_dummy = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
-+
-+ if (!(regstart && regend && old_regstart && old_regend && reg_info
-+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
-+ {
-+ FREE_VARIABLES ();
-+ return -2;
-+ }
-+ }
-+ else
-+ {
-+ /* We must initialize all our variables to NULL, so that
-+ `FREE_VARIABLES' doesn't try to free them. */
-+ regstart = regend = old_regstart = old_regend = best_regstart
-+ = best_regend = reg_dummy = NULL;
-+ reg_info = reg_info_dummy = (PREFIX(register_info_type) *) NULL;
-+ }
-+#endif /* MATCH_MAY_ALLOCATE */
-+
-+ /* The starting position is bogus. */
-+#ifdef WCHAR
-+ if (pos < 0 || pos > csize1 + csize2)
-+#else /* BYTE */
-+ if (pos < 0 || pos > size1 + size2)
-+#endif
-+ {
-+ FREE_VARIABLES ();
-+ return -1;
-+ }
-+
-+#ifdef WCHAR
-+ /* Allocate wchar_t array for string1 and string2 and
-+ fill them with converted string. */
-+ if (string1 == NULL && string2 == NULL)
-+ {
-+ /* We need seting up buffers here. */
-+
-+ /* We must free wcs buffers in this function. */
-+ cant_free_wcs_buf = 0;
-+
-+ if (csize1 != 0)
-+ {
-+ string1 = REGEX_TALLOC (csize1 + 1, CHAR_T);
-+ mbs_offset1 = REGEX_TALLOC (csize1 + 1, int);
-+ is_binary = REGEX_TALLOC (csize1 + 1, char);
-+ if (!string1 || !mbs_offset1 || !is_binary)
-+ {
-+ FREE_VAR (string1);
-+ FREE_VAR (mbs_offset1);
-+ FREE_VAR (is_binary);
-+ return -2;
-+ }
-+ }
-+ if (csize2 != 0)
-+ {
-+ string2 = REGEX_TALLOC (csize2 + 1, CHAR_T);
-+ mbs_offset2 = REGEX_TALLOC (csize2 + 1, int);
-+ is_binary = REGEX_TALLOC (csize2 + 1, char);
-+ if (!string2 || !mbs_offset2 || !is_binary)
-+ {
-+ FREE_VAR (string1);
-+ FREE_VAR (mbs_offset1);
-+ FREE_VAR (string2);
-+ FREE_VAR (mbs_offset2);
-+ FREE_VAR (is_binary);
-+ return -2;
-+ }
-+ size2 = convert_mbs_to_wcs(string2, cstring2, csize2,
-+ mbs_offset2, is_binary);
-+ string2[size2] = L'\0'; /* for a sentinel */
-+ FREE_VAR (is_binary);
-+ }
-+ }
-+
-+ /* We need to cast pattern to (wchar_t*), because we casted this compiled
-+ pattern to (char*) in regex_compile. */
-+ p = pattern = (CHAR_T*)bufp->buffer;
-+ pend = (CHAR_T*)(bufp->buffer + bufp->used);
-+
-+#endif /* WCHAR */
-+
-+ /* Initialize subexpression text positions to -1 to mark ones that no
-+ start_memory/stop_memory has been seen for. Also initialize the
-+ register information struct. */
-+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
-+ {
-+ regstart[mcnt] = regend[mcnt]
-+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
-+
-+ REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
-+ IS_ACTIVE (reg_info[mcnt]) = 0;
-+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
-+ EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
-+ }
-+
-+ /* We move `string1' into `string2' if the latter's empty -- but not if
-+ `string1' is null. */
-+ if (size2 == 0 && string1 != NULL)
-+ {
-+ string2 = string1;
-+ size2 = size1;
-+ string1 = 0;
-+ size1 = 0;
-+#ifdef WCHAR
-+ mbs_offset2 = mbs_offset1;
-+ csize2 = csize1;
-+ mbs_offset1 = NULL;
-+ csize1 = 0;
-+#endif
-+ }
-+ end1 = string1 + size1;
-+ end2 = string2 + size2;
-+
-+ /* Compute where to stop matching, within the two strings. */
-+#ifdef WCHAR
-+ if (stop <= csize1)
-+ {
-+ mcnt = count_mbs_length(mbs_offset1, stop);
-+ end_match_1 = string1 + mcnt;
-+ end_match_2 = string2;
-+ }
-+ else
-+ {
-+ if (stop > csize1 + csize2)
-+ stop = csize1 + csize2;
-+ end_match_1 = end1;
-+ mcnt = count_mbs_length(mbs_offset2, stop-csize1);
-+ end_match_2 = string2 + mcnt;
-+ }
-+ if (mcnt < 0)
-+ { /* count_mbs_length return error. */
-+ FREE_VARIABLES ();
-+ return -1;
-+ }
-+#else
-+ if (stop <= size1)
-+ {
-+ end_match_1 = string1 + stop;
-+ end_match_2 = string2;
-+ }
-+ else
-+ {
-+ end_match_1 = end1;
-+ end_match_2 = string2 + stop - size1;
-+ }
-+#endif /* WCHAR */
-+
-+ /* `p' scans through the pattern as `d' scans through the data.
-+ `dend' is the end of the input string that `d' points within. `d'
-+ is advanced into the following input string whenever necessary, but
-+ this happens before fetching; therefore, at the beginning of the
-+ loop, `d' can be pointing at the end of a string, but it cannot
-+ equal `string2'. */
-+#ifdef WCHAR
-+ if (size1 > 0 && pos <= csize1)
-+ {
-+ mcnt = count_mbs_length(mbs_offset1, pos);
-+ d = string1 + mcnt;
-+ dend = end_match_1;
-+ }
-+ else
-+ {
-+ mcnt = count_mbs_length(mbs_offset2, pos-csize1);
-+ d = string2 + mcnt;
-+ dend = end_match_2;
-+ }
-+
-+ if (mcnt < 0)
-+ { /* count_mbs_length return error. */
-+ FREE_VARIABLES ();
-+ return -1;
-+ }
-+#else
-+ if (size1 > 0 && pos <= size1)
-+ {
-+ d = string1 + pos;
-+ dend = end_match_1;
-+ }
-+ else
-+ {
-+ d = string2 + pos - size1;
-+ dend = end_match_2;
-+ }
-+#endif /* WCHAR */
-+
-+ DEBUG_PRINT1 ("The compiled pattern is:\n");
-+ DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
-+ DEBUG_PRINT1 ("The string to match is: `");
-+ DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
-+ DEBUG_PRINT1 ("'\n");
-+
-+ /* This loops over pattern commands. It exits by returning from the
-+ function if the match is complete, or it drops through if the match
-+ fails at this starting point in the input data. */
-+ for (;;)
-+ {
-+#ifdef _LIBC
-+ DEBUG_PRINT2 ("\n%p: ", p);
-+#else
-+ DEBUG_PRINT2 ("\n0x%x: ", p);
-+#endif
-+
-+ if (p == pend)
-+ { /* End of pattern means we might have succeeded. */
-+ DEBUG_PRINT1 ("end of pattern ... ");
-+
-+ /* If we haven't matched the entire string, and we want the
-+ longest match, try backtracking. */
-+ if (d != end_match_2)
-+ {
-+ /* 1 if this match ends in the same string (string1 or string2)
-+ as the best previous match. */
-+ boolean same_str_p = (FIRST_STRING_P (match_end)
-+ == MATCHING_IN_FIRST_STRING);
-+ /* 1 if this match is the best seen so far. */
-+ boolean best_match_p;
-+
-+ /* AIX compiler got confused when this was combined
-+ with the previous declaration. */
-+ if (same_str_p)
-+ best_match_p = d > match_end;
-+ else
-+ best_match_p = !MATCHING_IN_FIRST_STRING;
-+
-+ DEBUG_PRINT1 ("backtracking.\n");
-+
-+ if (!FAIL_STACK_EMPTY ())
-+ { /* More failure points to try. */
-+
-+ /* If exceeds best match so far, save it. */
-+ if (!best_regs_set || best_match_p)
-+ {
-+ best_regs_set = true;
-+ match_end = d;
-+
-+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
-+
-+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
-+ {
-+ best_regstart[mcnt] = regstart[mcnt];
-+ best_regend[mcnt] = regend[mcnt];
-+ }
-+ }
-+ goto fail;
-+ }
-+
-+ /* If no failure points, don't restore garbage. And if
-+ last match is real best match, don't restore second
-+ best one. */
-+ else if (best_regs_set && !best_match_p)
-+ {
-+ restore_best_regs:
-+ /* Restore best match. It may happen that `dend ==
-+ end_match_1' while the restored d is in string2.
-+ For example, the pattern `x.*y.*z' against the
-+ strings `x-' and `y-z-', if the two strings are
-+ not consecutive in memory. */
-+ DEBUG_PRINT1 ("Restoring best registers.\n");
-+
-+ d = match_end;
-+ dend = ((d >= string1 && d <= end1)
-+ ? end_match_1 : end_match_2);
-+
-+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
-+ {
-+ regstart[mcnt] = best_regstart[mcnt];
-+ regend[mcnt] = best_regend[mcnt];
-+ }
-+ }
-+ } /* d != end_match_2 */
-+
-+ succeed_label:
-+ DEBUG_PRINT1 ("Accepting match.\n");
-+ /* If caller wants register contents data back, do it. */
-+ if (regs && !bufp->no_sub)
-+ {
-+ /* Have the register data arrays been allocated? */
-+ if (bufp->regs_allocated == REGS_UNALLOCATED)
-+ { /* No. So allocate them with malloc. We need one
-+ extra element beyond `num_regs' for the `-1' marker
-+ GNU code uses. */
-+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
-+ regs->start = TALLOC (regs->num_regs, regoff_t);
-+ regs->end = TALLOC (regs->num_regs, regoff_t);
-+ if (regs->start == NULL || regs->end == NULL)
-+ {
-+ FREE_VARIABLES ();
-+ return -2;
-+ }
-+ bufp->regs_allocated = REGS_REALLOCATE;
-+ }
-+ else if (bufp->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 (regs->num_regs < num_regs + 1)
-+ {
-+ regs->num_regs = num_regs + 1;
-+ RETALLOC (regs->start, regs->num_regs, regoff_t);
-+ RETALLOC (regs->end, regs->num_regs, regoff_t);
-+ if (regs->start == NULL || regs->end == NULL)
-+ {
-+ FREE_VARIABLES ();
-+ return -2;
-+ }
-+ }
-+ }
-+ else
-+ {
-+ /* These braces fend off a "empty body in an else-statement"
-+ warning under GCC when assert expands to nothing. */
-+ assert (bufp->regs_allocated == REGS_FIXED);
-+ }
-+
-+ /* Convert the pointer data in `regstart' and `regend' to
-+ indices. Register zero has to be set differently,
-+ since we haven't kept track of any info for it. */
-+ if (regs->num_regs > 0)
-+ {
-+ regs->start[0] = pos;
-+#ifdef WCHAR
-+ if (MATCHING_IN_FIRST_STRING)
-+ regs->end[0] = mbs_offset1 != NULL ?
-+ mbs_offset1[d-string1] : 0;
-+ else
-+ regs->end[0] = csize1 + (mbs_offset2 != NULL ?
-+ mbs_offset2[d-string2] : 0);
-+#else
-+ regs->end[0] = (MATCHING_IN_FIRST_STRING
-+ ? ((regoff_t) (d - string1))
-+ : ((regoff_t) (d - string2 + size1)));
-+#endif /* WCHAR */
-+ }
-+
-+ /* Go through the first `min (num_regs, regs->num_regs)'
-+ registers, since that is all we initialized. */
-+ for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs);
-+ mcnt++)
-+ {
-+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
-+ regs->start[mcnt] = regs->end[mcnt] = -1;
-+ else
-+ {
-+ regs->start[mcnt]
-+ = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
-+ regs->end[mcnt]
-+ = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
-+ }
-+ }
-+
-+ /* If the regs structure we return has more elements than
-+ were in the pattern, set the extra elements to -1. If
-+ we (re)allocated the registers, this is the case,
-+ because we always allocate enough to have at least one
-+ -1 at the end. */
-+ for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++)
-+ regs->start[mcnt] = regs->end[mcnt] = -1;
-+ } /* regs && !bufp->no_sub */
-+
-+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
-+ nfailure_points_pushed, nfailure_points_popped,
-+ nfailure_points_pushed - nfailure_points_popped);
-+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
-+
-+#ifdef WCHAR
-+ if (MATCHING_IN_FIRST_STRING)
-+ mcnt = mbs_offset1 != NULL ? mbs_offset1[d-string1] : 0;
-+ else
-+ mcnt = (mbs_offset2 != NULL ? mbs_offset2[d-string2] : 0) +
-+ csize1;
-+ mcnt -= pos;
-+#else
-+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
-+ ? string1
-+ : string2 - size1);
-+#endif /* WCHAR */
-+
-+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
-+
-+ FREE_VARIABLES ();
-+ return mcnt;
-+ }
-+
-+ /* Otherwise match next pattern command. */
-+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
-+ {
-+ /* Ignore these. Used to ignore the n of succeed_n's which
-+ currently have n == 0. */
-+ case no_op:
-+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
-+ break;
-+
-+ case succeed:
-+ DEBUG_PRINT1 ("EXECUTING succeed.\n");
-+ goto succeed_label;
-+
-+ /* Match the next n pattern characters exactly. The following
-+ byte in the pattern defines n, and the n bytes after that
-+ are the characters to match. */
-+ case exactn:
-+#ifdef MBS_SUPPORT
-+ case exactn_bin:
-+#endif
-+ mcnt = *p++;
-+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
-+
-+ /* This is written out as an if-else so we don't waste time
-+ testing `translate' inside the loop. */
-+ if (translate)
-+ {
-+ do
-+ {
-+ PREFETCH ();
-+#ifdef WCHAR
-+ if (*d <= 0xff)
-+ {
-+ if ((UCHAR_T) translate[(unsigned char) *d++]
-+ != (UCHAR_T) *p++)
-+ goto fail;
-+ }
-+ else
-+ {
-+ if (*d++ != (CHAR_T) *p++)
-+ goto fail;
-+ }
-+#else
-+ if ((UCHAR_T) translate[(unsigned char) *d++]
-+ != (UCHAR_T) *p++)
-+ goto fail;
-+#endif /* WCHAR */
-+ }
-+ while (--mcnt);
-+ }
-+ else
-+ {
-+ do
-+ {
-+ PREFETCH ();
-+ if (*d++ != (CHAR_T) *p++) goto fail;
-+ }
-+ while (--mcnt);
-+ }
-+ SET_REGS_MATCHED ();
-+ break;
-+
-+
-+ /* Match any character except possibly a newline or a null. */
-+ case anychar:
-+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
-+
-+ PREFETCH ();
-+
-+ if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
-+ || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
-+ goto fail;
-+
-+ SET_REGS_MATCHED ();
-+ DEBUG_PRINT2 (" Matched `%ld'.\n", (long int) *d);
-+ d++;
-+ break;
-+
-+
-+ case charset:
-+ case charset_not:
-+ {
-+ register UCHAR_T c;
-+#ifdef WCHAR
-+ unsigned int i, char_class_length, coll_symbol_length,
-+ equiv_class_length, ranges_length, chars_length, length;
-+ CHAR_T *workp, *workp2, *charset_top;
-+#define WORK_BUFFER_SIZE 128
-+ CHAR_T str_buf[WORK_BUFFER_SIZE];
-+# ifdef _LIBC
-+ uint32_t nrules;
-+# endif /* _LIBC */
-+#endif /* WCHAR */
-+ boolean negate = (re_opcode_t) *(p - 1) == charset_not;
-+
-+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", negate ? "_not" : "");
-+ PREFETCH ();
-+ c = TRANSLATE (*d); /* The character to match. */
-+#ifdef WCHAR
-+# ifdef _LIBC
-+ nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-+# endif /* _LIBC */
-+ charset_top = p - 1;
-+ char_class_length = *p++;
-+ coll_symbol_length = *p++;
-+ equiv_class_length = *p++;
-+ ranges_length = *p++;
-+ chars_length = *p++;
-+ /* p points charset[6], so the address of the next instruction
-+ (charset[l+m+n+2o+k+p']) equals p[l+m+n+2*o+p'],
-+ where l=length of char_classes, m=length of collating_symbol,
-+ n=equivalence_class, o=length of char_range,
-+ p'=length of character. */
-+ workp = p;
-+ /* Update p to indicate the next instruction. */
-+ p += char_class_length + coll_symbol_length+ equiv_class_length +
-+ 2*ranges_length + chars_length;
-+
-+ /* match with char_class? */
-+ for (i = 0; i < char_class_length ; i += CHAR_CLASS_SIZE)
-+ {
-+ wctype_t wctype;
-+ uintptr_t alignedp = ((uintptr_t)workp
-+ + __alignof__(wctype_t) - 1)
-+ & ~(uintptr_t)(__alignof__(wctype_t) - 1);
-+ wctype = *((wctype_t*)alignedp);
-+ workp += CHAR_CLASS_SIZE;
-+# ifdef _LIBC
-+ if (__iswctype((wint_t)c, wctype))
-+ goto char_set_matched;
-+# else
-+ if (iswctype((wint_t)c, wctype))
-+ goto char_set_matched;
-+# endif
-+ }
-+
-+ /* match with collating_symbol? */
-+# ifdef _LIBC
-+ if (nrules != 0)
-+ {
-+ const unsigned char *extra = (const unsigned char *)
-+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
-+
-+ for (workp2 = workp + coll_symbol_length ; workp < workp2 ;
-+ workp++)
-+ {
-+ int32_t *wextra;
-+ wextra = (int32_t*)(extra + *workp++);
-+ for (i = 0; i < *wextra; ++i)
-+ if (TRANSLATE(d[i]) != wextra[1 + i])
-+ break;
-+
-+ if (i == *wextra)
-+ {
-+ /* Update d, however d will be incremented at
-+ char_set_matched:, we decrement d here. */
-+ d += i - 1;
-+ goto char_set_matched;
-+ }
-+ }
-+ }
-+ else /* (nrules == 0) */
-+# endif
-+ /* If we can't look up collation data, we use wcscoll
-+ instead. */
-+ {
-+ for (workp2 = workp + coll_symbol_length ; workp < workp2 ;)
-+ {
-+ const CHAR_T *backup_d = d, *backup_dend = dend;
-+# ifdef _LIBC
-+ length = __wcslen (workp);
-+# else
-+ length = wcslen (workp);
-+# endif
-+
-+ /* If wcscoll(the collating symbol, whole string) > 0,
-+ any substring of the string never match with the
-+ collating symbol. */
-+# ifdef _LIBC
-+ if (__wcscoll (workp, d) > 0)
-+# else
-+ if (wcscoll (workp, d) > 0)
-+# endif
-+ {
-+ workp += length + 1;
-+ continue;
-+ }
-+
-+ /* First, we compare the collating symbol with
-+ the first character of the string.
-+ If it don't match, we add the next character to
-+ the compare buffer in turn. */
-+ for (i = 0 ; i < WORK_BUFFER_SIZE-1 ; i++, d++)
-+ {
-+ int match;
-+ if (d == dend)
-+ {
-+ if (dend == end_match_2)
-+ break;
-+ d = string2;
-+ dend = end_match_2;
-+ }
-+
-+ /* add next character to the compare buffer. */
-+ str_buf[i] = TRANSLATE(*d);
-+ str_buf[i+1] = '\0';
-+
-+# ifdef _LIBC
-+ match = __wcscoll (workp, str_buf);
-+# else
-+ match = wcscoll (workp, str_buf);
-+# endif
-+ if (match == 0)
-+ goto char_set_matched;
-+
-+ if (match < 0)
-+ /* (str_buf > workp) indicate (str_buf + X > workp),
-+ because for all X (str_buf + X > str_buf).
-+ So we don't need continue this loop. */
-+ break;
-+
-+ /* Otherwise(str_buf < workp),
-+ (str_buf+next_character) may equals (workp).
-+ So we continue this loop. */
-+ }
-+ /* not matched */
-+ d = backup_d;
-+ dend = backup_dend;
-+ workp += length + 1;
-+ }
-+ }
-+ /* match with equivalence_class? */
-+# ifdef _LIBC
-+ if (nrules != 0)
-+ {
-+ const CHAR_T *backup_d = d, *backup_dend = dend;
-+ /* Try to match the equivalence class against
-+ those known to the collate implementation. */
-+ const int32_t *table;
-+ const int32_t *weights;
-+ const int32_t *extra;
-+ const int32_t *indirect;
-+ int32_t idx, idx2;
-+ wint_t *cp;
-+ size_t len;
-+
-+ table = (const int32_t *)
-+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
-+ weights = (const wint_t *)
-+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
-+ extra = (const wint_t *)
-+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
-+ indirect = (const int32_t *)
-+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
-+
-+ /* Write 1 collating element to str_buf, and
-+ get its index. */
-+ idx2 = 0;
-+
-+ for (i = 0 ; idx2 == 0 && i < WORK_BUFFER_SIZE - 1; i++)
-+ {
-+ cp = (wint_t*)str_buf;
-+ if (d == dend)
-+ {
-+ if (dend == end_match_2)
-+ break;
-+ d = string2;
-+ dend = end_match_2;
-+ }
-+ str_buf[i] = TRANSLATE(*(d+i));
-+ str_buf[i+1] = '\0'; /* sentinel */
-+ idx2 = FINDIDX (table, indirect, extra, &cp, 1);
-+ }
-+
-+ /* Update d, however d will be incremented at
-+ char_set_matched:, we decrement d here. */
-+ d = backup_d + ((wchar_t*)cp - (wchar_t*)str_buf - 1);
-+ if (d >= dend)
-+ {
-+ if (dend == end_match_2)
-+ d = dend;
-+ else
-+ {
-+ d = string2;
-+ dend = end_match_2;
-+ }
-+ }
-+
-+ len = weights[idx2];
-+
-+ for (workp2 = workp + equiv_class_length ; workp < workp2 ;
-+ workp++)
-+ {
-+ idx = (int32_t)*workp;
-+ /* We already checked idx != 0 in regex_compile. */
-+
-+ if (idx2 != 0 && len == weights[idx])
-+ {
-+ int cnt = 0;
-+ while (cnt < len && (weights[idx + 1 + cnt]
-+ == weights[idx2 + 1 + cnt]))
-+ ++cnt;
-+
-+ if (cnt == len)
-+ goto char_set_matched;
-+ }
-+ }
-+ /* not matched */
-+ d = backup_d;
-+ dend = backup_dend;
-+ }
-+ else /* (nrules == 0) */
-+# endif
-+ /* If we can't look up collation data, we use wcscoll
-+ instead. */
-+ {
-+ for (workp2 = workp + equiv_class_length ; workp < workp2 ;)
-+ {
-+ const CHAR_T *backup_d = d, *backup_dend = dend;
-+# ifdef _LIBC
-+ length = __wcslen (workp);
-+# else
-+ length = wcslen (workp);
-+# endif
-+
-+ /* If wcscoll(the collating symbol, whole string) > 0,
-+ any substring of the string never match with the
-+ collating symbol. */
-+# ifdef _LIBC
-+ if (__wcscoll (workp, d) > 0)
-+# else
-+ if (wcscoll (workp, d) > 0)
-+# endif
-+ {
-+ workp += length + 1;
-+ break;
-+ }
-+
-+ /* First, we compare the equivalence class with
-+ the first character of the string.
-+ If it don't match, we add the next character to
-+ the compare buffer in turn. */
-+ for (i = 0 ; i < WORK_BUFFER_SIZE - 1 ; i++, d++)
-+ {
-+ int match;
-+ if (d == dend)
-+ {
-+ if (dend == end_match_2)
-+ break;
-+ d = string2;
-+ dend = end_match_2;
-+ }
-+
-+ /* add next character to the compare buffer. */
-+ str_buf[i] = TRANSLATE(*d);
-+ str_buf[i+1] = '\0';
-+
-+# ifdef _LIBC
-+ match = __wcscoll (workp, str_buf);
-+# else
-+ match = wcscoll (workp, str_buf);
-+# endif
-+
-+ if (match == 0)
-+ goto char_set_matched;
-+
-+ if (match < 0)
-+ /* (str_buf > workp) indicate (str_buf + X > workp),
-+ because for all X (str_buf + X > str_buf).
-+ So we don't need continue this loop. */
-+ break;
-+
-+ /* Otherwise(str_buf < workp),
-+ (str_buf+next_character) may equals (workp).
-+ So we continue this loop. */
-+ }
-+ /* not matched */
-+ d = backup_d;
-+ dend = backup_dend;
-+ workp += length + 1;
-+ }
-+ }
-+
-+ /* match with char_range? */
-+# ifdef _LIBC
-+ if (nrules != 0)
-+ {
-+ uint32_t collseqval;
-+ const char *collseq = (const char *)
-+ _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
-+
-+ collseqval = collseq_table_lookup (collseq, c);
-+
-+ for (; workp < p - chars_length ;)
-+ {
-+ uint32_t start_val, end_val;
-+
-+ /* We already compute the collation sequence value
-+ of the characters (or collating symbols). */
-+ start_val = (uint32_t) *workp++; /* range_start */
-+ end_val = (uint32_t) *workp++; /* range_end */
-+
-+ if (start_val <= collseqval && collseqval <= end_val)
-+ goto char_set_matched;
-+ }
-+ }
-+ else
-+# endif
-+ {
-+ /* We set range_start_char at str_buf[0], range_end_char
-+ at str_buf[4], and compared char at str_buf[2]. */
-+ str_buf[1] = 0;
-+ str_buf[2] = c;
-+ str_buf[3] = 0;
-+ str_buf[5] = 0;
-+ for (; workp < p - chars_length ;)
-+ {
-+ wchar_t *range_start_char, *range_end_char;
-+
-+ /* match if (range_start_char <= c <= range_end_char). */
-+
-+ /* If range_start(or end) < 0, we assume -range_start(end)
-+ is the offset of the collating symbol which is specified
-+ as the character of the range start(end). */
-+
-+ /* range_start */
-+ if (*workp < 0)
-+ range_start_char = charset_top - (*workp++);
-+ else
-+ {
-+ str_buf[0] = *workp++;
-+ range_start_char = str_buf;
-+ }
-+
-+ /* range_end */
-+ if (*workp < 0)
-+ range_end_char = charset_top - (*workp++);
-+ else
-+ {
-+ str_buf[4] = *workp++;
-+ range_end_char = str_buf + 4;
-+ }
-+
-+# ifdef _LIBC
-+ if (__wcscoll (range_start_char, str_buf+2) <= 0
-+ && __wcscoll (str_buf+2, range_end_char) <= 0)
-+# else
-+ if (wcscoll (range_start_char, str_buf+2) <= 0
-+ && wcscoll (str_buf+2, range_end_char) <= 0)
-+# endif
-+ goto char_set_matched;
-+ }
-+ }
-+
-+ /* match with char? */
-+ for (; workp < p ; workp++)
-+ if (c == *workp)
-+ goto char_set_matched;
-+
-+ negate = !negate;
-+
-+ char_set_matched:
-+ if (negate) goto fail;
-+#else
-+ /* Cast to `unsigned' instead of `unsigned char' in case the
-+ bit list is a full 32 bytes long. */
-+ if (c < (unsigned) (*p * BYTEWIDTH)
-+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
-+ negate = !negate;
-+
-+ p += 1 + *p;
-+
-+ if (!negate) goto fail;
-+#undef WORK_BUFFER_SIZE
-+#endif /* WCHAR */
-+ SET_REGS_MATCHED ();
-+ d++;
-+ break;
-+ }
-+
-+
-+ /* The beginning of a group is represented by start_memory.
-+ The arguments are the register number in the next byte, and the
-+ number of groups inner to this one in the next. The text
-+ matched within the group is recorded (in the internal
-+ registers data structure) under the register number. */
-+ case start_memory:
-+ DEBUG_PRINT3 ("EXECUTING start_memory %ld (%ld):\n",
-+ (long int) *p, (long int) p[1]);
-+
-+ /* Find out if this group can match the empty string. */
-+ p1 = p; /* To send to group_match_null_string_p. */
-+
-+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
-+ REG_MATCH_NULL_STRING_P (reg_info[*p])
-+ = PREFIX(group_match_null_string_p) (&p1, pend, reg_info);
-+
-+ /* Save the position in the string where we were the last time
-+ we were at this open-group operator in case the group is
-+ operated upon by a repetition operator, e.g., with `(a*)*b'
-+ against `ab'; then we want to ignore where we are now in
-+ the string in case this attempt to match fails. */
-+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
-+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
-+ : regstart[*p];
-+ DEBUG_PRINT2 (" old_regstart: %d\n",
-+ POINTER_TO_OFFSET (old_regstart[*p]));
-+
-+ regstart[*p] = d;
-+ DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
-+
-+ IS_ACTIVE (reg_info[*p]) = 1;
-+ MATCHED_SOMETHING (reg_info[*p]) = 0;
-+
-+ /* Clear this whenever we change the register activity status. */
-+ set_regs_matched_done = 0;
-+
-+ /* This is the new highest active register. */
-+ highest_active_reg = *p;
-+
-+ /* If nothing was active before, this is the new lowest active
-+ register. */
-+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
-+ lowest_active_reg = *p;
-+
-+ /* Move past the register number and inner group count. */
-+ p += 2;
-+ just_past_start_mem = p;
-+
-+ break;
-+
-+
-+ /* The stop_memory opcode represents the end of a group. Its
-+ arguments are the same as start_memory's: the register
-+ number, and the number of inner groups. */
-+ case stop_memory:
-+ DEBUG_PRINT3 ("EXECUTING stop_memory %ld (%ld):\n",
-+ (long int) *p, (long int) p[1]);
-+
-+ /* We need to save the string position the last time we were at
-+ this close-group operator in case the group is operated
-+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
-+ against `aba'; then we want to ignore where we are now in
-+ the string in case this attempt to match fails. */
-+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
-+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
-+ : regend[*p];
-+ DEBUG_PRINT2 (" old_regend: %d\n",
-+ POINTER_TO_OFFSET (old_regend[*p]));
-+
-+ regend[*p] = d;
-+ DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
-+
-+ /* This register isn't active anymore. */
-+ IS_ACTIVE (reg_info[*p]) = 0;
-+
-+ /* Clear this whenever we change the register activity status. */
-+ set_regs_matched_done = 0;
-+
-+ /* If this was the only register active, nothing is active
-+ anymore. */
-+ if (lowest_active_reg == highest_active_reg)
-+ {
-+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
-+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
-+ }
-+ else
-+ { /* We must scan for the new highest active register, since
-+ it isn't necessarily one less than now: consider
-+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
-+ new highest active register is 1. */
-+ UCHAR_T r = *p - 1;
-+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
-+ r--;
-+
-+ /* If we end up at register zero, that means that we saved
-+ the registers as the result of an `on_failure_jump', not
-+ a `start_memory', and we jumped to past the innermost
-+ `stop_memory'. For example, in ((.)*) we save
-+ registers 1 and 2 as a result of the *, but when we pop
-+ back to the second ), we are at the stop_memory 1.
-+ Thus, nothing is active. */
-+ if (r == 0)
-+ {
-+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
-+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
-+ }
-+ else
-+ highest_active_reg = r;
-+ }
-+
-+ /* If just failed to match something this time around with a
-+ group that's operated on by a repetition operator, try to
-+ force exit from the ``loop'', and restore the register
-+ information for this group that we had before trying this
-+ last match. */
-+ if ((!MATCHED_SOMETHING (reg_info[*p])
-+ || just_past_start_mem == p - 1)
-+ && (p + 2) < pend)
-+ {
-+ boolean is_a_jump_n = false;
-+
-+ p1 = p + 2;
-+ mcnt = 0;
-+ switch ((re_opcode_t) *p1++)
-+ {
-+ case jump_n:
-+ is_a_jump_n = true;
-+ case pop_failure_jump:
-+ case maybe_pop_jump:
-+ case jump:
-+ case dummy_failure_jump:
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-+ if (is_a_jump_n)
-+ p1 += OFFSET_ADDRESS_SIZE;
-+ break;
-+
-+ default:
-+ /* do nothing */ ;
-+ }
-+ p1 += mcnt;
-+
-+ /* If the next operation is a jump backwards in the pattern
-+ to an on_failure_jump right before the start_memory
-+ corresponding to this stop_memory, exit from the loop
-+ by forcing a failure after pushing on the stack the
-+ on_failure_jump's jump in the pattern, and d. */
-+ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
-+ && (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == start_memory
-+ && p1[2+OFFSET_ADDRESS_SIZE] == *p)
-+ {
-+ /* If this group ever matched anything, then restore
-+ what its registers were before trying this last
-+ failed match, e.g., with `(a*)*b' against `ab' for
-+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
-+ against `aba' for regend[3].
-+
-+ Also restore the registers for inner groups for,
-+ e.g., `((a*)(b*))*' against `aba' (register 3 would
-+ otherwise get trashed). */
-+
-+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
-+ {
-+ unsigned r;
-+
-+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
-+
-+ /* Restore this and inner groups' (if any) registers. */
-+ for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1);
-+ r++)
-+ {
-+ regstart[r] = old_regstart[r];
-+
-+ /* xx why this test? */
-+ if (old_regend[r] >= regstart[r])
-+ regend[r] = old_regend[r];
-+ }
-+ }
-+ p1++;
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
-+
-+ goto fail;
-+ }
-+ }
-+
-+ /* Move past the register number and the inner group count. */
-+ p += 2;
-+ break;
-+
-+
-+ /* \<digit> has been turned into a `duplicate' command which is
-+ followed by the numeric value of <digit> as the register number. */
-+ case duplicate:
-+ {
-+ register const CHAR_T *d2, *dend2;
-+ int regno = *p++; /* Get which register to match against. */
-+ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
-+
-+ /* Can't back reference a group which we've never matched. */
-+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
-+ goto fail;
-+
-+ /* Where in input to try to start matching. */
-+ d2 = regstart[regno];
-+
-+ /* Where to stop matching; if both the place to start and
-+ the place to stop matching are in the same string, then
-+ set to the place to stop, otherwise, for now have to use
-+ the end of the first string. */
-+
-+ dend2 = ((FIRST_STRING_P (regstart[regno])
-+ == FIRST_STRING_P (regend[regno]))
-+ ? regend[regno] : end_match_1);
-+ for (;;)
-+ {
-+ /* If necessary, advance to next segment in register
-+ contents. */
-+ while (d2 == dend2)
-+ {
-+ if (dend2 == end_match_2) break;
-+ if (dend2 == regend[regno]) break;
-+
-+ /* End of string1 => advance to string2. */
-+ d2 = string2;
-+ dend2 = regend[regno];
-+ }
-+ /* At end of register contents => success */
-+ if (d2 == dend2) break;
-+
-+ /* If necessary, advance to next segment in data. */
-+ PREFETCH ();
-+
-+ /* How many characters left in this segment to match. */
-+ mcnt = dend - d;
-+
-+ /* Want how many consecutive characters we can match in
-+ one shot, so, if necessary, adjust the count. */
-+ if (mcnt > dend2 - d2)
-+ mcnt = dend2 - d2;
-+
-+ /* Compare that many; failure if mismatch, else move
-+ past them. */
-+ if (translate
-+ ? PREFIX(bcmp_translate) (d, d2, mcnt, translate)
-+ : memcmp (d, d2, mcnt*sizeof(UCHAR_T)))
-+ goto fail;
-+ d += mcnt, d2 += mcnt;
-+
-+ /* Do this because we've match some characters. */
-+ SET_REGS_MATCHED ();
-+ }
-+ }
-+ break;
-+
-+
-+ /* begline matches the empty string at the beginning of the string
-+ (unless `not_bol' is set in `bufp'), and, if
-+ `newline_anchor' is set, after newlines. */
-+ case begline:
-+ DEBUG_PRINT1 ("EXECUTING begline.\n");
-+
-+ if (AT_STRINGS_BEG (d))
-+ {
-+ if (!bufp->not_bol) break;
-+ }
-+ else if (d[-1] == '\n' && bufp->newline_anchor)
-+ {
-+ break;
-+ }
-+ /* In all other cases, we fail. */
-+ goto fail;
-+
-+
-+ /* endline is the dual of begline. */
-+ case endline:
-+ DEBUG_PRINT1 ("EXECUTING endline.\n");
-+
-+ if (AT_STRINGS_END (d))
-+ {
-+ if (!bufp->not_eol) break;
-+ }
-+
-+ /* We have to ``prefetch'' the next character. */
-+ else if ((d == end1 ? *string2 : *d) == '\n'
-+ && bufp->newline_anchor)
-+ {
-+ break;
-+ }
-+ goto fail;
-+
-+
-+ /* Match at the very beginning of the data. */
-+ case begbuf:
-+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
-+ if (AT_STRINGS_BEG (d))
-+ break;
-+ goto fail;
-+
-+
-+ /* Match at the very end of the data. */
-+ case endbuf:
-+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
-+ if (AT_STRINGS_END (d))
-+ break;
-+ goto fail;
-+
-+
-+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
-+ pushes NULL as the value for the string on the stack. Then
-+ `pop_failure_point' will keep the current value for the
-+ string, instead of restoring it. To see why, consider
-+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
-+ then the . fails against the \n. But the next thing we want
-+ to do is match the \n against the \n; if we restored the
-+ string value, we would be back at the foo.
-+
-+ Because this is used only in specific cases, we don't need to
-+ check all the things that `on_failure_jump' does, to make
-+ sure the right things get saved on the stack. Hence we don't
-+ share its code. The only reason to push anything on the
-+ stack at all is that otherwise we would have to change
-+ `anychar's code to do something besides goto fail in this
-+ case; that seems worse than this. */
-+ case on_failure_keep_string_jump:
-+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
-+
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
-+#ifdef _LIBC
-+ DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt);
-+#else
-+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
-+#endif
-+
-+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
-+ break;
-+
-+
-+ /* Uses of on_failure_jump:
-+
-+ Each alternative starts with an on_failure_jump that points
-+ to the beginning of the next alternative. Each alternative
-+ except the last ends with a jump that in effect jumps past
-+ the rest of the alternatives. (They really jump to the
-+ ending jump of the following alternative, because tensioning
-+ these jumps is a hassle.)
-+
-+ Repeats start with an on_failure_jump that points past both
-+ the repetition text and either the following jump or
-+ pop_failure_jump back to this on_failure_jump. */
-+ case on_failure_jump:
-+ on_failure:
-+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
-+
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
-+#ifdef _LIBC
-+ DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt);
-+#else
-+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
-+#endif
-+
-+ /* If this on_failure_jump comes right before a group (i.e.,
-+ the original * applied to a group), save the information
-+ for that group and all inner ones, so that if we fail back
-+ to this point, the group's information will be correct.
-+ For example, in \(a*\)*\1, we need the preceding group,
-+ and in \(zz\(a*\)b*\)\2, we need the inner group. */
-+
-+ /* We can't use `p' to check ahead because we push
-+ a failure point to `p + mcnt' after we do this. */
-+ p1 = p;
-+
-+ /* We need to skip no_op's before we look for the
-+ start_memory in case this on_failure_jump is happening as
-+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
-+ against aba. */
-+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
-+ p1++;
-+
-+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
-+ {
-+ /* We have a new highest active register now. This will
-+ get reset at the start_memory we are about to get to,
-+ but we will have saved all the registers relevant to
-+ this repetition op, as described above. */
-+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
-+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
-+ lowest_active_reg = *(p1 + 1);
-+ }
-+
-+ DEBUG_PRINT1 (":\n");
-+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
-+ break;
-+
-+
-+ /* A smart repeat ends with `maybe_pop_jump'.
-+ We change it to either `pop_failure_jump' or `jump'. */
-+ case maybe_pop_jump:
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
-+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
-+ {
-+ register UCHAR_T *p2 = p;
-+
-+ /* Compare the beginning of the repeat with what in the
-+ pattern follows its end. If we can establish that there
-+ is nothing that they would both match, i.e., that we
-+ would have to backtrack because of (as in, e.g., `a*a')
-+ then we can change to pop_failure_jump, because we'll
-+ never have to backtrack.
-+
-+ This is not true in the case of alternatives: in
-+ `(a|ab)*' we do need to backtrack to the `ab' alternative
-+ (e.g., if the string was `ab'). But instead of trying to
-+ detect that here, the alternative has put on a dummy
-+ failure point which is what we will end up popping. */
-+
-+ /* Skip over open/close-group commands.
-+ If what follows this loop is a ...+ construct,
-+ look at what begins its body, since we will have to
-+ match at least one of that. */
-+ while (1)
-+ {
-+ if (p2 + 2 < pend
-+ && ((re_opcode_t) *p2 == stop_memory
-+ || (re_opcode_t) *p2 == start_memory))
-+ p2 += 3;
-+ else if (p2 + 2 + 2 * OFFSET_ADDRESS_SIZE < pend
-+ && (re_opcode_t) *p2 == dummy_failure_jump)
-+ p2 += 2 + 2 * OFFSET_ADDRESS_SIZE;
-+ else
-+ break;
-+ }
-+
-+ p1 = p + mcnt;
-+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
-+ to the `maybe_finalize_jump' of this case. Examine what
-+ follows. */
-+
-+ /* If we're at the end of the pattern, we can change. */
-+ if (p2 == pend)
-+ {
-+ /* Consider what happens when matching ":\(.*\)"
-+ against ":/". I don't really understand this code
-+ yet. */
-+ p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
-+ pop_failure_jump;
-+ DEBUG_PRINT1
-+ (" End of pattern: change to `pop_failure_jump'.\n");
-+ }
-+
-+ else if ((re_opcode_t) *p2 == exactn
-+#ifdef MBS_SUPPORT
-+ || (re_opcode_t) *p2 == exactn_bin
-+#endif
-+ || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
-+ {
-+ register UCHAR_T c
-+ = *p2 == (UCHAR_T) endline ? '\n' : p2[2];
-+
-+ if (((re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn
-+#ifdef MBS_SUPPORT
-+ || (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn_bin
-+#endif
-+ ) && p1[3+OFFSET_ADDRESS_SIZE] != c)
-+ {
-+ p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
-+ pop_failure_jump;
-+#ifdef WCHAR
-+ DEBUG_PRINT3 (" %C != %C => pop_failure_jump.\n",
-+ (wint_t) c,
-+ (wint_t) p1[3+OFFSET_ADDRESS_SIZE]);
-+#else
-+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
-+ (char) c,
-+ (char) p1[3+OFFSET_ADDRESS_SIZE]);
-+#endif
-+ }
-+
-+#ifndef WCHAR
-+ else if ((re_opcode_t) p1[3] == charset
-+ || (re_opcode_t) p1[3] == charset_not)
-+ {
-+ int negate = (re_opcode_t) p1[3] == charset_not;
-+
-+ if (c < (unsigned) (p1[4] * BYTEWIDTH)
-+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
-+ negate = !negate;
-+
-+ /* `negate' is equal to 1 if c would match, which means
-+ that we can't change to pop_failure_jump. */
-+ if (!negate)
-+ {
-+ p[-3] = (unsigned char) pop_failure_jump;
-+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
-+ }
-+ }
-+#endif /* not WCHAR */
-+ }
-+#ifndef WCHAR
-+ else if ((re_opcode_t) *p2 == charset)
-+ {
-+ /* We win if the first character of the loop is not part
-+ of the charset. */
-+ if ((re_opcode_t) p1[3] == exactn
-+ && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
-+ && (p2[2 + p1[5] / BYTEWIDTH]
-+ & (1 << (p1[5] % BYTEWIDTH)))))
-+ {
-+ p[-3] = (unsigned char) pop_failure_jump;
-+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
-+ }
-+
-+ else if ((re_opcode_t) p1[3] == charset_not)
-+ {
-+ int idx;
-+ /* We win if the charset_not inside the loop
-+ lists every character listed in the charset after. */
-+ for (idx = 0; idx < (int) p2[1]; idx++)
-+ if (! (p2[2 + idx] == 0
-+ || (idx < (int) p1[4]
-+ && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
-+ break;
-+
-+ if (idx == p2[1])
-+ {
-+ p[-3] = (unsigned char) pop_failure_jump;
-+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
-+ }
-+ }
-+ else if ((re_opcode_t) p1[3] == charset)
-+ {
-+ int idx;
-+ /* We win if the charset inside the loop
-+ has no overlap with the one after the loop. */
-+ for (idx = 0;
-+ idx < (int) p2[1] && idx < (int) p1[4];
-+ idx++)
-+ if ((p2[2 + idx] & p1[5 + idx]) != 0)
-+ break;
-+
-+ if (idx == p2[1] || idx == p1[4])
-+ {
-+ p[-3] = (unsigned char) pop_failure_jump;
-+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
-+ }
-+ }
-+ }
-+#endif /* not WCHAR */
-+ }
-+ p -= OFFSET_ADDRESS_SIZE; /* Point at relative address again. */
-+ if ((re_opcode_t) p[-1] != pop_failure_jump)
-+ {
-+ p[-1] = (UCHAR_T) jump;
-+ DEBUG_PRINT1 (" Match => jump.\n");
-+ goto unconditional_jump;
-+ }
-+ /* Note fall through. */
-+
-+
-+ /* The end of a simple repeat has a pop_failure_jump back to
-+ its matching on_failure_jump, where the latter will push a
-+ failure point. The pop_failure_jump takes off failure
-+ points put on by this pop_failure_jump's matching
-+ on_failure_jump; we got through the pattern to here from the
-+ matching on_failure_jump, so didn't fail. */
-+ case pop_failure_jump:
-+ {
-+ /* We need to pass separate storage for the lowest and
-+ highest registers, even though we don't care about the
-+ actual values. Otherwise, we will restore only one
-+ register from the stack, since lowest will == highest in
-+ `pop_failure_point'. */
-+ active_reg_t dummy_low_reg, dummy_high_reg;
-+ UCHAR_T *pdummy __attribute__ ((unused)) = NULL;
-+ const CHAR_T *sdummy __attribute__ ((unused)) = NULL;
-+
-+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
-+ POP_FAILURE_POINT (sdummy, pdummy,
-+ dummy_low_reg, dummy_high_reg,
-+ reg_dummy, reg_dummy, reg_info_dummy);
-+ }
-+ /* Note fall through. */
-+
-+ unconditional_jump:
-+#ifdef _LIBC
-+ DEBUG_PRINT2 ("\n%p: ", p);
-+#else
-+ DEBUG_PRINT2 ("\n0x%x: ", p);
-+#endif
-+ /* Note fall through. */
-+
-+ /* Unconditionally jump (without popping any failure points). */
-+ case jump:
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
-+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
-+ p += mcnt; /* Do the jump. */
-+#ifdef _LIBC
-+ DEBUG_PRINT2 ("(to %p).\n", p);
-+#else
-+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
-+#endif
-+ break;
-+
-+
-+ /* We need this opcode so we can detect where alternatives end
-+ in `group_match_null_string_p' et al. */
-+ case jump_past_alt:
-+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
-+ goto unconditional_jump;
-+
-+
-+ /* Normally, the on_failure_jump pushes a failure point, which
-+ then gets popped at pop_failure_jump. We will end up at
-+ pop_failure_jump, also, and with a pattern of, say, `a+', we
-+ are skipping over the on_failure_jump, so we have to push
-+ something meaningless for pop_failure_jump to pop. */
-+ case dummy_failure_jump:
-+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
-+ /* It doesn't matter what we push for the string here. What
-+ the code at `fail' tests is the value for the pattern. */
-+ PUSH_FAILURE_POINT (NULL, NULL, -2);
-+ goto unconditional_jump;
-+
-+
-+ /* At the end of an alternative, we need to push a dummy failure
-+ point in case we are followed by a `pop_failure_jump', because
-+ we don't want the failure point for the alternative to be
-+ popped. For example, matching `(a|ab)*' against `aab'
-+ requires that we match the `ab' alternative. */
-+ case push_dummy_failure:
-+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
-+ /* See comments just above at `dummy_failure_jump' about the
-+ two zeroes. */
-+ PUSH_FAILURE_POINT (NULL, NULL, -2);
-+ break;
-+
-+ /* Have to succeed matching what follows at least n times.
-+ After that, handle like `on_failure_jump'. */
-+ case succeed_n:
-+ EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
-+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
-+
-+ assert (mcnt >= 0);
-+ /* Originally, this is how many times we HAVE to succeed. */
-+ if (mcnt > 0)
-+ {
-+ mcnt--;
-+ p += OFFSET_ADDRESS_SIZE;
-+ STORE_NUMBER_AND_INCR (p, mcnt);
-+#ifdef _LIBC
-+ DEBUG_PRINT3 (" Setting %p to %d.\n", p - OFFSET_ADDRESS_SIZE
-+ , mcnt);
-+#else
-+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - OFFSET_ADDRESS_SIZE
-+ , mcnt);
-+#endif
-+ }
-+ else if (mcnt == 0)
-+ {
-+#ifdef _LIBC
-+ DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n",
-+ p + OFFSET_ADDRESS_SIZE);
-+#else
-+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n",
-+ p + OFFSET_ADDRESS_SIZE);
-+#endif /* _LIBC */
-+
-+#ifdef WCHAR
-+ p[1] = (UCHAR_T) no_op;
-+#else
-+ p[2] = (UCHAR_T) no_op;
-+ p[3] = (UCHAR_T) no_op;
-+#endif /* WCHAR */
-+ goto on_failure;
-+ }
-+ break;
-+
-+ case jump_n:
-+ EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
-+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
-+
-+ /* Originally, this is how many times we CAN jump. */
-+ if (mcnt)
-+ {
-+ mcnt--;
-+ STORE_NUMBER (p + OFFSET_ADDRESS_SIZE, mcnt);
-+
-+#ifdef _LIBC
-+ DEBUG_PRINT3 (" Setting %p to %d.\n", p + OFFSET_ADDRESS_SIZE,
-+ mcnt);
-+#else
-+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + OFFSET_ADDRESS_SIZE,
-+ mcnt);
-+#endif /* _LIBC */
-+ goto unconditional_jump;
-+ }
-+ /* If don't have to jump any more, skip over the rest of command. */
-+ else
-+ p += 2 * OFFSET_ADDRESS_SIZE;
-+ break;
-+
-+ case set_number_at:
-+ {
-+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
-+
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
-+ p1 = p + mcnt;
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
-+#ifdef _LIBC
-+ DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt);
-+#else
-+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
-+#endif
-+ STORE_NUMBER (p1, mcnt);
-+ break;
-+ }
-+
-+#if 0
-+ /* The DEC Alpha C compiler 3.x generates incorrect code for the
-+ test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of
-+ AT_WORD_BOUNDARY, so this code is disabled. Expanding the
-+ macro and introducing temporary variables works around the bug. */
-+
-+ case wordbound:
-+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
-+ if (AT_WORD_BOUNDARY (d))
-+ break;
-+ goto fail;
-+
-+ case notwordbound:
-+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
-+ if (AT_WORD_BOUNDARY (d))
-+ goto fail;
-+ break;
-+#else
-+ case wordbound:
-+ {
-+ boolean prevchar, thischar;
-+
-+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
-+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
-+ break;
-+
-+ prevchar = WORDCHAR_P (d - 1);
-+ thischar = WORDCHAR_P (d);
-+ if (prevchar != thischar)
-+ break;
-+ goto fail;
-+ }
-+
-+ case notwordbound:
-+ {
-+ boolean prevchar, thischar;
-+
-+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
-+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
-+ goto fail;
-+
-+ prevchar = WORDCHAR_P (d - 1);
-+ thischar = WORDCHAR_P (d);
-+ if (prevchar != thischar)
-+ goto fail;
-+ break;
-+ }
-+#endif
-+
-+ case wordbeg:
-+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
-+ if (!AT_STRINGS_END (d) && WORDCHAR_P (d)
-+ && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
-+ break;
-+ goto fail;
-+
-+ case wordend:
-+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
-+ if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
-+ && (AT_STRINGS_END (d) || !WORDCHAR_P (d)))
-+ break;
-+ goto fail;
-+
-+#ifdef emacs
-+ case before_dot:
-+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
-+ if (PTR_CHAR_POS ((unsigned char *) d) >= point)
-+ goto fail;
-+ break;
-+
-+ case at_dot:
-+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
-+ if (PTR_CHAR_POS ((unsigned char *) d) != point)
-+ goto fail;
-+ break;
-+
-+ case after_dot:
-+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
-+ if (PTR_CHAR_POS ((unsigned char *) d) <= point)
-+ goto fail;
-+ break;
-+
-+ case syntaxspec:
-+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
-+ mcnt = *p++;
-+ goto matchsyntax;
-+
-+ case wordchar:
-+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
-+ mcnt = (int) Sword;
-+ matchsyntax:
-+ PREFETCH ();
-+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
-+ d++;
-+ if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
-+ goto fail;
-+ SET_REGS_MATCHED ();
-+ break;
-+
-+ case notsyntaxspec:
-+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
-+ mcnt = *p++;
-+ goto matchnotsyntax;
-+
-+ case notwordchar:
-+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
-+ mcnt = (int) Sword;
-+ matchnotsyntax:
-+ PREFETCH ();
-+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
-+ d++;
-+ if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
-+ goto fail;
-+ SET_REGS_MATCHED ();
-+ break;
-+
-+#else /* not emacs */
-+ case wordchar:
-+ DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
-+ PREFETCH ();
-+ if (!WORDCHAR_P (d))
-+ goto fail;
-+ SET_REGS_MATCHED ();
-+ d++;
-+ break;
-+
-+ case notwordchar:
-+ DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
-+ PREFETCH ();
-+ if (WORDCHAR_P (d))
-+ goto fail;
-+ SET_REGS_MATCHED ();
-+ d++;
-+ break;
-+#endif /* not emacs */
-+
-+ default:
-+ abort ();
-+ }
-+ continue; /* Successfully executed one pattern command; keep going. */
-+
-+
-+ /* We goto here if a matching operation fails. */
-+ fail:
-+ if (!FAIL_STACK_EMPTY ())
-+ { /* A restart point is known. Restore to that state. */
-+ DEBUG_PRINT1 ("\nFAIL:\n");
-+ POP_FAILURE_POINT (d, p,
-+ lowest_active_reg, highest_active_reg,
-+ regstart, regend, reg_info);
-+
-+ /* If this failure point is a dummy, try the next one. */
-+ if (!p)
-+ goto fail;
-+
-+ /* If we failed to the end of the pattern, don't examine *p. */
-+ assert (p <= pend);
-+ if (p < pend)
-+ {
-+ boolean is_a_jump_n = false;
-+
-+ /* If failed to a backwards jump that's part of a repetition
-+ loop, need to pop this failure point and use the next one. */
-+ switch ((re_opcode_t) *p)
-+ {
-+ case jump_n:
-+ is_a_jump_n = true;
-+ case maybe_pop_jump:
-+ case pop_failure_jump:
-+ case jump:
-+ p1 = p + 1;
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-+ p1 += mcnt;
-+
-+ if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
-+ || (!is_a_jump_n
-+ && (re_opcode_t) *p1 == on_failure_jump))
-+ goto fail;
-+ break;
-+ default:
-+ /* do nothing */ ;
-+ }
-+ }
-+
-+ if (d >= string1 && d <= end1)
-+ dend = end_match_1;
-+ }
-+ else
-+ break; /* Matching at this starting point really fails. */
-+ } /* for (;;) */
-+
-+ if (best_regs_set)
-+ goto restore_best_regs;
-+
-+ FREE_VARIABLES ();
-+
-+ return -1; /* Failure to match. */
-+} /* re_match_2 */
-+
-+/* Subroutine definitions for re_match_2. */
-+
-+
-+/* We are passed P pointing to a register number after a start_memory.
-+
-+ Return true if the pattern up to the corresponding stop_memory can
-+ match the empty string, and false otherwise.
-+
-+ If we find the matching stop_memory, sets P to point to one past its number.
-+ Otherwise, sets P to an undefined byte less than or equal to END.
-+
-+ We don't handle duplicates properly (yet). */
-+
-+static boolean
-+PREFIX(group_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
-+ PREFIX(register_info_type) *reg_info)
-+{
-+ int mcnt;
-+ /* Point to after the args to the start_memory. */
-+ UCHAR_T *p1 = *p + 2;
-+
-+ while (p1 < end)
-+ {
-+ /* Skip over opcodes that can match nothing, and return true or
-+ false, as appropriate, when we get to one that can't, or to the
-+ matching stop_memory. */
-+
-+ switch ((re_opcode_t) *p1)
-+ {
-+ /* Could be either a loop or a series of alternatives. */
-+ case on_failure_jump:
-+ p1++;
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-+
-+ /* If the next operation is not a jump backwards in the
-+ pattern. */
-+
-+ if (mcnt >= 0)
-+ {
-+ /* Go through the on_failure_jumps of the alternatives,
-+ seeing if any of the alternatives cannot match nothing.
-+ The last alternative starts with only a jump,
-+ whereas the rest start with on_failure_jump and end
-+ with a jump, e.g., here is the pattern for `a|b|c':
-+
-+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
-+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
-+ /exactn/1/c
-+
-+ So, we have to first go through the first (n-1)
-+ alternatives and then deal with the last one separately. */
-+
-+
-+ /* Deal with the first (n-1) alternatives, which start
-+ with an on_failure_jump (see above) that jumps to right
-+ past a jump_past_alt. */
-+
-+ while ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] ==
-+ jump_past_alt)
-+ {
-+ /* `mcnt' holds how many bytes long the alternative
-+ is, including the ending `jump_past_alt' and
-+ its number. */
-+
-+ if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt -
-+ (1 + OFFSET_ADDRESS_SIZE),
-+ reg_info))
-+ return false;
-+
-+ /* Move to right after this alternative, including the
-+ jump_past_alt. */
-+ p1 += mcnt;
-+
-+ /* Break if it's the beginning of an n-th alternative
-+ that doesn't begin with an on_failure_jump. */
-+ if ((re_opcode_t) *p1 != on_failure_jump)
-+ break;
-+
-+ /* Still have to check that it's not an n-th
-+ alternative that starts with an on_failure_jump. */
-+ p1++;
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-+ if ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] !=
-+ jump_past_alt)
-+ {
-+ /* Get to the beginning of the n-th alternative. */
-+ p1 -= 1 + OFFSET_ADDRESS_SIZE;
-+ break;
-+ }
-+ }
-+
-+ /* Deal with the last alternative: go back and get number
-+ of the `jump_past_alt' just before it. `mcnt' contains
-+ the length of the alternative. */
-+ EXTRACT_NUMBER (mcnt, p1 - OFFSET_ADDRESS_SIZE);
-+
-+ if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt, reg_info))
-+ return false;
-+
-+ p1 += mcnt; /* Get past the n-th alternative. */
-+ } /* if mcnt > 0 */
-+ break;
-+
-+
-+ case stop_memory:
-+ assert (p1[1] == **p);
-+ *p = p1 + 2;
-+ return true;
-+
-+
-+ default:
-+ if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
-+ return false;
-+ }
-+ } /* while p1 < end */
-+
-+ return false;
-+} /* group_match_null_string_p */
-+
-+
-+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
-+ It expects P to be the first byte of a single alternative and END one
-+ byte past the last. The alternative can contain groups. */
-+
-+static boolean
-+PREFIX(alt_match_null_string_p) (UCHAR_T *p, UCHAR_T *end,
-+ PREFIX(register_info_type) *reg_info)
-+{
-+ int mcnt;
-+ UCHAR_T *p1 = p;
-+
-+ while (p1 < end)
-+ {
-+ /* Skip over opcodes that can match nothing, and break when we get
-+ to one that can't. */
-+
-+ switch ((re_opcode_t) *p1)
-+ {
-+ /* It's a loop. */
-+ case on_failure_jump:
-+ p1++;
-+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-+ p1 += mcnt;
-+ break;
-+
-+ default:
-+ if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
-+ return false;
-+ }
-+ } /* while p1 < end */
-+
-+ return true;
-+} /* alt_match_null_string_p */
-+
-+
-+/* Deals with the ops common to group_match_null_string_p and
-+ alt_match_null_string_p.
-+
-+ Sets P to one after the op and its arguments, if any. */
-+
-+static boolean
-+PREFIX(common_op_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
-+ PREFIX(register_info_type) *reg_info)
-+{
-+ int mcnt;
-+ boolean ret;
-+ int reg_no;
-+ UCHAR_T *p1 = *p;
-+
-+ switch ((re_opcode_t) *p1++)
-+ {
-+ case no_op:
-+ case begline:
-+ case endline:
-+ case begbuf:
-+ case endbuf:
-+ case wordbeg:
-+ case wordend:
-+ case wordbound:
-+ case notwordbound:
-+#ifdef emacs
-+ case before_dot:
-+ case at_dot:
-+ case after_dot:
-+#endif
-+ break;
-+
-+ case start_memory:
-+ reg_no = *p1;
-+ assert (reg_no > 0 && reg_no <= MAX_REGNUM);
-+ ret = PREFIX(group_match_null_string_p) (&p1, end, reg_info);
-+
-+ /* Have to set this here in case we're checking a group which
-+ contains a group and a back reference to it. */
-+
-+ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
-+ REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
-+
-+ if (!ret)
-+ return fals