diff options
author | Khem Raj <raj.khem@gmail.com> | 2016-01-02 21:37:22 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-02-21 09:32:01 +0000 |
commit | 9c3d461c4d54d684b38ec4c038a1c3c2fb9923f0 (patch) | |
tree | d4974d75c8003d3b5bd2ee5093662b00ed682975 /meta | |
parent | 6eb64cdd5296c42a46f3485bca403814eec55b2c (diff) | |
download | openembedded-core-contrib-9c3d461c4d54d684b38ec4c038a1c3c2fb9923f0.tar.gz |
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>
Diffstat (limited to 'meta')
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 5622f3ec16f..c412420eaf8 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 efcdf4dc63b..fa930fd4804 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 7214f714043..5975fd26c7a 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 8ab01dc79d4..e86770e12d4 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 f7702e0358c..f7702e0358c 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 0b69bad46a3..0b69bad46a3 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 9fd27f32f9a..00000000000 --- 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 5a89bd8022a..5a89bd8022a 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 7c4551a4aa1..5711209c715 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 3d663481336..97c280059fe 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 b568fc6bdc2..473b89449df 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 a681a64e851..dde94b450c8 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 748750304f3..00000000000 --- 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 00000000000..21f04a1321a --- /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 8d3f859555e..ba8c92e1122 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 65c227ff20b..086a73dd26b 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 aec8fbeb9ad..952784b1cc7 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 b3fa931c6c8..8d513ab42ac 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 1f5475912c4..12f24fb6852 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 df3c1ef21f6..77bd7d13241 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 07a112b2181..251e5f5af30 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 267791393e0..3208a0c89b6 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 c1fda9d433f..82fa1004423 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 0ba5d2fbad5..ea3e1670f85 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 4b261ca1ef3..00000000000 --- 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 089e8b1b0b8..90e12b88352 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 0ce823087d2..e51b611f377 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 c306ce6afe2..0c9ae6c139e 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 8eacbc059fe..e282e60ebd0 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 dcb80f9c803..00000000000 --- 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 df93094543e..c04e0a11d41 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 38bb8a15e3b..4362efae777 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 8a4c9c3e89b..225f22f013d 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 9f3d753d70f..88b20f67adb 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 c359cce9c56..d95ea3ba3d4 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 0514e282e69..00000000000 --- 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 (®ex, '\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 false; -+ break; -+ -+ /* If this is an optimized succeed_n for zero times, make the jump. */ -+ case jump: -+ EXTRACT_NUMBER_AND_INCR (mcnt, p1); -+ if (mcnt >= 0) -+ p1 += mcnt; -+ else -+ return false; -+ break; -+ -+ case succeed_n: -+ /* Get to the number of times to succeed. */ -+ p1 += OFFSET_ADDRESS_SIZE; -+ EXTRACT_NUMBER_AND_INCR (mcnt, p1); -+ -+ if (mcnt == 0) -+ { -+ p1 -= 2 * OFFSET_ADDRESS_SIZE; -+ EXTRACT_NUMBER_AND_INCR (mcnt, p1); -+ p1 += mcnt; -+ } -+ else -+ return false; -+ break; -+ -+ case duplicate: -+ if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) -+ return false; -+ break; -+ -+ case set_number_at: -+ p1 += 2 * OFFSET_ADDRESS_SIZE; -+ -+ default: -+ /* All other opcodes mean we cannot match the empty string. */ -+ return false; -+ } -+ -+ *p = p1; -+ return true; -+} /* common_op_match_null_string_p */ -+ -+ -+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN -+ bytes; nonzero otherwise. */ -+ -+static int -+PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, register int len, -+ RE_TRANSLATE_TYPE translate) -+{ -+ register const UCHAR_T *p1 = (const UCHAR_T *) s1; -+ register const UCHAR_T *p2 = (const UCHAR_T *) s2; -+ while (len) -+ { -+#ifdef WCHAR -+ if (((*p1<=0xff)?translate[*p1++]:*p1++) -+ != ((*p2<=0xff)?translate[*p2++]:*p2++)) -+ return 1; -+#else /* BYTE */ -+ if (translate[*p1++] != translate[*p2++]) return 1; -+#endif /* WCHAR */ -+ len--; -+ } -+ return 0; -+} -+ -+ -+#else /* not INSIDE_RECURSION */ -+ -+/* Entry points for GNU code. */ -+ -+/* re_compile_pattern is the GNU regular expression compiler: it -+ compiles PATTERN (of length SIZE) and puts the result in BUFP. -+ Returns 0 if the pattern was valid, otherwise an error string. -+ -+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields -+ are set in BUFP on entry. -+ -+ We call regex_compile to do the actual compilation. */ -+ -+const char * -+re_compile_pattern (const char *pattern, size_t length, -+ struct re_pattern_buffer *bufp) -+{ -+ reg_errcode_t ret; -+ -+ /* GNU code is written to assume at least RE_NREGS registers will be set -+ (and at least one extra will be -1). */ -+ bufp->regs_allocated = REGS_UNALLOCATED; -+ -+ /* And GNU code determines whether or not to get register information -+ by passing null for the REGS argument to re_match, etc., not by -+ setting no_sub. */ -+ bufp->no_sub = 0; -+ -+ /* Match anchors at newline. */ -+ bufp->newline_anchor = 1; -+ -+# ifdef MBS_SUPPORT -+ if (MB_CUR_MAX != 1) -+ ret = wcs_regex_compile (pattern, length, re_syntax_options, bufp); -+ else -+# endif -+ ret = byte_regex_compile (pattern, length, re_syntax_options, bufp); -+ -+ if (!ret) -+ return NULL; -+ return gettext (re_error_msgid[(int) ret]); -+} -+#ifdef _LIBC -+weak_alias (__re_compile_pattern, re_compile_pattern) -+#endif -+ -+/* Entry points compatible with 4.2 BSD regex library. We don't define -+ them unless specifically requested. */ -+ -+#if defined _REGEX_RE_COMP || defined _LIBC -+ -+/* BSD has one and only one pattern buffer. */ -+static struct re_pattern_buffer re_comp_buf; -+ -+char * -+#ifdef _LIBC -+/* Make these definitions weak in libc, so POSIX programs can redefine -+ these names if they don't use our functions, and still use -+ regcomp/regexec below without link errors. */ -+weak_function -+#endif -+re_comp (const char *s) -+{ -+ reg_errcode_t ret; -+ -+ if (!s) -+ { -+ if (!re_comp_buf.buffer) -+ return (char *) gettext ("No previous regular expression"); -+ return 0; -+ } -+ -+ if (!re_comp_buf.buffer) -+ { -+ re_comp_buf.buffer = (unsigned char *) malloc (200); -+ if (re_comp_buf.buffer == NULL) -+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); -+ re_comp_buf.allocated = 200; -+ -+ re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); -+ if (re_comp_buf.fastmap == NULL) -+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); -+ } -+ -+ /* Since `re_exec' always passes NULL for the `regs' argument, we -+ don't need to initialize the pattern buffer fields which affect it. */ -+ -+ /* Match anchors at newlines. */ -+ re_comp_buf.newline_anchor = 1; -+ -+# ifdef MBS_SUPPORT -+ if (MB_CUR_MAX != 1) -+ ret = wcs_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); -+ else -+# endif -+ ret = byte_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); -+ -+ if (!ret) -+ return NULL; -+ -+ /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ -+ return (char *) gettext (re_error_msgid[(int) ret]); -+} -+ -+ -+int -+#ifdef _LIBC -+weak_function -+#endif -+re_exec (const char *s) -+{ -+ const int len = strlen (s); -+ return -+ 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); -+} -+ -+#endif /* _REGEX_RE_COMP */ -+ -+/* POSIX.2 functions. Don't define these for Emacs. */ -+ -+#ifndef emacs -+ -+/* regcomp takes a regular expression as a string and compiles it. -+ -+ PREG is a regex_t *. We do not expect any fields to be initialized, -+ since POSIX says we shouldn't. Thus, we set -+ -+ `buffer' to the compiled pattern; -+ `used' to the length of the compiled pattern; -+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the -+ REG_EXTENDED bit in CFLAGS is set; otherwise, to -+ RE_SYNTAX_POSIX_BASIC; -+ `newline_anchor' to REG_NEWLINE being set in CFLAGS; -+ `fastmap' to an allocated space for the fastmap; -+ `fastmap_accurate' to zero; -+ `re_nsub' to the number of subexpressions in PATTERN. -+ -+ PATTERN is the address of the pattern string. -+ -+ CFLAGS is a series of bits which affect compilation. -+ -+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we -+ use POSIX basic syntax. -+ -+ If REG_NEWLINE is set, then . and [^...] don't match newline. -+ Also, regexec will try a match beginning after every newline. -+ -+ If REG_ICASE is set, then we considers upper- and lowercase -+ versions of letters to be equivalent when matching. -+ -+ If REG_NOSUB is set, then when PREG is passed to regexec, that -+ routine will report only success or failure, and nothing about the -+ registers. -+ -+ It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for -+ the return codes and their meanings.) */ -+ -+int -+regcomp (regex_t *preg, const char *pattern, int cflags) -+{ -+ reg_errcode_t ret; -+ reg_syntax_t syntax -+ = (cflags & REG_EXTENDED) ? -+ RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; -+ -+ /* regex_compile will allocate the space for the compiled pattern. */ -+ preg->buffer = 0; -+ preg->allocated = 0; -+ preg->used = 0; -+ -+ /* Try to allocate space for the fastmap. */ -+ preg->fastmap = (char *) malloc (1 << BYTEWIDTH); -+ -+ if (cflags & REG_ICASE) -+ { -+ int i; -+ -+ preg->translate -+ = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE -+ * sizeof (*(RE_TRANSLATE_TYPE)0)); -+ if (preg->translate == NULL) -+ return (int) REG_ESPACE; -+ -+ /* Map uppercase characters to corresponding lowercase ones. */ -+ for (i = 0; i < CHAR_SET_SIZE; i++) -+ preg->translate[i] = ISUPPER (i) ? TOLOWER (i) : i; -+ } -+ else -+ preg->translate = NULL; -+ -+ /* If REG_NEWLINE is set, newlines are treated differently. */ -+ if (cflags & REG_NEWLINE) -+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */ -+ syntax &= ~RE_DOT_NEWLINE; -+ syntax |= RE_HAT_LISTS_NOT_NEWLINE; -+ /* It also changes the matching behavior. */ -+ preg->newline_anchor = 1; -+ } -+ else -+ preg->newline_anchor = 0; -+ -+ preg->no_sub = !!(cflags & REG_NOSUB); -+ -+ /* POSIX says a null character in the pattern terminates it, so we -+ can use strlen here in compiling the pattern. */ -+# ifdef MBS_SUPPORT -+ if (MB_CUR_MAX != 1) -+ ret = wcs_regex_compile (pattern, strlen (pattern), syntax, preg); -+ else -+# endif -+ ret = byte_regex_compile (pattern, strlen (pattern), syntax, preg); -+ -+ /* POSIX doesn't distinguish between an unmatched open-group and an -+ unmatched close-group: both are REG_EPAREN. */ -+ if (ret == REG_ERPAREN) ret = REG_EPAREN; -+ -+ if (ret == REG_NOERROR && preg->fastmap) -+ { -+ /* Compute the fastmap now, since regexec cannot modify the pattern -+ buffer. */ -+ if (re_compile_fastmap (preg) == -2) -+ { -+ /* Some error occurred while computing the fastmap, just forget -+ about it. */ -+ free (preg->fastmap); -+ preg->fastmap = NULL; -+ } -+ } -+ -+ return (int) ret; -+} -+#ifdef _LIBC -+weak_alias (__regcomp, regcomp) -+#endif -+ -+ -+/* regexec searches for a given pattern, specified by PREG, in the -+ string STRING. -+ -+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to -+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at -+ least NMATCH elements, and we set them to the offsets of the -+ corresponding matched substrings. -+ -+ EFLAGS specifies `execution flags' which affect matching: if -+ REG_NOTBOL is set, then ^ does not match at the beginning of the -+ string; if REG_NOTEOL is set, then $ does not match at the end. -+ -+ We return 0 if we find a match and REG_NOMATCH if not. */ -+ -+int -+regexec (const regex_t *preg, const char *string, size_t nmatch, -+ regmatch_t pmatch[], int eflags) -+{ -+ int ret; -+ struct re_registers regs; -+ regex_t private_preg; -+ int len = strlen (string); -+ boolean want_reg_info = !preg->no_sub && nmatch > 0; -+ -+ private_preg = *preg; -+ -+ private_preg.not_bol = !!(eflags & REG_NOTBOL); -+ private_preg.not_eol = !!(eflags & REG_NOTEOL); -+ -+ /* The user has told us exactly how many registers to return -+ information about, via `nmatch'. We have to pass that on to the -+ matching routines. */ -+ private_preg.regs_allocated = REGS_FIXED; -+ -+ if (want_reg_info) -+ { -+ regs.num_regs = nmatch; -+ regs.start = TALLOC (nmatch * 2, regoff_t); -+ if (regs.start == NULL) -+ return (int) REG_NOMATCH; -+ regs.end = regs.start + nmatch; -+ } -+ -+ /* Perform the searching operation. */ -+ ret = re_search (&private_preg, string, len, -+ /* start: */ 0, /* range: */ len, -+ want_reg_info ? ®s : (struct re_registers *) 0); -+ -+ /* Copy the register information to the POSIX structure. */ -+ if (want_reg_info) -+ { -+ if (ret >= 0) -+ { -+ unsigned r; -+ -+ for (r = 0; r < nmatch; r++) -+ { -+ pmatch[r].rm_so = regs.start[r]; -+ pmatch[r].rm_eo = regs.end[r]; -+ } -+ } -+ -+ /* If we needed the temporary register info, free the space now. */ -+ free (regs.start); -+ } -+ -+ /* We want zero return to mean success, unlike `re_search'. */ -+ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; -+} -+#ifdef _LIBC -+/* EGLIBC: This is handled in regexec-compat.c. */ -+/*weak_alias (__regexec, regexec)*/ -+#include "regexec-compat.c" -+#endif -+ -+ -+/* Returns a message corresponding to an error code, ERRCODE, returned -+ from either regcomp or regexec. We don't use PREG here. */ -+ -+size_t -+regerror (int errcode, const regex_t *preg __attribute__ ((unused)), -+ char *errbuf, size_t errbuf_size) -+{ -+ const char *msg; -+ size_t msg_size; -+ -+ if (errcode < 0 -+ || errcode >= (int) (sizeof (re_error_msgid) -+ / sizeof (re_error_msgid[0]))) -+ /* Only error codes returned by the rest of the code should be passed -+ to this routine. If we are given anything else, or if other regex -+ code generates an invalid error code, then the program has a bug. -+ Dump core so we can fix it. */ -+ abort (); -+ -+ msg = gettext (re_error_msgid[errcode]); -+ -+ msg_size = strlen (msg) + 1; /* Includes the null. */ -+ -+ if (errbuf_size != 0) -+ { -+ if (msg_size > errbuf_size) -+ { -+#if defined HAVE_MEMPCPY || defined _LIBC -+ *((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0'; -+#else -+ memcpy (errbuf, msg, errbuf_size - 1); -+ errbuf[errbuf_size - 1] = 0; -+#endif -+ } -+ else -+ memcpy (errbuf, msg, msg_size); -+ } -+ -+ return msg_size; -+} -+#ifdef _LIBC -+weak_alias (__regerror, regerror) -+#endif -+ -+ -+/* Free dynamically allocated space used by PREG. */ -+ -+void -+regfree (regex_t *preg) -+{ -+ if (preg->buffer != NULL) -+ free (preg->buffer); -+ preg->buffer = NULL; -+ -+ preg->allocated = 0; -+ preg->used = 0; -+ -+ if (preg->fastmap != NULL) -+ free (preg->fastmap); -+ preg->fastmap = NULL; -+ preg->fastmap_accurate = 0; -+ -+ if (preg->translate != NULL) -+ free (preg->translate); -+ preg->translate = NULL; -+} -+#ifdef _LIBC -+weak_alias (__regfree, regfree) -+#endif -+ -+#endif /* not emacs */ -+ -+#endif /* not INSIDE_RECURSION */ -+ -+ -+#undef STORE_NUMBER -+#undef STORE_NUMBER_AND_INCR -+#undef EXTRACT_NUMBER -+#undef EXTRACT_NUMBER_AND_INCR -+ -+#undef DEBUG_PRINT_COMPILED_PATTERN -+#undef DEBUG_PRINT_DOUBLE_STRING -+ -+#undef INIT_FAIL_STACK -+#undef RESET_FAIL_STACK -+#undef DOUBLE_FAIL_STACK -+#undef PUSH_PATTERN_OP -+#undef PUSH_FAILURE_POINTER -+#undef PUSH_FAILURE_INT -+#undef PUSH_FAILURE_ELT -+#undef POP_FAILURE_POINTER -+#undef POP_FAILURE_INT -+#undef POP_FAILURE_ELT -+#undef DEBUG_PUSH -+#undef DEBUG_POP -+#undef PUSH_FAILURE_POINT -+#undef POP_FAILURE_POINT -+ -+#undef REG_UNSET_VALUE -+#undef REG_UNSET -+ -+#undef PATFETCH -+#undef PATFETCH_RAW -+#undef PATUNFETCH -+#undef TRANSLATE -+ -+#undef INIT_BUF_SIZE -+#undef GET_BUFFER_SPACE -+#undef BUF_PUSH -+#undef BUF_PUSH_2 -+#undef BUF_PUSH_3 -+#undef STORE_JUMP -+#undef STORE_JUMP2 -+#undef INSERT_JUMP -+#undef INSERT_JUMP2 -+#undef EXTEND_BUFFER -+#undef GET_UNSIGNED_NUMBER -+#undef FREE_STACK_RETURN -+ -+# undef POINTER_TO_OFFSET -+# undef MATCHING_IN_FRST_STRING -+# undef PREFETCH -+# undef AT_STRINGS_BEG -+# undef AT_STRINGS_END -+# undef WORDCHAR_P -+# undef FREE_VAR -+# undef FREE_VARIABLES -+# undef NO_HIGHEST_ACTIVE_REG -+# undef NO_LOWEST_ACTIVE_REG -+ -+# undef CHAR_T -+# undef UCHAR_T -+# undef COMPILED_BUFFER_VAR -+# undef OFFSET_ADDRESS_SIZE -+# undef CHAR_CLASS_SIZE -+# undef PREFIX -+# undef ARG_PREFIX -+# undef PUT_CHAR -+# undef BYTE -+# undef WCHAR -+ -+# define DEFINED_ONCE -diff --git a/pwd/Makefile b/pwd/Makefile -index 7f6de03..916d546 100644 ---- a/pwd/Makefile -+++ b/pwd/Makefile -@@ -18,6 +18,8 @@ - # - # Sub-makefile for pwd portion of the library. - # -+include ../option-groups.mak -+ - subdir := pwd - - include ../Makeconfig -diff --git a/resolv/Makefile b/resolv/Makefile -index 1dcb75f..2e4b630 100644 ---- a/resolv/Makefile -+++ b/resolv/Makefile -@@ -18,6 +18,8 @@ - # - # Sub-makefile for resolv portion of the library. - # -+include ../option-groups.mak -+ - subdir := resolv - - include ../Makeconfig -@@ -27,21 +29,22 @@ headers := resolv.h \ - arpa/nameser.h arpa/nameser_compat.h \ - sys/bitypes.h - --routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ -- res_hconf res_libc res-state -+routines-$(OPTION_EGLIBC_INET) \ -+ += herror inet_addr inet_ntop inet_pton nsap_addr res_init \ -+ res_hconf res_libc res-state - --tests = tst-aton tst-leaks tst-inet_ntop --xtests = tst-leaks2 -+tests-$(OPTION_EGLIBC_INET) += tst-aton tst-leaks tst-inet_ntop -+xtests-$(OPTION_EGLIBC_INET) += tst-leaks2 - - generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace - --extra-libs := libresolv libnss_dns -+extra-libs-$(OPTION_EGLIBC_INET) += libresolv libnss_dns - ifeq ($(have-thread-library),yes) --extra-libs += libanl --routines += gai_sigqueue -+extra-libs-$(OPTION_EGLIBC_INET_ANL) += libanl -+routines-$(OPTION_EGLIBC_INET) += gai_sigqueue - tests += tst-res_hconf_reorder - endif --extra-libs-others = $(extra-libs) -+extra-libs-others-y += $(extra-libs-y) - libresolv-routines := gethnamaddr res_comp res_debug \ - res_data res_mkquery res_query res_send \ - inet_net_ntop inet_net_pton inet_neta base64 \ -@@ -61,7 +64,7 @@ routines += $(libnss_dns-routines) $(libresolv-routines) - static-only-routines += $(libnss_dns-routines) $(libresolv-routines) - endif - --ifeq (yesyes,$(build-shared)$(have-thread-library)) -+ifeq (yesyesy,$(build-shared)$(have-thread-library)$(OPTION_EGLIBC_INET_ANL)) - tests: $(objpfx)ga_test - endif - -diff --git a/stdio-common/Makefile b/stdio-common/Makefile -index d0bf0e1..8655801 100644 ---- a/stdio-common/Makefile -+++ b/stdio-common/Makefile -@@ -18,6 +18,8 @@ - # - # Specific makefile for stdio-common. - # -+include ../option-groups.mak -+ - subdir := stdio-common - - include ../Makeconfig -@@ -30,7 +32,7 @@ routines := \ - vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex \ - reg-modifier reg-type \ - printf_size fprintf printf snprintf sprintf asprintf dprintf \ -- vfwprintf vfscanf vfwscanf \ -+ vfscanf \ - fscanf scanf sscanf \ - perror psignal \ - tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \ -@@ -41,23 +43,36 @@ routines := \ - isoc99_vsscanf \ - psiginfo - --aux := errlist siglist printf-parsemb printf-parsewc fxprintf -+# Ideally, _itowa and itowa-digits would be in this option group as -+# well, but it is used unconditionally by printf_fp and printf_fphex, -+# and it didn't seem straightforward to disentangle it. -+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ -+ += vfwprintf vfwscanf -+ -+aux := errlist siglist printf-parsemb fxprintf -+aux-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += printf-parsewc - - tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ - temptest tst-fileno test-fwrite tst-ungetc tst-ferror \ - xbug errnobug \ - bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \ -- tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \ -+ tfformat tiformat tllformat tstdiomisc tst-printfsz \ - scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \ -- scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \ -- tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \ -- tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \ -+ scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \ -+ tst-fseek tst-fmemopen tst-gets \ -+ tst-sprintf tst-rndseek tst-fdopen tst-fphex \ - tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \ -- tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \ -- bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \ -- scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \ -- bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \ -+ tst-fwrite bug16 bug17 tst-sprintf2 bug18 \ -+ bug19 tst-popen2 scanf14 scanf15 bug21 bug22 \ -+ scanf16 scanf17 tst-setvbuf1 bug23 bug24 \ -+ bug-vfprintf-nargs tst-sprintf3 \ - bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3 -+tests-$(OPTION_EGLIBC_LOCALE_CODE) \ -+ += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping -+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \ -+ += tst-perror bug19a bug20 tst-long-dbl-fphex tst-fphex-wide -+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ -+ += bug18a tst-swscanf tst-wc-printf - - test-srcs = tst-unbputc tst-printf - -diff --git a/stdio-common/_i18n_number.h b/stdio-common/_i18n_number.h -index 3c73044..ac62b3a 100644 ---- a/stdio-common/_i18n_number.h -+++ b/stdio-common/_i18n_number.h -@@ -19,10 +19,13 @@ - #include <stdbool.h> - #include <wchar.h> - #include <wctype.h> -+#include <gnu/option-groups.h> - - #include "../locale/outdigits.h" - #include "../locale/outdigitswc.h" - -+#if __OPTION_EGLIBC_LOCALE_CODE -+ - static CHAR_T * - _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end) - { -@@ -115,3 +118,13 @@ _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end) - - return w; - } -+ -+#else -+ -+static CHAR_T * -+_i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end) -+{ -+ return w; -+} -+ -+#endif -diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c -index 7b2eb94..8476076 100644 ---- a/stdio-common/fxprintf.c -+++ b/stdio-common/fxprintf.c -@@ -23,6 +23,7 @@ - #include <wchar.h> - #include <string.h> - #include <libioP.h> -+#include <gnu/option-groups.h> - - - int -@@ -37,6 +38,7 @@ __fxprintf (FILE *fp, const char *fmt, ...) - int res; - if (_IO_fwide (fp, 0) > 0) - { -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - size_t len = strlen (fmt) + 1; - wchar_t wfmt[len]; - for (size_t i = 0; i < len; ++i) -@@ -45,6 +47,9 @@ __fxprintf (FILE *fp, const char *fmt, ...) - wfmt[i] = fmt[i]; - } - res = __vfwprintf (fp, wfmt, ap); -+#else -+ abort(); -+#endif - } - else - res = _IO_vfprintf (fp, fmt, ap); -diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c -index 3023b20..bd0df66 100644 ---- a/stdio-common/printf_fp.c -+++ b/stdio-common/printf_fp.c -@@ -39,6 +39,7 @@ - #include <unistd.h> - #include <stdlib.h> - #include <wchar.h> -+#include <gnu/option-groups.h> - #include <stdbool.h> - #include <rounding-mode.h> - -@@ -142,6 +143,10 @@ extern mp_size_t __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, - extern unsigned int __guess_grouping (unsigned int intdig_max, - const char *grouping); - -+/* Ideally, when OPTION_EGLIBC_LOCALE_CODE is disabled, this should do -+ all its work in ordinary characters, rather than doing it in wide -+ characters and then converting at the end. But that is a challenge -+ for another day. */ - - static wchar_t *group_number (wchar_t *buf, wchar_t *bufend, - unsigned int intdig_no, const char *grouping, -@@ -251,7 +256,14 @@ ___printf_fp (FILE *fp, - mp_limb_t cy; - - /* Nonzero if this is output on a wide character stream. */ -+#if __OPTION_POSIX_C_LANG_WIDE_CHAR - int wide = info->wide; -+#else -+ /* This should never be called on a wide-oriented stream when -+ OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't -+ be trusted to figure that out. */ -+ const int wide = 0; -+#endif - - /* Buffer in which we produce the output. */ - wchar_t *wbuffer = NULL; -@@ -261,6 +273,7 @@ ___printf_fp (FILE *fp, - p.expsign = 0; - - /* Figure out the decimal point character. */ -+#if __OPTION_EGLIBC_LOCALE_CODE - if (info->extra == 0) - { - decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); -@@ -280,7 +293,13 @@ ___printf_fp (FILE *fp, - /* The decimal point character must not be zero. */ - assert (*decimal != '\0'); - assert (decimalwc != L'\0'); -+#else -+ /* Hard-code values from 'C' locale. */ -+ decimal = "."; -+ decimalwc = L'.'; -+#endif - -+#if __OPTION_EGLIBC_LOCALE_CODE - if (info->group) - { - if (info->extra == 0) -@@ -324,6 +343,9 @@ ___printf_fp (FILE *fp, - } - else - grouping = NULL; -+#else -+ grouping = NULL; -+#endif - - /* Fetch the argument value. */ - #ifndef __NO_LONG_DOUBLE_MATH -diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c -index 6c3b5e9..f660ce0 100644 ---- a/stdio-common/printf_fphex.c -+++ b/stdio-common/printf_fphex.c -@@ -28,6 +28,7 @@ - #include <_itoa.h> - #include <_itowa.h> - #include <locale/localeinfo.h> -+#include <gnu/option-groups.h> - #include <stdbool.h> - #include <rounding-mode.h> - -@@ -139,10 +140,18 @@ __printf_fphex (FILE *fp, - int done = 0; - - /* Nonzero if this is output on a wide character stream. */ -+#if __OPTION_POSIX_C_LANG_WIDE_CHAR - int wide = info->wide; -+#else -+ /* This should never be called on a wide-oriented stream when -+ OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't -+ be trusted to figure that out. */ -+ const int wide = 0; -+#endif - - - /* Figure out the decimal point character. */ -+#if __OPTION_EGLIBC_LOCALE_CODE - if (info->extra == 0) - { - decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); -@@ -156,6 +165,10 @@ __printf_fphex (FILE *fp, - } - /* The decimal point character must never be zero. */ - assert (*decimal != '\0' && decimalwc != L'\0'); -+#else -+ decimal = "."; -+ decimalwc = L'.'; -+#endif - - - /* Fetch the argument value. */ -diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c -index 7dcd58e..6fb7491 100644 ---- a/stdio-common/printf_size.c -+++ b/stdio-common/printf_size.c -@@ -23,6 +23,7 @@ - #include <math.h> - #include <printf.h> - #include <libioP.h> -+#include <gnu/option-groups.h> - - - /* This defines make it possible to use the same code for GNU C library and -@@ -116,7 +117,14 @@ __printf_size (FILE *fp, const struct printf_info *info, - - struct printf_info fp_info; - int done = 0; -+#if __OPTION_POSIX_C_LANG_WIDE_CHAR - int wide = info->wide; -+#else -+ /* This should never be called on a wide-oriented stream when -+ OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't -+ be trusted to figure that out. */ -+ const int wide = 0; -+#endif - int res; - - /* Fetch the argument value. */ -diff --git a/stdio-common/scanf14.c b/stdio-common/scanf14.c -index cffccb0..6cc260a 100644 ---- a/stdio-common/scanf14.c -+++ b/stdio-common/scanf14.c -@@ -3,6 +3,7 @@ - #include <string.h> - #include <wchar.h> - #include <libc-internal.h> -+#include <gnu/option-groups.h> - - #define FAIL() \ - do { \ -@@ -48,6 +49,7 @@ main (void) - /* See explanation above. */ - DIAG_PUSH_NEEDS_COMMENT; - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); -+#if __OPTION_EGLIBC_LOCALE_CODE - if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) - FAIL (); - else -@@ -57,6 +59,7 @@ main (void) - memset (lsp, 'x', sizeof L"3.25"); - free (lsp); - } -+#endif - if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) - FAIL (); - else -diff --git a/stdio-common/tst-popen.c b/stdio-common/tst-popen.c -index 5def27f..7c9b91e 100644 ---- a/stdio-common/tst-popen.c -+++ b/stdio-common/tst-popen.c -@@ -19,6 +19,7 @@ - #include <stdio.h> - #include <string.h> - #include <wchar.h> -+#include <gnu/option-groups.h> - - static int - do_test (void) -@@ -34,12 +35,14 @@ do_test (void) - return 1; - } - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - /* POSIX says that pipe streams are byte-oriented. */ - if (fwide (f, 0) >= 0) - { - puts ("popen did not return byte-oriented stream"); - result = 1; - } -+#endif - - if (getline (&line, &len, f) != 5) - { -diff --git a/stdio-common/tst-sprintf.c b/stdio-common/tst-sprintf.c -index d5284b9..f1e3d21 100644 ---- a/stdio-common/tst-sprintf.c -+++ b/stdio-common/tst-sprintf.c -@@ -3,7 +3,7 @@ - #include <locale.h> - #include <string.h> - #include <libc-internal.h> -- -+#include <gnu/option-groups.h> - - static int - do_test (void) -@@ -11,12 +11,14 @@ do_test (void) - char buf[100]; - int result = 0; - -+#if __OPTION_POSIX_C_LANG_WIDE_CHAR - if (sprintf (buf, "%.0ls", L"foo") != 0 - || strlen (buf) != 0) - { - puts ("sprintf (buf, \"%.0ls\", L\"foo\") produced some output"); - result = 1; - } -+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ - - #define SIZE (1024*70000) - #define STR(x) #x -diff --git a/stdio-common/tstdiomisc.c b/stdio-common/tstdiomisc.c -index 5548a71..31ed024 100644 ---- a/stdio-common/tstdiomisc.c -+++ b/stdio-common/tstdiomisc.c -@@ -4,6 +4,7 @@ - #include <string.h> - #include <wchar.h> - #include <libc-internal.h> -+#include <gnu/option-groups.h> - - static int - t1 (void) -@@ -134,6 +135,7 @@ F (void) - printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n", - buf); - -+#if __OPTION_POSIX_C_LANG_WIDE_CHAR - swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G", - qnanval, qnanval, qnanval, qnanval, - qnanval, qnanval, qnanval, qnanval); -@@ -171,6 +173,7 @@ F (void) - result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0; - printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n", - wbuf); -+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ - - lqnanval = NAN; - -@@ -215,6 +218,7 @@ F (void) - printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n", - buf); - -+#if __OPTION_POSIX_C_LANG_WIDE_CHAR - swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), - L"%La %LA %Le %LE %Lf %LF %Lg %LG", - lqnanval, lqnanval, lqnanval, lqnanval, -@@ -259,6 +263,7 @@ F (void) - result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0; - printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n", - wbuf); -+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ - - return result; - } -diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c -index 0592e70..f21d973 100644 ---- a/stdio-common/vfprintf.c -+++ b/stdio-common/vfprintf.c -@@ -29,6 +29,7 @@ - #include <_itoa.h> - #include <locale/localeinfo.h> - #include <stdio.h> -+#include <gnu/option-groups.h> - - /* This code is shared between the standard stdio implementation found - in GNU C library and the libio implementation originally found in -@@ -140,6 +141,18 @@ typedef wchar_t THOUSANDS_SEP_T; - # define EOF WEOF - #endif - -+#if __OPTION_POSIX_C_LANG_WIDE_CHAR -+# define MULTIBYTE_SUPPORT (1) -+#else -+# define MULTIBYTE_SUPPORT (0) -+#endif -+ -+#if __OPTION_EGLIBC_LOCALE_CODE -+# define LOCALE_SUPPORT (1) -+#else -+# define LOCALE_SUPPORT (0) -+#endif -+ - #include "_i18n_number.h" - - /* Include the shared code for parsing the format string. */ -@@ -1065,8 +1078,11 @@ static const uint8_t jump_table[] = - # define process_string_arg(fspec) \ - LABEL (form_character): \ - /* Character. */ \ -- if (is_long) \ -- goto LABEL (form_wcharacter); \ -+ if (is_long) \ -+ { \ -+ assert (MULTIBYTE_SUPPORT); \ -+ goto LABEL (form_wcharacter); \ -+ } \ - --width; /* Account for the character itself. */ \ - if (!left) \ - PAD (' '); \ -@@ -1079,6 +1095,7 @@ static const uint8_t jump_table[] = - break; \ - \ - LABEL (form_wcharacter): \ -+ assert (MULTIBYTE_SUPPORT); \ - { \ - /* Wide character. */ \ - char buf[MB_CUR_MAX]; \ -@@ -1145,6 +1162,7 @@ static const uint8_t jump_table[] = - } \ - else \ - { \ -+ assert (MULTIBYTE_SUPPORT); \ - const wchar_t *s2 = (const wchar_t *) string; \ - mbstate_t mbstate; \ - \ -@@ -1399,7 +1417,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) - LABEL (flag_quote): - group = 1; - -- if (grouping == (const char *) -1) -+ if (! LOCALE_SUPPORT) -+ grouping = NULL; -+ else if (grouping == (const char *) -1) - { - #ifdef COMPILE_WPRINTF - thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC, -@@ -1728,8 +1748,9 @@ printf_positional (_IO_FILE *s, const CHAR_T *format, int readonly_format, - size_t cnt; - - CHAR_T *workstart = NULL; -- -- if (grouping == (const char *) -1) -+ if (! LOCALE_SUPPORT) -+ grouping = NULL; -+ else if (grouping == (const char *) -1) - { - #ifdef COMPILE_WPRINTF - thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC, -diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c -index 0e204e7..66cc0af 100644 ---- a/stdio-common/vfscanf.c -+++ b/stdio-common/vfscanf.c -@@ -29,6 +29,7 @@ - #include <wctype.h> - #include <bits/libc-lock.h> - #include <locale/localeinfo.h> -+#include <gnu/option-groups.h> - - #ifdef __GNUC__ - # define HAVE_LONGLONG -@@ -133,6 +134,12 @@ - # define WINT_T int - #endif - -+#if __OPTION_POSIX_C_LANG_WIDE_CHAR -+# define MULTIBYTE_SUPPORT (1) -+#else -+# define MULTIBYTE_SUPPORT (0) -+#endif -+ - #define encode_error() do { \ - errval = 4; \ - __set_errno (EILSEQ); \ -@@ -316,24 +323,35 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - ARGCHECK (s, format); - - { --#ifndef COMPILE_WSCANF -+#if __OPTION_EGLIBC_LOCALE_CODE && !defined (COMPILE_WSCANF) - struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC]; - #endif - -+#if __OPTION_EGLIBC_LOCALE_CODE - /* Figure out the decimal point character. */ --#ifdef COMPILE_WSCANF -+# ifdef COMPILE_WSCANF - decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC); --#else -+# else - decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string; --#endif -+# endif - /* Figure out the thousands separator character. */ --#ifdef COMPILE_WSCANF -+# ifdef COMPILE_WSCANF - thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC); --#else -+# else - thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string; - if (*thousands == '\0') - thousands = NULL; --#endif -+# endif -+#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */ -+ /* Hard-code values from the C locale. */ -+# ifdef COMPILE_WSCANF -+ decimal = L'.'; -+ thousands = L'\0'; -+# else -+ decimal = "."; -+ thousands = NULL; -+# endif -+#endif /* __OPTION_EGLIBC_LOCALE_CODE */ - } - - /* Lock the stream. */ -@@ -385,6 +403,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - #ifndef COMPILE_WSCANF - if (!isascii ((unsigned char) *f)) - { -+ assert (MULTIBYTE_SUPPORT); -+ - /* Non-ASCII, may be a multibyte. */ - int len = __mbrlen (f, strlen (f), &state); - if (len > 0) -@@ -830,6 +850,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - } - /* FALLTHROUGH */ - case L_('C'): -+ assert (MULTIBYTE_SUPPORT); -+ - if (width == -1) - width = 1; - -@@ -1172,6 +1194,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - /* FALLTHROUGH */ - - case L_('S'): -+ assert (MULTIBYTE_SUPPORT); -+ - { - #ifndef COMPILE_WSCANF - mbstate_t cstate; -@@ -1419,10 +1443,17 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - const char *mbdigits[10]; - const char *mbdigits_extended[10]; - #endif -+#if __OPTION_EGLIBC_LOCALE_CODE - /* "to_inpunct" is a map from ASCII digits to their - equivalent in locale. This is defined for locales - which use an extra digits set. */ - wctrans_t map = __wctrans ("to_inpunct"); -+#else -+ /* This will always be the case when -+ OPTION_EGLIBC_LOCALE_CODE is disabled, but the -+ compiler can't figure that out. */ -+ wctrans_t map = NULL; -+#endif - int n; - - from_level = 0; -@@ -2088,6 +2119,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - --width; - } - -+#if __OPTION_EGLIBC_LOCALE_CODE - wctrans_t map; - if (__builtin_expect ((flags & I18N) != 0, 0) - /* Hexadecimal floats make no sense, fixing localized -@@ -2304,6 +2336,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - ; - #endif - } -+#endif /* __OPTION_EGLIBC_LOCALE_CODE */ - - /* Have we read any character? If we try to read a number - in hexadecimal notation and we have read only the `0x' -@@ -2343,7 +2376,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - - case L_('['): /* Character class. */ - if (flags & LONG) -- STRING_ARG (wstr, wchar_t, 100); -+ { -+ assert (MULTIBYTE_SUPPORT); -+ STRING_ARG (wstr, wchar_t, 100); -+ } - else - STRING_ARG (str, char, 100); - -@@ -2417,6 +2453,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, - if (flags & LONG) - { - size_t now = read_in; -+ assert (MULTIBYTE_SUPPORT); - #ifdef COMPILE_WSCANF - if (__glibc_unlikely (inchar () == WEOF)) - input_error (); -diff --git a/stdlib/Makefile b/stdlib/Makefile -index 402466a..7e7e304 100644 ---- a/stdlib/Makefile -+++ b/stdlib/Makefile -@@ -18,6 +18,8 @@ - # - # Makefile for stdlib routines - # -+include ../option-groups.mak -+ - subdir := stdlib - - include ../Makeconfig -@@ -30,7 +32,7 @@ headers := stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h \ - alloca.h fmtmsg.h \ - bits/stdlib-bsearch.h - --routines := \ -+routines-y := \ - atof atoi atol atoll \ - abort \ - bsearch qsort msort \ -@@ -39,7 +41,6 @@ routines := \ - quick_exit at_quick_exit cxa_at_quick_exit cxa_thread_atexit_impl \ - abs labs llabs \ - div ldiv lldiv \ -- mblen mbstowcs mbtowc wcstombs wctomb \ - random random_r rand rand_r \ - drand48 erand48 lrand48 nrand48 mrand48 jrand48 \ - srand48 seed48 lcong48 \ -@@ -52,9 +53,18 @@ routines := \ - strtof_l strtod_l strtold_l \ - system canonicalize \ - a64l l64a \ -- rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg \ -- strtoimax strtoumax wcstoimax wcstoumax \ -+ getsubopt xpg_basename \ -+ strtoimax strtoumax \ - getcontext setcontext makecontext swapcontext -+routines-$(OPTION_EGLIBC_LOCALE_CODE) += \ -+ strfmon strfmon_l -+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += \ -+ mblen mbstowcs mbtowc wcstombs wctomb \ -+ wcstoimax wcstoumax -+ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP)) -+routines-y += rpmatch -+endif -+routines-$(OPTION_EGLIBC_FMTMSG) += fmtmsg - aux = grouping groupingwc tens_in_limb - - # These routines will be omitted from the libc shared object. -@@ -62,20 +72,24 @@ aux = grouping groupingwc tens_in_limb - # linked against when the shared library will be used. - static-only-routines = atexit at_quick_exit - --test-srcs := tst-fmtmsg --tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ -+test-srcs-$(OPTION_EGLIBC_FMTMSG) := tst-fmtmsg -+tests := tst-strtol tst-strtod testrand testsort testdiv \ - test-canon test-canon2 tst-strtoll tst-environ \ - tst-xpg-basename tst-random tst-random2 tst-bsearch \ - tst-limits tst-rand48 bug-strtod tst-setcontext \ -- tst-setcontext2 test-a64l tst-qsort tst-system testmb2 \ -- bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 \ -- tst-rand48-2 tst-makecontext tst-strtod4 tst-strtod5 \ -+ tst-setcontext2 test-a64l tst-qsort tst-system \ -+ bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 \ -+ tst-rand48-2 tst-makecontext \ - tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \ - tst-makecontext3 bug-getcontext bug-fmtmsg1 \ - tst-secure-getenv tst-strtod-overflow tst-strtod-round \ - tst-tininess tst-strtod-underflow tst-tls-atexit \ - tst-setcontext3 tst-tls-atexit-nodelete - tests-static := tst-secure-getenv -+tests-$(OPTION_EGLIBC_LOCALE_CODE) \ -+ += tst-strtod3 tst-strtod4 tst-strtod5 testmb2 -+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ -+ += testmb - - modules-names = tst-tls-atexit-lib - -@@ -116,8 +130,10 @@ CFLAGS-tst-makecontext2.c = $(stack-align-test-flags) - tests-special += $(objpfx)isomac.out - - ifeq ($(run-built-tests),yes) -+ifeq (y,$(OPTION_EGLIBC_FMTMSG)) - tests-special += $(objpfx)tst-fmtmsg.out - endif -+endif - - include ../Rules - -diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c -index e13ab1e..63efe41 100644 ---- a/stdlib/strtod_l.c -+++ b/stdlib/strtod_l.c -@@ -17,6 +17,7 @@ - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -+#include <gnu/option-groups.h> - #include <xlocale.h> - - extern double ____strtod_l_internal (const char *, char **, int, __locale_t); -@@ -548,6 +549,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) - /* Used in several places. */ - int cnt; - -+#if __OPTION_EGLIBC_LOCALE_CODE - struct __locale_data *current = loc->__locales[LC_NUMERIC]; - - if (__glibc_unlikely (group)) -@@ -586,6 +588,17 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) - decimal_len = strlen (decimal); - assert (decimal_len > 0); - #endif -+#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */ -+ /* Hard-code values from the 'C' locale. */ -+ grouping = NULL; -+#ifdef USE_WIDE_CHAR -+ decimal = L'.'; -+# define decimal_len 1 -+#else -+ decimal = "."; -+ decimal_len = 1; -+#endif -+#endif /* __OPTION_EGLIBC_LOCALE_CODE */ - - /* Prepare number representation. */ - exponent = 0; -diff --git a/stdlib/tst-strtod.c b/stdlib/tst-strtod.c -index a469208..28fb423 100644 ---- a/stdlib/tst-strtod.c -+++ b/stdlib/tst-strtod.c -@@ -23,6 +23,7 @@ - #include <errno.h> - #include <string.h> - #include <math.h> -+#include <gnu/option-groups.h> - - struct ltest - { -@@ -176,7 +177,9 @@ main (int argc, char ** argv) - - status |= long_dbl (); - -+#if __OPTION_EGLIBC_LOCALE_CODE - status |= locale_test (); -+#endif - - return status ? EXIT_FAILURE : EXIT_SUCCESS; - } -@@ -219,6 +222,7 @@ long_dbl (void) - return 0; - } - -+#if __OPTION_EGLIBC_LOCALE_CODE - /* Perform a few tests in a locale with thousands separators. */ - static int - locale_test (void) -@@ -276,3 +280,4 @@ locale_test (void) - - return result; - } -+#endif /* __OPTION_EGLIBC_LOCALE_CODE */ -diff --git a/streams/Makefile b/streams/Makefile -index a8a6162..ceb423f 100644 ---- a/streams/Makefile -+++ b/streams/Makefile -@@ -18,11 +18,14 @@ - # - # Makefile for streams. - # -+include ../option-groups.mak -+ - subdir := streams - - include ../Makeconfig - - headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h --routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach -+routines-$(OPTION_EGLIBC_STREAMS) \ -+ += isastream getmsg getpmsg putmsg putpmsg fattach fdetach - - include ../Rules -diff --git a/string/Makefile b/string/Makefile -index 8424a61..5988834 100644 ---- a/string/Makefile -+++ b/string/Makefile -@@ -18,6 +18,8 @@ - # - # Sub-makefile for string portion of library. - # -+include ../option-groups.mak -+ - subdir := string - - include ../Makeconfig -@@ -39,10 +41,12 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \ - $(addprefix argz-,append count create ctsep next \ - delete extract insert stringify \ - addsep replace) \ -- envz basename \ -+ basename \ - strcoll_l strxfrm_l string-inlines memrchr \ - xpg-strerror strerror_l - -+routines-$(OPTION_EGLIBC_ENVZ) += envz -+ - strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \ - stpcpy stpncpy strcat strchr strcmp strcpy strcspn \ - strlen strncmp strncpy strpbrk strrchr strspn memmem \ -@@ -51,10 +55,12 @@ strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \ - tests := tester inl-tester noinl-tester testcopy test-ffs \ - tst-strlen stratcliff tst-svc tst-inlcall \ - bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \ -- tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \ -+ tst-strtok tst-strfry \ - bug-strtok1 $(addprefix test-,$(strop-tests)) \ -- bug-envz1 tst-strxfrm2 tst-endian tst-svc2 \ -- tst-strtok_r -+ tst-strxfrm2 tst-endian tst-svc2 tst-strtok_r -+tests-$(OPTION_EGLIBC_ENVZ) += bug-envz1 -+tests-$(OPTION_EGLIBC_LOCALE_CODE) \ -+ += tst-strxfrm bug-strcoll1 - - xtests = tst-strcoll-overflow - -diff --git a/string/strcoll_l.c b/string/strcoll_l.c -index 8f1225f..b36b18c 100644 ---- a/string/strcoll_l.c -+++ b/string/strcoll_l.c -@@ -24,6 +24,7 @@ - #include <stdint.h> - #include <string.h> - #include <sys/param.h> -+#include <gnu/option-groups.h> - - #ifndef STRING_TYPE - # define STRING_TYPE char -@@ -260,7 +261,11 @@ int - STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) - { - struct __locale_data *current = l->__locales[LC_COLLATE]; -+#if __OPTION_EGLIBC_LOCALE_CODE - uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word; -+#else -+ const uint_fast32_t nrules = 0; -+#endif - /* We don't assign the following values right away since it might be - unnecessary in case there are no rules. */ - const unsigned char *rulesets; -diff --git a/string/strerror_l.c b/string/strerror_l.c -index 2ed78b5..6584813 100644 ---- a/string/strerror_l.c -+++ b/string/strerror_l.c -@@ -21,6 +21,7 @@ - #include <stdlib.h> - #include <string.h> - #include <sys/param.h> -+#include <gnu/option-groups.h> - - - static __thread char *last_value; -@@ -29,10 +30,14 @@ static __thread char *last_value; - static const char * - translate (const char *str, locale_t loc) - { -+#if __OPTION_EGLIBC_LOCALE_CODE - locale_t oldloc = __uselocale (loc); - const char *res = _(str); - __uselocale (oldloc); - return res; -+#else -+ return str; -+#endif - } - - -diff --git a/string/strxfrm_l.c b/string/strxfrm_l.c -index 8b61ea2..41fdc22 100644 ---- a/string/strxfrm_l.c -+++ b/string/strxfrm_l.c -@@ -24,6 +24,7 @@ - #include <stdlib.h> - #include <string.h> - #include <sys/param.h> -+#include <gnu/option-groups.h> - - #ifndef STRING_TYPE - # define STRING_TYPE char -@@ -669,7 +670,11 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l) - { - locale_data_t l_data; - struct __locale_data *current = l->__locales[LC_COLLATE]; -+#if __OPTION_EGLIBC_LOCALE_CODE - l_data.nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word; -+#else -+ l_data.nrules = 0; -+#endif - - /* Handle byte comparison case. */ - if (l_data.nrules == 0) -diff --git a/string/test-strcmp.c b/string/test-strcmp.c -index dc4ba6f..a978656 100644 ---- a/string/test-strcmp.c -+++ b/string/test-strcmp.c -@@ -329,34 +329,6 @@ check (void) - FOR_EACH_IMPL (impl, 0) - check_result (impl, s1 + i1, s2 + i2, exp_result); - } -- -- /* Test cases where there are multiple zero bytes after the first. */ -- -- for (size_t i = 0; i < 16 + 1; i++) -- { -- s1[i] = 0x00; -- s2[i] = 0x00; -- } -- -- for (size_t i = 0; i < 16; i++) -- { -- int exp_result; -- -- for (int val = 0x01; val < 0x100; val++) -- { -- for (size_t j = 0; j < i; j++) -- { -- s1[j] = val; -- s2[j] = val; -- } -- -- s2[i] = val; -- -- exp_result = SIMPLE_STRCMP (s1, s2); -- FOR_EACH_IMPL (impl, 0) -- check_result (impl, s1, s2, exp_result); -- } -- } - } - - -diff --git a/string/tst-strxfrm.c b/string/tst-strxfrm.c -index f48cfc0..c3a51f9 100644 ---- a/string/tst-strxfrm.c -+++ b/string/tst-strxfrm.c -@@ -3,6 +3,7 @@ - #include <stdio.h> - #include <stdlib.h> - #include <string.h> -+#include <gnu/option-groups.h> - - - char const string[] = ""; -@@ -64,8 +65,10 @@ do_test (void) - int result = 0; - - result |= test ("C"); -+#if __OPTION_EGLIBC_LOCALE_CODE - result |= test ("en_US.ISO-8859-1"); - result |= test ("de_DE.UTF-8"); -+#endif - - return result; - } -diff --git a/string/tst-strxfrm2.c b/string/tst-strxfrm2.c -index d5a1115..19c7f30 100644 ---- a/string/tst-strxfrm2.c -+++ b/string/tst-strxfrm2.c -@@ -1,6 +1,7 @@ - #include <locale.h> - #include <stdio.h> - #include <string.h> -+#include <gnu/option-groups.h> - - static int - do_test (void) -@@ -38,6 +39,7 @@ do_test (void) - res = 1; - } - -+#if __OPTION_EGLIBC_LOCALE_CODE - if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) - { - puts ("setlocale failed"); -@@ -75,6 +77,7 @@ do_test (void) - res = 1; - } - } -+#endif - - return res; - } -diff --git a/sunrpc/Makefile b/sunrpc/Makefile -index 60caa0a..5bc70ab 100644 ---- a/sunrpc/Makefile -+++ b/sunrpc/Makefile -@@ -18,6 +18,8 @@ - # - # Sub-makefile for sunrpc portion of the library. - # -+include ../option-groups.mak -+ - subdir := sunrpc - - include ../Makeconfig -@@ -55,7 +57,6 @@ headers-in-tirpc = $(addprefix rpc/,auth.h auth_unix.h clnt.h pmap_clnt.h \ - headers-not-in-tirpc = $(addprefix rpc/,key_prot.h rpc_des.h) \ - $(rpcsvc:%=rpcsvc/%) rpcsvc/bootparam.h - headers = rpc/netdb.h --install-others = $(inst_sysconfdir)/rpc - generated += $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) $(rpcsvc:%.x=x%.stmp) \ - $(rpcsvc:%.x=rpcsvc/%.stmp) rpcgen - generated-dirs += rpcsvc -@@ -65,20 +66,28 @@ headers += $(headers-in-tirpc) $(headers-not-in-tirpc) - endif - - ifeq ($(build-shared),yes) --need-export-routines := auth_des auth_unix clnt_gen clnt_perr clnt_tcp \ -+need-export-routines-$(OPTION_EGLIBC_SUNRPC) := \ -+ auth_des auth_unix clnt_gen clnt_perr clnt_tcp \ - clnt_udp get_myaddr key_call netname pm_getport \ -- rpc_thread svc svc_tcp svc_udp xcrypt xdr_array xdr \ -+ rpc_thread svc svc_tcp svc_udp xdr_array xdr \ - xdr_intXX_t xdr_mem xdr_ref xdr_sizeof xdr_stdio \ - svc_run -+need-export-routines-y += xcrypt -+need-export-routines := $(need-export-routines-y) - --routines := auth_none authuxprot bindrsvprt clnt_raw clnt_simp \ -+routines-$(OPTION_EGLIBC_SUNRPC) := \ -+ auth_none authuxprot bindrsvprt clnt_raw clnt_simp \ - rpc_dtable getrpcport pmap_clnt pm_getmaps pmap_prot pmap_prot2 \ - pmap_rmt rpc_prot rpc_common rpc_cmsg svc_auth svc_authux svc_raw \ - svc_simple xdr_float xdr_rec publickey authdes_prot \ -- des_crypt des_impl des_soft key_prot openchild rtime svcauth_des \ -+ key_prot openchild rtime svcauth_des \ - getrpcent getrpcbyname getrpcbynumber \ - getrpcent_r getrpcbyname_r getrpcbynumber_r \ -- clnt_unix svc_unix create_xid $(need-export-routines) -+ clnt_unix svc_unix create_xid -+ -+# xdecrypt is also used by nss/nss_files/files-key.c. -+routines-y += des_crypt des_impl des_soft $(need-export-routines) -+ - ifneq ($(link-obsolete-rpc),yes) - # We only add the RPC for compatibility to libc.so. - shared-only-routines = $(routines) -@@ -87,25 +96,28 @@ endif - - # We do not build rpcinfo anymore. It is not needed for a bootstrap - # and not wanted on complete systems. --# others := rpcinfo --# install-sbin := rpcinfo --install-bin := rpcgen -+# others-$(OPTION_EGLIBC_SUNRPC) += rpcinfo -+# install-sbin-$(OPTION_EGLIBC_SUNRPC) += rpcinfo -+install-bin-$(OPTION_EGLIBC_SUNRPC) += rpcgen - rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \ - rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \ - rpc_tblout.o rpc_sample.o --extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs)) --others += rpcgen -+extra-objs-$(OPTION_EGLIBC_SUNRPC) = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs)) -+others-$(OPTION_EGLIBC_SUNRPC) += rpcgen -+ -+install-others-$(OPTION_EGLIBC_SUNRPC) += $(inst_sysconfdir)/rpc - --tests = tst-xdrmem tst-xdrmem2 test-rpcent --xtests := tst-getmyaddr -+tests-$(OPTION_EGLIBC_SUNRPC) = tst-xdrmem tst-xdrmem2 test-rpcent -+xtests-$(OPTION_EGLIBC_SUNRPC) := tst-getmyaddr - - ifeq ($(have-thread-library),yes) --xtests += thrsvc -+xtests-$(OPTION_EGLIBC_SUNRPC) += thrsvc - endif - - headers += $(rpcsvc:%.x=rpcsvc/%.h) --extra-libs := librpcsvc --extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass. -+extra-libs-$(OPTION_EGLIBC_SUNRPC) += librpcsvc -+# Make it in `others' pass, not `lib' pass. -+extra-libs-others-y += $(extra-libs-y) - librpcsvc-routines = $(rpcsvc:%.x=x%) - librpcsvc-inhibit-o = .os # Build no shared rpcsvc library. - omit-deps = $(librpcsvc-routines) -diff --git a/sysdeps/arm/Makefile b/sysdeps/arm/Makefile -index 17c129b..543791a 100644 ---- a/sysdeps/arm/Makefile -+++ b/sysdeps/arm/Makefile -@@ -37,10 +37,13 @@ ifeq ($(subdir),csu) - # get offset to rtld_global._dl_hwcap - gen-as-const-headers += rtld-global-offsets.sym tlsdesc.sym - aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math --aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \ -+aeabi_routines = aeabi_assert aeabi_errno_addr \ - aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \ - aeabi_memmove aeabi_memset \ - aeabi_read_tp libc-aeabi_read_tp -+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE)) -+aeabi_routines += aeabi_localeconv -+endif - - sysdep_routines += $(aeabi_constants) $(aeabi_routines) - static-only-routines += $(aeabi_constants) aeabi_read_tp -diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h -index 7a0fe8d..a3e2c0a 100644 ---- a/sysdeps/generic/ldsodefs.h -+++ b/sysdeps/generic/ldsodefs.h -@@ -435,6 +435,12 @@ extern struct rtld_global _rtld_global __rtld_global_attribute__; - # undef __rtld_global_attribute__ - #endif - -+#if __OPTION_EGLIBC_RTLD_DEBUG -+# define GLRO_dl_debug_mask GLRO(dl_debug_mask) -+#else -+# define GLRO_dl_debug_mask 0 -+#endif -+ - #ifndef SHARED - # define GLRO(name) _##name - #else -@@ -447,8 +453,10 @@ struct rtld_global_ro - { - #endif - -+#if __OPTION_EGLIBC_RTLD_DEBUG - /* If nonzero the appropriate debug information is printed. */ - EXTERN int _dl_debug_mask; -+#endif - #define DL_DEBUG_LIBS (1 << 0) - #define DL_DEBUG_IMPCALLS (1 << 1) - #define DL_DEBUG_BINDINGS (1 << 2) -diff --git a/sysdeps/gnu/Makefile b/sysdeps/gnu/Makefile -index ea68037..3175cc3 100644 ---- a/sysdeps/gnu/Makefile -+++ b/sysdeps/gnu/Makefile -@@ -59,7 +59,8 @@ $(foreach o,$(object-suffixes) $(object-suffixes:=.d),\ - endif - - ifeq ($(subdir),login) --sysdep_routines += setutxent getutxent endutxent getutxid getutxline \ -+sysdep_routines-$(OPTION_EGLIBC_UTMPX) \ -+ += setutxent getutxent endutxent getutxid getutxline \ - pututxline utmpxname updwtmpx getutmpx getutmp - - sysdep_headers += utmpx.h bits/utmpx.h -diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile -index 222122d..4509357 100644 ---- a/sysdeps/ieee754/ldbl-opt/Makefile -+++ b/sysdeps/ieee754/ldbl-opt/Makefile -@@ -11,19 +11,18 @@ libm-routines += s_nexttowardfd - routines += math_ldbl_opt nldbl-compat - - extra-libs += libnldbl --libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \ -+libnldbl-calls = asprintf dprintf fprintf fscanf iovfscanf \ - obstack_printf obstack_vprintf printf scanf snprintf \ -- sprintf sscanf swprintf swscanf vasprintf vdprintf vfprintf \ -- vfscanf vfwprintf vfwscanf vprintf vscanf vsnprintf \ -- vsprintf vsscanf vswprintf vswscanf vwprintf vwscanf \ -- wprintf wscanf printf_fp printf_size \ -- fprintf_chk fwprintf_chk printf_chk snprintf_chk sprintf_chk \ -- swprintf_chk vfprintf_chk vfwprintf_chk vprintf_chk \ -- vsnprintf_chk vsprintf_chk vswprintf_chk vwprintf_chk \ -- wprintf_chk asprintf_chk vasprintf_chk dprintf_chk \ -+ sprintf sscanf vasprintf vdprintf vfprintf \ -+ vfscanf vprintf vscanf vsnprintf \ -+ vsprintf vsscanf \ -+ printf_fp printf_size \ -+ fprintf_chk printf_chk snprintf_chk sprintf_chk \ -+ vfprintf_chk vprintf_chk \ -+ vsnprintf_chk vsprintf_chk \ -+ asprintf_chk vasprintf_chk dprintf_chk \ - vdprintf_chk obstack_printf_chk obstack_vprintf_chk \ - syslog syslog_chk vsyslog vsyslog_chk \ -- strfmon strfmon_l \ - strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \ - qecvt qfcvt qgcvt qecvt_r qfcvt_r \ - isinf isnan finite signbit scalb log2 lgamma_r ceil \ -@@ -38,9 +37,15 @@ libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \ - casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \ - cabs carg cimag creal clog10 \ - isoc99_scanf isoc99_fscanf isoc99_sscanf \ -- isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \ -+ isoc99_vscanf isoc99_vfscanf isoc99_vsscanf -+libnldbl-calls-$(OPTION_EGLIBC_LOCALE_CODE) += strfmon strfmon_l -+libnldbl-calls-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += fwprintf fwscanf \ -+ swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf \ -+ vwprintf vwscanf wprintf wscanf fwprintf_chk swprintf_chk \ -+ vfwprintf_chk vswprintf_chk vwprintf_chk wprintf_chk \ - isoc99_wscanf isoc99_fwscanf isoc99_swscanf \ - isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf -+libnldbl-calls += $(libnldbl-calls-y) - libnldbl-routines = $(libnldbl-calls:%=nldbl-%) - libnldbl-inhibit-o = $(object-suffixes) - libnldbl-static-only-routines = $(libnldbl-routines) -diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c -index 0198886..55501cd 100644 ---- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c -+++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c -@@ -26,6 +26,7 @@ - #include <locale/localeinfo.h> - #include <sys/syslog.h> - #include <bits/libc-lock.h> -+#include <gnu/option-groups.h> - - #include "nldbl-compat.h" - -@@ -33,20 +34,14 @@ libc_hidden_proto (__nldbl_vfprintf) - libc_hidden_proto (__nldbl_vsscanf) - libc_hidden_proto (__nldbl_vsprintf) - libc_hidden_proto (__nldbl_vfscanf) --libc_hidden_proto (__nldbl_vfwscanf) - libc_hidden_proto (__nldbl_vdprintf) --libc_hidden_proto (__nldbl_vswscanf) --libc_hidden_proto (__nldbl_vfwprintf) --libc_hidden_proto (__nldbl_vswprintf) - libc_hidden_proto (__nldbl_vsnprintf) - libc_hidden_proto (__nldbl_vasprintf) - libc_hidden_proto (__nldbl_obstack_vprintf) --libc_hidden_proto (__nldbl___vfwprintf_chk) - libc_hidden_proto (__nldbl___vsnprintf_chk) - libc_hidden_proto (__nldbl___vfprintf_chk) - libc_hidden_proto (__nldbl___vsyslog_chk) - libc_hidden_proto (__nldbl___vsprintf_chk) --libc_hidden_proto (__nldbl___vswprintf_chk) - libc_hidden_proto (__nldbl___vasprintf_chk) - libc_hidden_proto (__nldbl___vdprintf_chk) - libc_hidden_proto (__nldbl___obstack_vprintf_chk) -@@ -54,8 +49,17 @@ libc_hidden_proto (__nldbl___vstrfmon) - libc_hidden_proto (__nldbl___vstrfmon_l) - libc_hidden_proto (__nldbl___isoc99_vsscanf) - libc_hidden_proto (__nldbl___isoc99_vfscanf) -+ -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO -+libc_hidden_proto (__nldbl_vfwscanf) -+libc_hidden_proto (__nldbl_vswscanf) -+libc_hidden_proto (__nldbl_vfwprintf) -+libc_hidden_proto (__nldbl_vswprintf) -+libc_hidden_proto (__nldbl___vfwprintf_chk) -+libc_hidden_proto (__nldbl___vswprintf_chk) - libc_hidden_proto (__nldbl___isoc99_vswscanf) - libc_hidden_proto (__nldbl___isoc99_vfwscanf) -+#endif - - static void - __nldbl_cleanup (void *arg) -@@ -117,6 +121,7 @@ __nldbl_fprintf (FILE *stream, const char *fmt, ...) - } - weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf) - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section weak_function - __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...) -@@ -130,6 +135,7 @@ __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...) - - return done; - } -+#endif - - int - attribute_compat_text_section -@@ -226,6 +232,7 @@ __nldbl_snprintf (char *s, size_t maxlen, const char *fmt, ...) - return done; - } - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section - __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...) -@@ -239,6 +246,7 @@ __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...) - - return done; - } -+#endif - - int - attribute_compat_text_section weak_function -@@ -264,6 +272,7 @@ __nldbl_vdprintf (int d, const char *fmt, va_list arg) - } - libc_hidden_def (__nldbl_vdprintf) - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section weak_function - __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap) -@@ -275,6 +284,7 @@ __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap) - return res; - } - libc_hidden_def (__nldbl_vfwprintf) -+#endif - - int - attribute_compat_text_section -@@ -297,6 +307,7 @@ __nldbl_vsnprintf (char *string, size_t maxlen, const char *fmt, - libc_hidden_def (__nldbl_vsnprintf) - weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf) - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section weak_function - __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt, -@@ -330,6 +341,7 @@ __nldbl_wprintf (const wchar_t *fmt, ...) - - return done; - } -+#endif - - int - attribute_compat_text_section -@@ -419,6 +431,7 @@ __nldbl_scanf (const char *fmt, ...) - return done; - } - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section - __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap) -@@ -491,6 +504,7 @@ __nldbl_wscanf (const wchar_t *fmt, ...) - - return done; - } -+#endif - - int - attribute_compat_text_section -@@ -506,6 +520,7 @@ __nldbl___fprintf_chk (FILE *stream, int flag, const char *fmt, ...) - return done; - } - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section - __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...) -@@ -519,6 +534,7 @@ __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...) - - return done; - } -+#endif - - int - attribute_compat_text_section -@@ -563,6 +579,7 @@ __nldbl___sprintf_chk (char *s, int flag, size_t slen, const char *fmt, ...) - return done; - } - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section - __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen, -@@ -577,6 +594,7 @@ __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen, - - return done; - } -+#endif - - int - attribute_compat_text_section -@@ -590,6 +608,7 @@ __nldbl___vfprintf_chk (FILE *s, int flag, const char *fmt, va_list ap) - } - libc_hidden_def (__nldbl___vfprintf_chk) - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section - __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap) -@@ -601,6 +620,7 @@ __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap) - return res; - } - libc_hidden_def (__nldbl___vfwprintf_chk) -+#endif - - int - attribute_compat_text_section -@@ -635,6 +655,7 @@ __nldbl___vsprintf_chk (char *string, int flag, size_t slen, const char *fmt, - } - libc_hidden_def (__nldbl___vsprintf_chk) - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section - __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen, -@@ -668,6 +689,7 @@ __nldbl___wprintf_chk (int flag, const wchar_t *fmt, ...) - - return done; - } -+#endif - - int - attribute_compat_text_section -@@ -775,6 +797,7 @@ __nldbl___printf_fp (FILE *fp, const struct printf_info *info, - return ___printf_fp (fp, &info_no_ldbl, args); - } - -+#if __OPTION_EGLIBC_LOCALE_CODE - ssize_t - attribute_compat_text_section - __nldbl_strfmon (char *s, size_t maxsize, const char *format, ...) -@@ -829,6 +852,7 @@ __nldbl___vstrfmon_l (char *s, size_t maxsize, __locale_t loc, - return res; - } - libc_hidden_def (__nldbl___vstrfmon_l) -+#endif - - void - attribute_compat_text_section -@@ -941,6 +965,7 @@ __nldbl___isoc99_scanf (const char *fmt, ...) - return done; - } - -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - int - attribute_compat_text_section - __nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap) -@@ -1014,6 +1039,7 @@ __nldbl___isoc99_wscanf (const wchar_t *fmt, ...) - - return done; - } -+#endif - - #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) - compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0); -@@ -1057,6 +1083,7 @@ compat_symbol (libc, __nldbl_printf_size, printf_size, GLIBC_2_1); - compat_symbol (libc, __nldbl___strfmon_l, __strfmon_l, GLIBC_2_1); - #endif - #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_2) -+# if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO - compat_symbol (libc, __nldbl_swprintf, swprintf, GLIBC_2_2); - compat_symbol (libc, __nldbl_vwprintf, vwprintf, GLIBC_2_2); - compat_symbol (libc, __nldbl_wprintf, wprintf, GLIBC_2_2); -@@ -1069,6 +1096,7 @@ compat_symbol (libc, __nldbl_vfwscanf, vfwscanf, GLIBC_2_2); - compat_symbol (libc, __nldbl_vswscanf, vswscanf, GLIBC_2_2); - compat_symbol (libc, __nldbl_vwscanf, vwscanf, GLIBC_2_2); - compat_symbol (libc, __nldbl_wscanf, wscanf, GLIBC_2_2); -+# endif - #endif - #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3) - compat_symbol (libc, __nldbl_strfmon_l, strfmon_l, GLIBC_2_3); -diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h -index 0d2c8af..f4cea50 100644 ---- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h -+++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h -@@ -30,6 +30,7 @@ - #include <math.h> - #include <monetary.h> - #include <sys/syslog.h> -+#include <gnu/option-groups.h> - - - /* Declare the __nldbl_NAME function the wrappers call that's in libc.so. */ -@@ -37,19 +38,15 @@ - - NLDBL_DECL (_IO_vfscanf); - NLDBL_DECL (vfscanf); --NLDBL_DECL (vfwscanf); - NLDBL_DECL (obstack_vprintf); - NLDBL_DECL (vasprintf); - NLDBL_DECL (dprintf); - NLDBL_DECL (vdprintf); - NLDBL_DECL (fprintf); - NLDBL_DECL (vfprintf); --NLDBL_DECL (vfwprintf); - NLDBL_DECL (vsnprintf); - NLDBL_DECL (vsprintf); - NLDBL_DECL (vsscanf); --NLDBL_DECL (vswprintf); --NLDBL_DECL (vswscanf); - NLDBL_DECL (__asprintf); - NLDBL_DECL (asprintf); - NLDBL_DECL (__printf_fp); -@@ -66,12 +63,18 @@ NLDBL_DECL (__isoc99_sscanf); - NLDBL_DECL (__isoc99_vscanf); - NLDBL_DECL (__isoc99_vfscanf); - NLDBL_DECL (__isoc99_vsscanf); -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO -+NLDBL_DECL (vfwscanf); -+NLDBL_DECL (vfwprintf); -+NLDBL_DECL (vswprintf); -+NLDBL_DECL (vswscanf); - NLDBL_DECL (__isoc99_wscanf); - NLDBL_DECL (__isoc99_fwscanf); - NLDBL_DECL (__isoc99_swscanf); - NLDBL_DECL (__isoc99_vwscanf); - NLDBL_DECL (__isoc99_vfwscanf); - NLDBL_DECL (__isoc99_vswscanf); -+#endif - - /* This one does not exist in the normal interface, only - __nldbl___vstrfmon really exists. */ -@@ -82,22 +85,23 @@ extern ssize_t __nldbl___vstrfmon (char *, size_t, const char *, va_list) - since we don't compile with _FORTIFY_SOURCE. */ - extern int __nldbl___vfprintf_chk (FILE *__restrict, int, - const char *__restrict, _G_va_list); --extern int __nldbl___vfwprintf_chk (FILE *__restrict, int, -- const wchar_t *__restrict, __gnuc_va_list); - extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t, - const char *__restrict, _G_va_list) __THROW; - extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t, - const char *__restrict, _G_va_list) - __THROW; --extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t, -- const wchar_t *__restrict, __gnuc_va_list) -- __THROW; - extern int __nldbl___vasprintf_chk (char **, int, const char *, _G_va_list) - __THROW; - extern int __nldbl___vdprintf_chk (int, int, const char *, _G_va_list); - extern int __nldbl___obstack_vprintf_chk (struct obstack *, int, const char *, - _G_va_list) __THROW; - extern void __nldbl___vsyslog_chk (int, int, const char *, va_list); -- -+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO -+extern int __nldbl___vfwprintf_chk (FILE *__restrict, int, -+ const wchar_t *__restrict, __gnuc_va_list); -+extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t, -+ const wchar_t *__restrict, __gnuc_va_list) -+ __THROW; -+#endif - - #endif /* __NLDBL_COMPAT_H */ -diff --git a/sysdeps/nptl/Makefile b/sysdeps/nptl/Makefile -index e9339a3..782009b 100644 ---- a/sysdeps/nptl/Makefile -+++ b/sysdeps/nptl/Makefile -@@ -18,6 +18,9 @@ - - ifeq ($(subdir),nptl) - libpthread-sysdep_routines += errno-loc -+ifeq ($(OPTION_EGLIBC_BIG_MACROS),n) -+sysdep_routines += small-macros-fns -+endif - endif - - ifeq ($(subdir),rt) -diff --git a/sysdeps/nptl/bits/libc-lock.h b/sysdeps/nptl/bits/libc-lock.h -index 5599cf1..b839378 100644 ---- a/sysdeps/nptl/bits/libc-lock.h -+++ b/sysdeps/nptl/bits/libc-lock.h -@@ -24,6 +24,14 @@ - #include <stddef.h> - - -+#ifdef _LIBC -+# include <lowlevellock.h> -+# include <tls.h> -+# include <pthread-functions.h> -+# include <errno.h> /* For EBUSY. */ -+# include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */ -+#endif -+ - /* Mutex type. */ - #if defined _LIBC || defined _IO_MTSAFE_IO - # if (!IS_IN (libc) && !IS_IN (libpthread)) || !defined _LIBC -@@ -87,6 +95,15 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; - - /* Lock the recursive named lock variable. */ - #if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread)) -+# if __OPTION_EGLIBC_BIG_MACROS != 1 -+/* EGLIBC: Declare wrapper function for a big macro if either -+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from -+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ -+extern void __libc_lock_lock_recursive_fn (__libc_lock_recursive_t *); -+libc_hidden_proto (__libc_lock_lock_recursive_fn); -+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ -+# if __OPTION_EGLIBC_BIG_MACROS -+ - # define __libc_lock_lock_recursive(NAME) \ - do { \ - void *self = THREAD_SELF; \ -@@ -97,6 +114,10 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; - } \ - ++(NAME).cnt; \ - } while (0) -+# else -+# define __libc_lock_lock_recursive(NAME) \ -+ __libc_lock_lock_recursive_fn (&(NAME)) -+# endif /* __OPTION_EGLIBC_BIG_MACROS */ - #else - # define __libc_lock_lock_recursive(NAME) \ - __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0) -@@ -104,6 +125,14 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; - - /* Try to lock the recursive named lock variable. */ - #if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread)) -+# if __OPTION_EGLIBC_BIG_MACROS != 1 -+/* EGLIBC: Declare wrapper function for a big macro if either -+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from -+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ -+extern int __libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *); -+libc_hidden_proto (__libc_lock_trylock_recursive_fn); -+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ -+# if __OPTION_EGLIBC_BIG_MACROS - # define __libc_lock_trylock_recursive(NAME) \ - ({ \ - int result = 0; \ -@@ -122,6 +151,10 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; - ++(NAME).cnt; \ - result; \ - }) -+# else -+# define __libc_lock_trylock_recursive(NAME) \ -+ __libc_lock_trylock_recursive_fn (&(NAME)) -+# endif /* __OPTION_EGLIBC_BIG_MACROS */ - #else - # define __libc_lock_trylock_recursive(NAME) \ - __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0) -@@ -129,6 +162,14 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; - - /* Unlock the recursive named lock variable. */ - #if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread)) -+# if __OPTION_EGLIBC_BIG_MACROS != 1 -+/* EGLIBC: Declare wrapper function for a big macro if either -+ !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from -+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ -+extern void __libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *); -+libc_hidden_proto (__libc_lock_unlock_recursive_fn); -+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ -+# if __OPTION_EGLIBC_BIG_MACROS - /* We do no error checking here. */ - # define __libc_lock_unlock_recursive(NAME) \ - do { \ -@@ -138,6 +179,10 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; - lll_unlock ((NAME).lock, LLL_PRIVATE); \ - } \ - } while (0) -+# else -+# define __libc_lock_unlock_recursive(NAME) \ -+ __libc_lock_unlock_recursive_fn (&(NAME)) -+# endif /* __OPTION_EGLIBC_BIG_MACROS */ - #else - # define __libc_lock_unlock_recursive(NAME) \ - __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0) -diff --git a/sysdeps/nptl/bits/libc-lockP.h b/sysdeps/nptl/bits/libc-lockP.h -index f55f621..da98869 100644 ---- a/sysdeps/nptl/bits/libc-lockP.h -+++ b/sysdeps/nptl/bits/libc-lockP.h -@@ -33,6 +33,8 @@ - #include <lowlevellock.h> - #include <tls.h> - #include <pthread-functions.h> -+#include <errno.h> /* For EBUSY. */ -+#include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */ - - #if IS_IN (libpthread) - /* This gets us the declarations of the __pthread_* internal names, -@@ -171,10 +173,22 @@ typedef pthread_key_t __libc_key_t; - - /* Lock the named lock variable. */ - #if IS_IN (libc) || IS_IN (libpthread) --# ifndef __libc_lock_lock --# define __libc_lock_lock(NAME) \ -+# if __OPTION_EGLIBC_BIG_MACROS != 1 -+/* EGLIBC: Declare wrapper function for a big macro if either -+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from -+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ -+extern void __libc_lock_lock_fn (__libc_lock_t *); -+libc_hidden_proto (__libc_lock_lock_fn); -+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ -+# if __OPTION_EGLIBC_BIG_MACROS -+# ifndef __libc_lock_lock -+# define __libc_lock_lock(NAME) \ - ({ lll_lock (NAME, LLL_PRIVATE); 0; }) --# endif -+# endif -+# else -+# define __libc_lock_lock(NAME) \ -+ __libc_lock_lock_fn (&(NAME)) -+# endif /* __OPTION_EGLIBC_BIG_MACROS */ - #else - # undef __libc_lock_lock - # define __libc_lock_lock(NAME) \ -@@ -187,10 +201,22 @@ typedef pthread_key_t __libc_key_t; - - /* Try to lock the named lock variable. */ - #if IS_IN (libc) || IS_IN (libpthread) --# ifndef __libc_lock_trylock --# define __libc_lock_trylock(NAME) \ -+# if __OPTION_EGLIBC_BIG_MACROS != 1 -+/* EGLIBC: Declare wrapper function for a big macro if either -+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from -+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ -+extern int __libc_lock_trylock_fn (__libc_lock_t *); -+libc_hidden_proto (__libc_lock_trylock_fn); -+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ -+# if __OPTION_EGLIBC_BIG_MACROS -+# ifndef __libc_lock_trylock -+# define __libc_lock_trylock(NAME) \ - lll_trylock (NAME) --# endif -+# endif -+# else -+# define __libc_lock_trylock(NAME) \ -+ __libc_lock_trylock_fn (&(NAME)) -+# endif /* __OPTION_EGLIBC_BIG_MACROS */ - #else - # undef __libc_lock_trylock - # define __libc_lock_trylock(NAME) \ -@@ -206,8 +232,20 @@ typedef pthread_key_t __libc_key_t; - - /* Unlock the named lock variable. */ - #if IS_IN (libc) || IS_IN (libpthread) -+# if __OPTION_EGLIBC_BIG_MACROS != 1 -+/* EGLIBC: Declare wrapper function for a big macro if either -+ !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from -+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ -+extern void __libc_lock_unlock_fn (__libc_lock_t *); -+libc_hidden_proto (__libc_lock_unlock_fn); -+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ -+# if __OPTION_EGLIBC_BIG_MACROS - # define __libc_lock_unlock(NAME) \ - lll_unlock (NAME, LLL_PRIVATE) -+# else -+# define __libc_lock_unlock(NAME) \ -+ __libc_lock_unlock_fn (&(NAME)) -+# endif /* __OPTION_EGLIBC_BIG_MACROS */ - #else - # define __libc_lock_unlock(NAME) \ - __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0) -diff --git a/sysdeps/nptl/small-macros-fns.c b/sysdeps/nptl/small-macros-fns.c -new file mode 100644 -index 0000000..f751053 ---- /dev/null -+++ b/sysdeps/nptl/small-macros-fns.c -@@ -0,0 +1,72 @@ -+/* EGLIBC: function wrappers for big macros. -+ Copyright (C) 2009 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; see the file COPYING.LIB. If not, -+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+#include <gnu/option-groups.h> -+ -+/* Handle macros from ./bits/libc-lock.h. */ -+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) -+ -+/* Get the macros for function bodies through a back door. */ -+# undef __OPTION_EGLIBC_BIG_MACROS -+# define __OPTION_EGLIBC_BIG_MACROS 2 -+# include <bits/libc-lock.h> -+ -+void -+__libc_lock_lock_fn (__libc_lock_t *name) -+{ -+ __libc_lock_lock (*name); -+} -+libc_hidden_def (__libc_lock_lock_fn); -+ -+void -+__libc_lock_lock_recursive_fn (__libc_lock_recursive_t *name) -+{ -+ __libc_lock_lock_recursive (*name); -+} -+libc_hidden_def (__libc_lock_lock_recursive_fn); -+ -+int -+__libc_lock_trylock_fn (__libc_lock_t *name) -+{ -+ return __libc_lock_trylock (*name); -+} -+libc_hidden_def (__libc_lock_trylock_fn); -+ -+int -+__libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *name) -+{ -+ return __libc_lock_trylock_recursive (*name); -+} -+libc_hidden_def (__libc_lock_trylock_recursive_fn); -+ -+void -+__libc_lock_unlock_fn (__libc_lock_t *name) -+{ -+ __libc_lock_unlock (*name); -+} -+libc_hidden_def (__libc_lock_unlock_fn); -+ -+void -+__libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *name) -+{ -+ __libc_lock_unlock_recursive (*name); -+} -+libc_hidden_def (__libc_lock_unlock_recursive_fn); -+ -+#endif /*defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)*/ -diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c -index 26e4692..d0a26c8 100644 ---- a/sysdeps/unix/sysv/linux/gethostid.c -+++ b/sysdeps/unix/sysv/linux/gethostid.c -@@ -21,6 +21,7 @@ - #include <unistd.h> - #include <netdb.h> - #include <not-cancel.h> -+#include <gnu/option-groups.h> - - #define HOSTIDFILE "/etc/hostid" - -@@ -89,6 +90,7 @@ gethostid (void) - return id; - } - -+#if __OPTION_EGLIBC_INET - /* Getting from the file was not successful. An intelligent guess for - a unique number of a host is its IP address. Return this. */ - if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0') -@@ -115,5 +117,9 @@ gethostid (void) - /* For the return value to be not exactly the IP address we do some - bit fiddling. */ - return (int32_t) (in.s_addr << 16 | in.s_addr >> 16); -+#else -+ /* Return an arbitrary value. */ -+ return 0; -+#endif - } - #endif -diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c -index 53a8bbb..cb110d4 100644 ---- a/sysdeps/unix/sysv/linux/libc_fatal.c -+++ b/sysdeps/unix/sysv/linux/libc_fatal.c -@@ -23,6 +23,7 @@ - #include <string.h> - #include <sys/mman.h> - #include <sys/uio.h> -+#include <gnu/option-groups.h> - - static bool - writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total) -@@ -40,6 +41,7 @@ writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total) - static void - backtrace_and_maps (int do_abort, bool written, int fd) - { -+#if __OPTION_EGLIBC_BACKTRACE - if (do_abort > 1 && written) - { - void *addrs[64]; -@@ -62,6 +64,7 @@ backtrace_and_maps (int do_abort, bool written, int fd) - close_not_cancel_no_status (fd2); - } - } -+#endif /* __OPTION_EGLIBC_BACKTRACE */ - } - #define BEFORE_ABORT backtrace_and_maps - -diff --git a/time/Makefile b/time/Makefile -index a411f62..2d022ca 100644 ---- a/time/Makefile -+++ b/time/Makefile -@@ -18,6 +18,8 @@ - # - # Makefile for time routines - # -+include ../option-groups.mak -+ - subdir := time - - include ../Makeconfig -@@ -30,15 +32,23 @@ routines := offtime asctime clock ctime ctime_r difftime \ - tzfile getitimer setitimer \ - stime dysize timegm ftime \ - getdate strptime strptime_l \ -- strftime wcsftime strftime_l wcsftime_l \ -+ strftime strftime_l \ - timespec_get --aux := era alt_digit lc-time-cleanup - --tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ -- tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \ -+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ -+ := wcsftime wcsftime_l -+aux-$(OPTION_EGLIBC_LOCALE_CODE) += alt_digit era lc-time-cleanup -+ -+tests := test_time clocktest tst-posixtz \ -+ tst-getdate tst-mktime tst-mktime2 tst-strftime \ - tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \ - tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime - -+tests-$(OPTION_EGLIBC_LOCALE_CODE) \ -+ += tst-strptime tst-ftime_l -+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \ -+ += tst_wcsftime -+ - include ../Rules - - tz-cflags = -DTZDIR='"$(zonedir)"' \ -diff --git a/time/strftime_l.c b/time/strftime_l.c -index b48ef34..bfdd618 100644 ---- a/time/strftime_l.c -+++ b/time/strftime_l.c -@@ -35,6 +35,10 @@ - # include "../locale/localeinfo.h" - #endif - -+#ifdef _LIBC -+# include <gnu/option-groups.h> -+#endif -+ - #if defined emacs && !defined HAVE_BCOPY - # define HAVE_MEMCPY 1 - #endif -@@ -882,7 +886,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument - case L_('C'): - if (modifier == L_('E')) - { --#if HAVE_STRUCT_ERA_ENTRY -+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY - struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); - if (era) - { -@@ -955,7 +959,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument - - if (modifier == L_('O') && 0 <= number_value) - { --#ifdef _NL_CURRENT -+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT) - /* Get the locale specific alternate representation of - the number NUMBER_VALUE. If none exist NULL is returned. */ - const CHAR_T *cp = nl_get_alt_digit (number_value -@@ -1260,7 +1264,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument - case L_('Y'): - if (modifier == 'E') - { --#if HAVE_STRUCT_ERA_ENTRY -+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY - struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); - if (era) - { -@@ -1285,7 +1289,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument - case L_('y'): - if (modifier == L_('E')) - { --#if HAVE_STRUCT_ERA_ENTRY -+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY - struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); - if (era) - { -diff --git a/time/strptime_l.c b/time/strptime_l.c -index 5640cce..784ccbc 100644 ---- a/time/strptime_l.c -+++ b/time/strptime_l.c -@@ -29,6 +29,7 @@ - - #ifdef _LIBC - # define HAVE_LOCALTIME_R 0 -+# include <gnu/option-groups.h> - # include "../locale/localeinfo.h" - #endif - -@@ -84,7 +85,7 @@ localtime_r (t, tp) - if (val < from || val > to) \ - return NULL; \ - } while (0) --#ifdef _NL_CURRENT -+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT) - # define get_alt_number(from, to, n) \ - ({ \ - __label__ do_normal; \ -@@ -257,8 +258,10 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM) - int cnt; - int cnt_longest; - size_t val; -+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE - size_t num_eras; - struct era_entry *era = NULL; -+#endif - enum ptime_locale_status { not, loc, raw } decided_longest; - struct __strptime_state - { -@@ -820,6 +823,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM) - s.want_xday = 1; - break; - case 'C': -+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE - if (s.decided != raw) - { - if (s.era_cnt >= 0) -@@ -856,10 +860,12 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM) - - s.decided = raw; - } -+#endif - /* The C locale has no era information, so use the - normal representation. */ - goto match_century; - case 'y': -+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE - if (s.decided != raw) - { - get_number(0, 9999, 4); -@@ -918,9 +924,10 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM) - - s.decided = raw; - } -- -+#endif - goto match_year_in_century; - case 'Y': -+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE - if (s.decided != raw) - { - num_eras = _NL_CURRENT_WORD (LC_TIME, -@@ -948,6 +955,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM) - - s.decided = raw; - } -+#endif - get_number (0, 9999, 4); - tm->tm_year = val - 1900; - s.want_century = 0; -@@ -1118,6 +1126,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM) - tm->tm_year = (s.century - 19) * 100; - } - -+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE - if (s.era_cnt != -1) - { - era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG); -@@ -1132,6 +1141,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM) - tm->tm_year = era->start_date[0]; - } - else -+#endif - if (s.want_era) - { - /* No era found but we have seen an E modifier. Rectify some -diff --git a/timezone/Makefile b/timezone/Makefile -index 886b06e..f922684 100644 ---- a/timezone/Makefile -+++ b/timezone/Makefile -@@ -127,7 +127,7 @@ $(testdata)/XT%: testdata/XT% - - $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make - sed -e 's|/bin/bash|/bin/sh|' \ -- -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \ -+ -e '/TZDIR=/s|\$$(pwd)|$(zonedir)|' \ - -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \ - -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \ - -e '/REPORT_BUGS_TO=/s|=.*|="$(REPORT_BUGS_TO)"|' \ -diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile -index 44a4494..db9fc24 100644 ---- a/wcsmbs/Makefile -+++ b/wcsmbs/Makefile -@@ -18,15 +18,21 @@ - # - # Sub-makefile for wcsmbs portion of the library. - # -+include ../option-groups.mak -+ - subdir := wcsmbs - - include ../Makeconfig - - headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h - --routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ -+# These functions are used by printf_fp.c, even in the plain case; see -+# comments there for OPTION_EGLIBC_LOCALE_CODE. -+routines := wmemcpy wmemset -+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ -+ := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ - wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \ -- wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy wmempcpy \ -+ wmemcmp wmemmove wcpcpy wcpncpy wmempcpy \ - btowc wctob mbsinit \ - mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \ - mbsnrtowcs wcsnrtombs wcsnlen wcschrnul \ -@@ -38,14 +44,21 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ - wcscoll_l wcsxfrm_l \ - wcscasecmp wcsncase wcscasecmp_l wcsncase_l \ - wcsmbsload mbsrtowcs_l \ -- isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \ - isoc99_swscanf isoc99_vswscanf \ - mbrtoc16 c16rtomb - --strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy --tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ -- tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ -- tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) -+routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \ -+ += isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf -+ -+strop-tests := wcscmp wmemcmp wmemcmp wcslen wcschr wcsrchr wcscpy -+ -+tests := tst-wchar-h -+tests-$(OPTION_EGLIBC_LOCALE_CODE) \ -+ += tst-btowc tst-mbrtowc tst-mbrtowc2 tst-wcrtomb tst-c16c32-1 -+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ -+ += tst-wcstof wcsmbs-tst1 tst-wcsnlen \ -+ tst-wcpncpy tst-mbsrtowcs \ -+ wcsatcliff $(addprefix test-,$(strop-tests)) - - include ../Rules - -diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c -index 6bb49bc..2ab9d07 100644 ---- a/wcsmbs/wcsmbsload.c -+++ b/wcsmbs/wcsmbsload.c -@@ -21,6 +21,7 @@ - #include <limits.h> - #include <stdlib.h> - #include <string.h> -+#include <gnu/option-groups.h> - - #include <locale/localeinfo.h> - #include <wcsmbsload.h> -@@ -143,6 +144,7 @@ __wcsmbs_getfct (const char *to, const char *from, size_t *nstepsp) - }) - - -+#if __OPTION_EGLIBC_LOCALE_CODE - /* Some of the functions here must not be used while setlocale is called. */ - __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden) - -@@ -211,6 +213,17 @@ __wcsmbs_load_conv (struct __locale_data *new_category) - - __libc_rwlock_unlock (__libc_setlocale_lock); - } -+#else -+void -+internal_function -+__wcsmbs_load_conv (struct __locale_data *new_category) -+{ -+ /* When OPTION_EGLIBC_LOCALE_CODE is disabled, we should never reach -+ this point: there is no way to change locales, so every locale -+ passed to get_gconv_fcts should be _nl_C_LC_CTYPE. */ -+ abort (); -+} -+#endif - - - /* Clone the current conversion function set. */ -diff --git a/wctype/Makefile b/wctype/Makefile -index c56f07c..4e8af43 100644 ---- a/wctype/Makefile -+++ b/wctype/Makefile -@@ -18,14 +18,20 @@ - # - # Sub-makefile for wctype portion of the library. - # -+include ../option-groups.mak -+ - subdir := wctype - - include ../Makeconfig - - headers := wctype.h --routines := wcfuncs wctype iswctype wctrans towctrans \ -- wcfuncs_l wctype_l iswctype_l wctrans_l towctrans_l -- --tests := test_wctype test_wcfuncs bug-wctypeh -+routines := wctrans towctrans towctrans_l -+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ -+ := wcfuncs wctype iswctype \ -+ wcfuncs_l wctype_l iswctype_l wctrans_l -+ -+tests := -+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ -+ += test_wctype test_wcfuncs bug-wctypeh - - include ../Rules --- -2.1.4 - diff --git a/meta/recipes-core/glibc/glibc/0025-eglibc-Forward-port-cross-locale-generation-support.patch b/meta/recipes-core/glibc/glibc/0025-eglibc-Forward-port-cross-locale-generation-support.patch new file mode 100644 index 00000000000..68d11192acf --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0025-eglibc-Forward-port-cross-locale-generation-support.patch @@ -0,0 +1,566 @@ +From a5695930aec68b3f501e475d8705cddbb63f695e 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 25/25] eglibc: Forward port cross locale generation support + +Upstream-Status: Pending + +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- + locale/Makefile | 3 ++- + locale/catnames.c | 48 +++++++++++++++++++++++++++++++++++ + 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-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 ---------------------- + 12 files changed, 169 insertions(+), 69 deletions(-) + create mode 100644 locale/catnames.c + +diff --git a/locale/Makefile b/locale/Makefile +index 75afbe1..d32523b 100644 +--- a/locale/Makefile ++++ b/locale/Makefile +@@ -25,7 +25,8 @@ 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 ++ newlocale duplocale freelocale uselocale \ ++ catnames + tests = tst-C-locale tst-locname tst-duplocale + categories = ctype messages monetary numeric time paper name \ + address telephone measurement identification collate +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/localeinfo.h b/locale/localeinfo.h +index 789da44..4ac9249 100644 +--- a/locale/localeinfo.h ++++ b/locale/localeinfo.h +@@ -224,7 +224,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 dc0fe30..3c88c6d 100644 +--- a/locale/programs/ld-collate.c ++++ b/locale/programs/ld-collate.c +@@ -350,7 +350,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) +@@ -1776,8 +1776,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) + { +@@ -2010,9 +2009,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)) + { +@@ -2036,9 +2035,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-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 fd6ca51..328d36c 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 ead030d..b551332 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 +-- +2.6.4 + diff --git a/meta/recipes-core/glibc/glibc/0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch b/meta/recipes-core/glibc/glibc/0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch new file mode 100644 index 00000000000..2b889a94cf7 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch @@ -0,0 +1,48 @@ +From 97fe7f1b23ea1f17533884b8fa7f7eb40087d558 Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Tue, 5 Jan 2016 17:50:00 -0800 +Subject: [PATCH] When disabling SSE, make sure -fpmath is not set to use SSE + either + +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 + +gcc -m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -x c /dev/null -S +-mno-sse -mno-mmx + +generates warning +/dev/null:1:0: warning: SSE instruction set disabled, using 387 +arithmetics + +where as + +gcc -m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -x c /dev/null -S +-mno-sse -mno-mmx -mfpmath=387 + +Generates no warnings + +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- +Upstream-Status: Submitted + + ChangeLog | 5 +++++ + sysdeps/i386/Makefile | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile +index 168512f..70153b3 100644 +--- a/sysdeps/i386/Makefile ++++ b/sysdeps/i386/Makefile +@@ -89,7 +89,7 @@ ifeq ($(subdir),elf) + # the first 3 mm/xmm/ymm/zmm registers are used to pass vector parameters + # which must be preserved. + 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/i386/tst-ld-sse-use.sh $(objpfx)ld.so +-- +2.6.4 + diff --git a/meta/recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch b/meta/recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch deleted file mode 100644 index 6b611dbde7c..00000000000 --- a/meta/recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch +++ /dev/null @@ -1,556 +0,0 @@ -From ba069b3107f5ad200c4ab95e69cf368e2353b00a Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Wed, 18 Mar 2015 00:46:50 +0000 -Subject: [PATCH 26/27] eglibc: dl_debug_mask is controlled by - __OPTION_EGLIBC_RTLD_DEBUG - -use GLRO_dl_debug_mask - -Singed-off-by: Khem Raj <raj.khem@gmail.com> - -Upstream-Status: Pending ---- - csu/libc-start.c | 4 ++-- - elf/dl-cache.c | 4 ++-- - elf/dl-close.c | 6 +++--- - elf/dl-conflict.c | 2 +- - elf/dl-deps.c | 6 +++--- - elf/dl-error.c | 2 +- - elf/dl-fini.c | 4 ++-- - elf/dl-init.c | 4 ++-- - elf/dl-load.c | 16 ++++++++-------- - elf/dl-lookup.c | 14 +++++++------- - elf/dl-object.c | 2 +- - elf/dl-open.c | 10 +++++----- - elf/dl-reloc.c | 2 +- - elf/dl-version.c | 2 +- - elf/get-dynamic-info.h | 2 +- - elf/rtld.c | 22 +++++++++++----------- - 16 files changed, 51 insertions(+), 51 deletions(-) - -diff --git a/csu/libc-start.c b/csu/libc-start.c -index 0afa7c0..2151fb6 100644 ---- a/csu/libc-start.c -+++ b/csu/libc-start.c -@@ -238,7 +238,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), - - /* Call the initializer of the program, if any. */ - #ifdef SHARED -- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) -+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) - GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]); - #endif - if (init) -@@ -261,7 +261,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), - #endif - - #ifdef SHARED -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS)) - GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]); - #endif - -diff --git a/elf/dl-cache.c b/elf/dl-cache.c -index 862f1d8..dab9c51 100644 ---- a/elf/dl-cache.c -+++ b/elf/dl-cache.c -@@ -194,7 +194,7 @@ _dl_load_cache_lookup (const char *name) - const char *best; - - /* Print a message if the loading of libs is traced. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) - _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE); - - if (cache == NULL) -@@ -292,7 +292,7 @@ _dl_load_cache_lookup (const char *name) - } - - /* Print our result if wanted. */ -- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0) -+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0) - && best != NULL) - _dl_debug_printf (" trying file=%s\n", best); - -diff --git a/elf/dl-close.c b/elf/dl-close.c -index c897247..b1b4bd5 100644 ---- a/elf/dl-close.c -+++ b/elf/dl-close.c -@@ -125,7 +125,7 @@ _dl_close_worker (struct link_map *map, bool force) - dl_close_state = rerun; - - /* There are still references to this object. Do nothing more. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) - _dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n", - map->l_name, map->l_direct_opencount); - -@@ -269,7 +269,7 @@ _dl_close_worker (struct link_map *map, bool force) - if (imap->l_init_called) - { - /* When debugging print a message first. */ -- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, -+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, - 0)) - _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n", - imap->l_name, nsid); -@@ -711,7 +711,7 @@ _dl_close_worker (struct link_map *map, bool force) - free (imap->l_reldeps); - - /* Print debugging message. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) - _dl_debug_printf ("\nfile=%s [%lu]; destroying link map\n", - imap->l_name, imap->l_ns); - -diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c -index 47a946e..e6a3f21 100644 ---- a/elf/dl-conflict.c -+++ b/elf/dl-conflict.c -@@ -32,7 +32,7 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, - ElfW(Rela) *conflictend) - { - #if ! ELF_MACHINE_NO_RELA -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC)) - _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name)); - - { -diff --git a/elf/dl-deps.c b/elf/dl-deps.c -index eee146a..1a4b004 100644 ---- a/elf/dl-deps.c -+++ b/elf/dl-deps.c -@@ -127,7 +127,7 @@ empty dynamic string token substitution")); \ - else \ - { \ - /* This is for DT_AUXILIARY. */ \ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) \ -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) \ - _dl_debug_printf (N_("\ - cannot load auxiliary `%s' because of empty dynamic string token " \ - "substitution\n"), __str); \ -@@ -303,7 +303,7 @@ _dl_map_object_deps (struct link_map *map, - args.name = name; - - /* Say that we are about to load an auxiliary library. */ -- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, -+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, - 0)) - _dl_debug_printf ("load auxiliary object=%s" - " requested by file=%s\n", -@@ -520,7 +520,7 @@ _dl_map_object_deps (struct link_map *map, - runp->map->l_reserved = 0; - } - -- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0 -+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_PRELINK, 0) != 0 - && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded) - { - /* If we are to compute conflicts, we have to build local scope -diff --git a/elf/dl-error.c b/elf/dl-error.c -index 0fc3fd8..ea82f4d 100644 ---- a/elf/dl-error.c -+++ b/elf/dl-error.c -@@ -139,7 +139,7 @@ internal_function - _dl_signal_cerror (int errcode, const char *objname, const char *occation, - const char *errstring) - { -- if (__builtin_expect (GLRO(dl_debug_mask) -+ if (__builtin_expect (GLRO_dl_debug_mask - & ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0)) - _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation, - errstring, receiver ? "continued" : "fatal"); -diff --git a/elf/dl-fini.c b/elf/dl-fini.c -index 6cfe651..f59f7fe 100644 ---- a/elf/dl-fini.c -+++ b/elf/dl-fini.c -@@ -234,7 +234,7 @@ _dl_fini (void) - || l->l_info[DT_FINI] != NULL) - { - /* When debugging print a message first. */ -- if (__builtin_expect (GLRO(dl_debug_mask) -+ if (__builtin_expect (GLRO_dl_debug_mask - & DL_DEBUG_IMPCALLS, 0)) - _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n", - DSO_FILENAME (l->l_name), -@@ -286,7 +286,7 @@ _dl_fini (void) - goto again; - } - -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS)) - _dl_debug_printf ("\nruntime linker statistics:\n" - " final number of relocations: %lu\n" - "final number of relocations from cache: %lu\n", -diff --git a/elf/dl-init.c b/elf/dl-init.c -index 2f85731..e46e8b6 100644 ---- a/elf/dl-init.c -+++ b/elf/dl-init.c -@@ -46,7 +46,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env) - return; - - /* Print a debug message if wanted. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS)) - _dl_debug_printf ("\ncalling init: %s\n\n", - DSO_FILENAME (l->l_name)); - -@@ -96,7 +96,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env) - ElfW(Addr) *addrs; - unsigned int cnt; - -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS)) - _dl_debug_printf ("\ncalling preinit: %s\n\n", - DSO_FILENAME (main_map->l_name)); - -diff --git a/elf/dl-load.c b/elf/dl-load.c -index f664f50..8c28744 100644 ---- a/elf/dl-load.c -+++ b/elf/dl-load.c -@@ -943,7 +943,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, - } - - /* Print debugging message. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) - _dl_debug_printf ("file=%s [%lu]; generating link map\n", name, nsid); - - /* This is the ELF header. We read it in `open_verify'. */ -@@ -1347,7 +1347,7 @@ cannot enable executable stack as shared object requires"); - - l->l_entry += l->l_addr; - -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) - _dl_debug_printf ("\ - dynamic: 0x%0*lx base: 0x%0*lx size: 0x%0*Zx\n\ - entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u\n\n", -@@ -1789,7 +1789,7 @@ open_path (const char *name, size_t namelen, int mode, - - /* If we are debugging the search for libraries print the path - now if it hasn't happened now. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS) - && current_what != this_dir->what) - { - current_what = this_dir->what; -@@ -1810,7 +1810,7 @@ open_path (const char *name, size_t namelen, int mode, - - buf); - - /* Print name we try if this is wanted. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) - _dl_debug_printf (" trying file=%s\n", buf); - - fd = open_verify (buf, fbp, loader, whatcode, mode, -@@ -1955,7 +1955,7 @@ _dl_map_object (struct link_map *loader, const char *name, - } - - /* Display information if we are debugging. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES) - && loader != NULL) - _dl_debug_printf ((mode & __RTLD_CALLMAP) == 0 - ? "\nfile=%s [%lu]; needed by %s [%lu]\n" -@@ -1997,7 +1997,7 @@ _dl_map_object (struct link_map *loader, const char *name, - - size_t namelen = strlen (name) + 1; - -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) - _dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid); - - fd = -1; -@@ -2119,7 +2119,7 @@ _dl_map_object (struct link_map *loader, const char *name, - #endif - - /* Add another newline when we are tracing the library loading. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) - _dl_debug_printf ("\n"); - } - else -@@ -2152,7 +2152,7 @@ _dl_map_object (struct link_map *loader, const char *name, - if (__glibc_unlikely (fd == -1)) - { - if (trace_mode -- && __glibc_likely ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) == 0)) -+ && __glibc_likely ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK) == 0)) - { - /* We haven't found an appropriate library. But since we - are only interested in the list of libraries this isn't -diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c -index 11cb44b..588c3e4 100644 ---- a/elf/dl-lookup.c -+++ b/elf/dl-lookup.c -@@ -302,7 +302,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, - hash table. */ - if (__glibc_unlikely (tab->size)) - { -- assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK); -+ assert (GLRO_dl_debug_mask & DL_DEBUG_PRELINK); - goto success; - } - #endif -@@ -378,7 +378,7 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, - continue; - - /* Print some debugging info if wanted. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SYMBOLS)) - _dl_debug_printf ("symbol=%s; lookup in file=%s [%lu]\n", - undef_name, DSO_FILENAME (map->l_name), - map->l_ns); -@@ -755,7 +755,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) - } - - /* Display information if we are debugging. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) - _dl_debug_printf ("\ - \nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n", - DSO_FILENAME (map->l_name), -@@ -859,7 +859,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, - { - if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) - && skip_map == NULL -- && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)) -+ && !(GLRO_dl_debug_mask & DL_DEBUG_UNUSED)) - { - /* We could find no value for a strong reference. */ - const char *reference_name = undef_map ? undef_map->l_name : ""; -@@ -935,7 +935,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, - if (__glibc_unlikely (current_value.m->l_used == 0)) - current_value.m->l_used = 1; - -- if (__glibc_unlikely (GLRO(dl_debug_mask) -+ if (__glibc_unlikely (GLRO_dl_debug_mask - & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK))) - _dl_debug_bindings (undef_name, undef_map, ref, - ¤t_value, version, type_class, protected); -@@ -1000,7 +1000,7 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, - { - const char *reference_name = undef_map->l_name; - -- if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS) -+ if (GLRO_dl_debug_mask & DL_DEBUG_BINDINGS) - { - _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'", - DSO_FILENAME (reference_name), -@@ -1014,7 +1014,7 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, - _dl_debug_printf_c ("\n"); - } - #ifdef SHARED -- if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) -+ if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK) - { - int conflict = 0; - struct sym_val val = { NULL, NULL }; -diff --git a/elf/dl-object.c b/elf/dl-object.c -index 1d58bbc..938a257 100644 ---- a/elf/dl-object.c -+++ b/elf/dl-object.c -@@ -98,7 +98,7 @@ _dl_new_object (char *realname, const char *libname, int type, - new->l_type = type; - /* If we set the bit now since we know it is never used we avoid - dirtying the cache line later. */ -- if ((GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) == 0) -+ if ((GLRO_dl_debug_mask & DL_DEBUG_UNUSED) == 0) - new->l_used = 1; - new->l_loader = loader; - #if NO_TLS_OFFSET != 0 -diff --git a/elf/dl-open.c b/elf/dl-open.c -index 2db1c02..1288604 100644 ---- a/elf/dl-open.c -+++ b/elf/dl-open.c -@@ -147,7 +147,7 @@ add_to_global (struct link_map *new) - ns->_ns_main_searchlist->r_list[new_nlist++] = map; - - /* We modify the global scope. Report this. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES)) - _dl_debug_printf ("\nadd %s [%lu] to global scope\n", - map->l_name, map->l_ns); - } -@@ -251,7 +251,7 @@ dl_open_worker (void *a) - if (__glibc_unlikely (new->l_searchlist.r_list != NULL)) - { - /* Let the user know about the opencount. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) - _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", - new->l_name, new->l_ns, new->l_direct_opencount); - -@@ -302,7 +302,7 @@ dl_open_worker (void *a) - LIBC_PROBE (map_complete, 3, args->nsid, r, new); - - /* Print scope information. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES)) - _dl_show_scope (new, 0); - - /* Only do lazy relocation if `LD_BIND_NOW' is not set. */ -@@ -519,7 +519,7 @@ dl_open_worker (void *a) - } - - /* Print scope information. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES)) - _dl_show_scope (imap, from_scope); - } - -@@ -577,7 +577,7 @@ TLS generation counter wrapped! Please report this.")); - #endif - - /* Let the user know about the opencount. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) - _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", - new->l_name, new->l_ns, new->l_direct_opencount); - } -diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c -index 61252d7..4c83815 100644 ---- a/elf/dl-reloc.c -+++ b/elf/dl-reloc.c -@@ -178,7 +178,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], - && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0)) - lazy = 0; - -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC)) - _dl_debug_printf ("\nrelocation processing: %s%s\n", - DSO_FILENAME (l->l_name), lazy ? " (lazy)" : ""); - -diff --git a/elf/dl-version.c b/elf/dl-version.c -index f6e5cd9..320628c 100644 ---- a/elf/dl-version.c -+++ b/elf/dl-version.c -@@ -82,7 +82,7 @@ match_symbol (const char *name, Lmid_t ns, ElfW(Word) hash, const char *string, - int result = 0; - - /* Display information about what we are doing while debugging. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_VERSIONS)) - _dl_debug_printf ("\ - checking for version `%s' in file %s [%lu] required by file %s [%lu]\n", - string, DSO_FILENAME (map->l_name), -diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h -index dc8359d..7774fda 100644 ---- a/elf/get-dynamic-info.h -+++ b/elf/get-dynamic-info.h -@@ -166,7 +166,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) - them. Therefore to avoid breaking existing applications the - best we can do is add a warning during debugging with the - intent of notifying the user of the problem. */ -- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0) -+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0) - && l->l_flags_1 & ~DT_1_SUPPORTED_MASK) - _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.\n", - l->l_flags_1 & ~DT_1_SUPPORTED_MASK); -diff --git a/elf/rtld.c b/elf/rtld.c -index fc3a2db..59c4637 100644 ---- a/elf/rtld.c -+++ b/elf/rtld.c -@@ -323,7 +323,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) - } - #endif - -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS)) - { - #ifndef HP_TIMING_NONAVAIL - print_statistics (&rtld_total_time); -@@ -1701,7 +1701,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", - after relocation. */ - struct link_map *l; - -- if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) -+ if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK) - { - struct r_scope_elem *scope = &main_map->l_searchlist; - -@@ -1731,7 +1731,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", - _dl_printf ("\n"); - } - } -- else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) -+ else if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED) - { - /* Look through the dependencies of the main executable - and determine which of them is not actually -@@ -1839,7 +1839,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", - } - } - -- if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) -+ if ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK) - && rtld_multiple_ref) - { - /* Mark the link map as not yet relocated again. */ -@@ -1972,7 +1972,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", - if (r_list == r_listend && liblist == liblistend) - prelinked = true; - -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) - _dl_debug_printf ("\nprelink checking: %s\n", - prelinked ? "ok" : "failed"); - } -@@ -1990,7 +1990,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", - GLRO(dl_init_all_dirs) = GL(dl_all_dirs); - - /* Print scope information. */ -- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) -+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES)) - { - _dl_debug_printf ("\nInitial object scopes\n"); - -@@ -2265,7 +2265,7 @@ process_dl_debug (const char *dl_debug) - if (debopts[cnt].len == len - && memcmp (dl_debug, debopts[cnt].name, len) == 0) - { -- GLRO(dl_debug_mask) |= debopts[cnt].mask; -+ GLRO_dl_debug_mask |= debopts[cnt].mask; - any_debug = 1; - break; - } -@@ -2286,7 +2286,7 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy); - ++dl_debug; - } - -- if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) -+ if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED) - { - /* In order to get an accurate picture of whether a particular - DT_NEEDED entry is actually used we have to process both -@@ -2294,7 +2294,7 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy); - GLRO(dl_lazy) = 0; - } - -- if (GLRO(dl_debug_mask) & DL_DEBUG_HELP) -+ if (GLRO_dl_debug_mask & DL_DEBUG_HELP) - { - size_t cnt; - -@@ -2499,7 +2499,7 @@ process_envvars (enum mode *modep) - mode = trace; - GLRO(dl_verbose) = 1; - #if __OPTION_EGLIBC_RTLD_DEBUG -- GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK; -+ GLRO_dl_debug_mask |= DL_DEBUG_PRELINK; - #endif - GLRO(dl_trace_prelink) = &envline[17]; - } -@@ -2548,7 +2548,7 @@ process_envvars (enum mode *modep) - { - unsetenv ("MALLOC_CHECK_"); - #if __OPTION_EGLIBC_RTLD_DEBUG -- GLRO(dl_debug_mask) = 0; -+ GLRO_dl_debug_mask = 0; - #endif - } - --- -2.1.4 - diff --git a/meta/recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch b/meta/recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch deleted file mode 100644 index 4106167df51..00000000000 --- a/meta/recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch +++ /dev/null @@ -1,145 +0,0 @@ -From e98779aa56fae0346dff2d0b72acadd0eaf01891 Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Wed, 27 May 2015 16:10:50 -0700 -Subject: [PATCH 27/27] eglibc-use-option-groups: Conditionally exclude c++ - tests - - Some test programs written in c++ are still included in spite of - "libc-cxx-tests" being omitted from DISTRO_FEATURES_LIBC. - All .cc programs are compiled with g++. - g++ automatically specifies linking against the C++ library. - This patch conditionally excludes the following tests as well: - - bug-atexit3-lib.cc - tst-cancel24.cc - tst-cancel24-static.cc - tst-unique3lib.cc - tst-unique3lib2.cc - tst-unique4lib.cc - tst-unique3.cc - tst-unique4.cc - - Tested with DISTRO_FEATURES_LIBC_remove = " libc-cxx-tests" - - [YOCTO #7003] - -Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - dlfcn/Makefile | 8 ++++++-- - elf/Makefile | 19 ++++++++++++++----- - nptl/Makefile | 12 ++++++++++-- - 3 files changed, 30 insertions(+), 9 deletions(-) - -diff --git a/dlfcn/Makefile b/dlfcn/Makefile -index 3827607..920bd58 100644 ---- a/dlfcn/Makefile -+++ b/dlfcn/Makefile -@@ -39,16 +39,20 @@ ifeq (yes,$(build-shared)) - tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \ - bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \ - tstatexit bug-dl-leaf tst-rec-dlopen --endif -- - tests-$(OPTION_EGLIBC_CXX_TESTS) += bug-atexit3 - -+endif -+ - modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \ - defaultmod2 errmsg1mod modatexit modcxaatexit \ - bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \ - bug-atexit2-lib bug-dl-leaf-lib \ - bug-dl-leaf-lib-cb moddummy1 moddummy2 - -+ifeq (y,$(OPTION_EGLIBC_CXX_TESTS)) -+modules-names += bug-atexit3-lib -+endif -+ - failtestmod.so-no-z-defs = yes - glreflib2.so-no-z-defs = yes - errmsg1mod.so-no-z-defs = yes -diff --git a/elf/Makefile b/elf/Makefile -index 71a18a1..26fe3c5 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -17,6 +17,8 @@ - - # Makefile for elf subdirectory of GNU C Library. - -+include ../option-groups.mak -+ - subdir := elf - - include ../Makeconfig -@@ -145,12 +147,15 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ - unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \ - tst-audit1 tst-audit2 tst-audit8 tst-audit9 \ - tst-stackguard1 tst-addr1 tst-thrlock \ -- tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \ -- tst-nodelete) \ -+ tst-unique1 tst-unique2 \ - tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \ - tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \ - tst-nodelete2 - # reldep9 -+ifeq (y,$(OPTION_EGLIBC_CXX_TESTS)) -+tests += $(if $(CXX),tst-unique3 tst-unique4 tst-nodelete) -+endif -+ - ifeq ($(build-hardcoded-path-in-tests),yes) - tests += tst-dlopen-aout - LDFLAGS-tst-dlopen-aout = $(no-pie-ldflag) -@@ -209,9 +214,6 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ - tst-unique1mod1 tst-unique1mod2 \ - tst-unique2mod1 tst-unique2mod2 \ - tst-auditmod9a tst-auditmod9b \ -- $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ -- tst-nodelete-uniquemod tst-nodelete-rtldmod \ -- tst-nodelete-zmod) \ - tst-initordera1 tst-initorderb1 \ - tst-initordera2 tst-initorderb2 \ - tst-initordera3 tst-initordera4 \ -@@ -220,6 +222,13 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ - tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \ - tst-array5dep tst-null-argv-lib \ - tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod -+ -+ifeq (y,$(OPTION_EGLIBC_CXX_TESTS)) -+modules-names += $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ -+ tst-nodelete-uniquemod tst-nodelete-rtldmod \ -+ tst-nodelete-zmod) -+endif -+ - ifeq (yes,$(have-protected-data)) - modules-names += tst-protected1moda tst-protected1modb - tests += tst-protected1a tst-protected1b -diff --git a/nptl/Makefile b/nptl/Makefile -index 596ca3c..50a708b 100644 ---- a/nptl/Makefile -+++ b/nptl/Makefile -@@ -390,12 +390,20 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \ - $(common-objpfx)libc.a - - tests-static += tst-locale1 tst-locale2 tst-stackguard1-static \ -- tst-cancel21-static tst-cancel24-static tst-cond8-static \ -+ tst-cancel21-static tst-cond8-static \ - tst-mutex8-static tst-mutexpi8-static tst-sem11-static \ - tst-sem12-static --tests += tst-stackguard1-static tst-cancel21-static tst-cancel24-static \ -+ -+ifeq (y,$(OPTION_EGLIBC_CXX_TESTS)) -+tests-static += tst-cancel24-static -+endif -+ -+tests += tst-stackguard1-static tst-cancel21-static \ - tst-cond8-static tst-mutex8-static tst-mutexpi8-static \ - tst-sem11-static tst-sem12-static -+ -+tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24-static -+ - xtests-static += tst-setuid1-static - - # These tests are linked with libc before libpthread --- -2.1.4 - diff --git a/meta/recipes-core/glibc/glibc/0028-Clear-ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA-for-prel.patch b/meta/recipes-core/glibc/glibc/0028-Clear-ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA-for-prel.patch deleted file mode 100644 index 3455df1cff3..00000000000 --- a/meta/recipes-core/glibc/glibc/0028-Clear-ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA-for-prel.patch +++ /dev/null @@ -1,84 +0,0 @@ -From cadaf1336332ca7bcdfe4a400776e5782a20e26d Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" <hjl.tools@gmail.com> -Date: Wed, 28 Oct 2015 07:49:44 -0700 -Subject: [PATCH] Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits for prelink - -prelink runs ld.so with the environment variable LD_TRACE_PRELINKING -set to dump the relocation type class from _dl_debug_bindings. prelink -has the following relocation type classes: - - #define RTYPE_CLASS_VALID 8 - #define RTYPE_CLASS_PLT (8|1) - #define RTYPE_CLASS_COPY (8|2) - #define RTYPE_CLASS_TLS (8|4) - -where ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA has a conflict with -RTYPE_CLASS_TLS. - -Since prelink only uses ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY -bits, we should clear the other bits when the DL_DEBUG_PRELINK bit is -set. - - [BZ #19178] - * elf/dl-lookup.c (RTYPE_CLASS_VALID): New. - (RTYPE_CLASS_PLT): Likewise. - (RTYPE_CLASS_COPY): Likewise. - (RTYPE_CLASS_TLS): Likewise. - (_dl_debug_bindings): Use RTYPE_CLASS_TLS and RTYPE_CLASS_VALID - to set relocation type class for DL_DEBUG_PRELINK. Keep only - ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY bits for - DL_DEBUG_PRELINK. - -Upstream-Status: submitted (https://sourceware.org/bugzilla/show_bug.cgi?id=19178) - -Signed-off-by: Mark Hatle <mark.hatle@windriver.com> ---- - elf/dl-lookup.c | 21 +++++++++++++++++++-- - 1 file changed, 19 insertions(+), 2 deletions(-) - -diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c -index 581fb20..6ae6cc3 100644 ---- a/elf/dl-lookup.c -+++ b/elf/dl-lookup.c -@@ -1016,6 +1016,18 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, - #ifdef SHARED - if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) - { -+/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with -+ LD_TRACE_PRELINKING. */ -+#define RTYPE_CLASS_VALID 8 -+#define RTYPE_CLASS_PLT (8|1) -+#define RTYPE_CLASS_COPY (8|2) -+#define RTYPE_CLASS_TLS (8|4) -+#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1 -+# error ELF_RTYPE_CLASS_PLT must be 0 or 1! -+#endif -+#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2 -+# error ELF_RTYPE_CLASS_COPY must be 0 or 2! -+#endif - int conflict = 0; - struct sym_val val = { NULL, NULL }; - -@@ -1071,12 +1083,17 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, - - if (value->s) - { -+ /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY -+ bits since since prelink only uses them. */ -+ type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY; - if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) - == STT_TLS)) -- type_class = 4; -+ /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS. */ -+ type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID; - else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) - == STT_GNU_IFUNC)) -- type_class |= 8; -+ /* Set the RTYPE_CLASS_VALID bit. */ -+ type_class |= RTYPE_CLASS_VALID; - } - - if (conflict --- -1.9.3 - diff --git a/meta/recipes-core/glibc/glibc/0029-fix-getmntent-empty-lines.patch b/meta/recipes-core/glibc/glibc/0029-fix-getmntent-empty-lines.patch deleted file mode 100644 index 390bb3034d2..00000000000 --- a/meta/recipes-core/glibc/glibc/0029-fix-getmntent-empty-lines.patch +++ /dev/null @@ -1,40 +0,0 @@ -From b0e805fa0d6fea33745952df7b7f5442ca4c374f Mon Sep 17 00:00:00 2001 -From: Mike Frysinger <vapier@gentoo.org> -Date: Fri, 28 Aug 2015 17:08:49 -0400 -Subject: [PATCH] getmntent: fix memory corruption w/blank lines [BZ #18887] - -The fix for BZ #17273 introduced a single byte of memory corruption when -the line is entirely blank. It would walk back past the start of the -buffer if the heap happened to be 0x20 or 0x09 and then write a NUL byte. - buffer = '\n'; - end_ptr = buffer; - while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t') - end_ptr--; - *end_ptr = '\0'; - -Fix that and rework the tests. Adding the testcase for BZ #17273 to the -existing \040 parser does not really make sense as it's unrelated, and -leads to confusing behavior: it implicitly relies on the new entry being -longer than the previous entry (since it just rewinds the FILE*). Split -it out into its own dedicated testcase instead. - -The original patch is at link https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=b0e805fa0d6fea33745952df7b7f5442ca4c374f. -Only code to mntent_r.c is kept in this patch, Change log, NEWS, Makefile, and test cases are excluded. - -Upstream-Status: Backport (upstreamed to 2.23) -Signed-off-by: Baoshan Pang <baoshan.pang@windriver.com> - -diff --git a/misc/mntent_r.c b/misc/mntent_r.c -index 6159873..19af8a8 100644 ---- a/misc/mntent_r.c -+++ b/misc/mntent_r.c -@@ -136,7 +136,8 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) - end_ptr = strchr (buffer, '\n'); - if (end_ptr != NULL) /* chop newline */ - { -- while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t') -+ while (end_ptr != buffer -+ && (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')) - end_ptr--; - *end_ptr = '\0'; - } diff --git a/meta/recipes-core/glibc/glibc/CVE-2015-7547.patch b/meta/recipes-core/glibc/glibc/CVE-2015-7547.patch deleted file mode 100644 index 4e539f84974..00000000000 --- a/meta/recipes-core/glibc/glibc/CVE-2015-7547.patch +++ /dev/null @@ -1,642 +0,0 @@ -From e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca Mon Sep 17 00:00:00 2001 -From: Carlos O'Donell <carlos@systemhalted.org> -Date: Tue, 16 Feb 2016 21:26:37 -0500 -Subject: [PATCH] CVE-2015-7547: getaddrinfo() stack-based buffer overflow (Bug - 18665). - -* A stack-based buffer overflow was found in libresolv when invoked from - libnss_dns, allowing specially crafted DNS responses to seize control - of execution flow in the DNS client. The buffer overflow occurs in - the functions send_dg (send datagram) and send_vc (send TCP) for the - NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC - family. The use of AF_UNSPEC triggers the low-level resolver code to - send out two parallel queries for A and AAAA. A mismanagement of the - buffers used for those queries could result in the response of a query - writing beyond the alloca allocated buffer created by - _nss_dns_gethostbyname4_r. Buffer management is simplified to remove - the overflow. Thanks to the Google Security Team and Red Hat for - reporting the security impact of this issue, and Robert Holiday of - Ciena for reporting the related bug 18665. (CVE-2015-7547) - -See also: -https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html -https://sourceware.org/ml/libc-alpha/2016-02/msg00418.html - -Upstream-Status: Backport -CVE: CVE-2015-7547 - -https://sourceware.org/git/?p=glibc.git;a=commit;h=e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca -minor tweeking to apply to Changelog and res_send.c - -Signed-off-by: Armin Kuster <akuster@mvista.com> - ---- - ChangeLog | 17 ++- - NEWS | 14 +++ - resolv/nss_dns/dns-host.c | 111 +++++++++++++++++++- - resolv/res_query.c | 3 + - resolv/res_send.c | 260 +++++++++++++++++++++++++++++++++++----------- - 5 files changed, 339 insertions(+), 66 deletions(-) - -Index: git/NEWS -=================================================================== ---- git.orig/NEWS -+++ git/NEWS -@@ -105,6 +105,20 @@ Security related changes: - depending on the length of the string passed as an argument to the - functions. Reported by Joseph Myers. - -+* A stack-based buffer overflow was found in libresolv when invoked from -+ libnss_dns, allowing specially crafted DNS responses to seize control -+ of execution flow in the DNS client. The buffer overflow occurs in -+ the functions send_dg (send datagram) and send_vc (send TCP) for the -+ NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC -+ family. The use of AF_UNSPEC triggers the low-level resolver code to -+ send out two parallel queries for A and AAAA. A mismanagement of the -+ buffers used for those queries could result in the response of a query -+ writing beyond the alloca allocated buffer created by -+ _nss_dns_gethostbyname4_r. Buffer management is simplified to remove -+ the overflow. Thanks to the Google Security Team and Red Hat for -+ reporting the security impact of this issue, and Robert Holiday of -+ Ciena for reporting the related bug 18665. (CVE-2015-7547) -+ - * The following bugs are resolved with this release: - - 6652, 10672, 12674, 12847, 12926, 13862, 14132, 14138, 14171, 14498, -Index: git/resolv/nss_dns/dns-host.c -=================================================================== ---- git.orig/resolv/nss_dns/dns-host.c -+++ git/resolv/nss_dns/dns-host.c -@@ -1031,7 +1031,10 @@ gaih_getanswer_slice (const querybuf *an - int h_namelen = 0; - - if (ancount == 0) -- return NSS_STATUS_NOTFOUND; -+ { -+ *h_errnop = HOST_NOT_FOUND; -+ return NSS_STATUS_NOTFOUND; -+ } - - while (ancount-- > 0 && cp < end_of_message && had_error == 0) - { -@@ -1208,7 +1211,14 @@ gaih_getanswer_slice (const querybuf *an - /* Special case here: if the resolver sent a result but it only - contains a CNAME while we are looking for a T_A or T_AAAA record, - we fail with NOTFOUND instead of TRYAGAIN. */ -- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND; -+ if (canon != NULL) -+ { -+ *h_errnop = HOST_NOT_FOUND; -+ return NSS_STATUS_NOTFOUND; -+ } -+ -+ *h_errnop = NETDB_INTERNAL; -+ return NSS_STATUS_TRYAGAIN; - } - - -@@ -1222,11 +1232,101 @@ gaih_getanswer (const querybuf *answer1, - - enum nss_status status = NSS_STATUS_NOTFOUND; - -+ /* Combining the NSS status of two distinct queries requires some -+ compromise and attention to symmetry (A or AAAA queries can be -+ returned in any order). What follows is a breakdown of how this -+ code is expected to work and why. We discuss only SUCCESS, -+ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns -+ that apply (though RETURN and MERGE exist). We make a distinction -+ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable). -+ A recoverable TRYAGAIN is almost always due to buffer size issues -+ and returns ERANGE in errno and the caller is expected to retry -+ with a larger buffer. -+ -+ Lastly, you may be tempted to make significant changes to the -+ conditions in this code to bring about symmetry between responses. -+ Please don't change anything without due consideration for -+ expected application behaviour. Some of the synthesized responses -+ aren't very well thought out and sometimes appear to imply that -+ IPv4 responses are always answer 1, and IPv6 responses are always -+ answer 2, but that's not true (see the implementation of send_dg -+ and send_vc to see response can arrive in any order, particularly -+ for UDP). However, we expect it holds roughly enough of the time -+ that this code works, but certainly needs to be fixed to make this -+ a more robust implementation. -+ -+ ---------------------------------------------- -+ | Answer 1 Status / | Synthesized | Reason | -+ | Answer 2 Status | Status | | -+ |--------------------------------------------| -+ | SUCCESS/SUCCESS | SUCCESS | [1] | -+ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] | -+ | SUCCESS/TRYAGAIN' | SUCCESS | [1] | -+ | SUCCESS/NOTFOUND | SUCCESS | [1] | -+ | SUCCESS/UNAVAIL | SUCCESS | [1] | -+ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] | -+ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] | -+ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] | -+ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] | -+ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] | -+ | TRYAGAIN'/SUCCESS | SUCCESS | [3] | -+ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] | -+ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] | -+ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] | -+ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] | -+ | NOTFOUND/SUCCESS | SUCCESS | [3] | -+ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] | -+ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] | -+ | NOTFOUND/NOTFOUND | NOTFOUND | [3] | -+ | NOTFOUND/UNAVAIL | UNAVAIL | [3] | -+ | UNAVAIL/SUCCESS | UNAVAIL | [4] | -+ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] | -+ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] | -+ | UNAVAIL/NOTFOUND | UNAVAIL | [4] | -+ | UNAVAIL/UNAVAIL | UNAVAIL | [4] | -+ ---------------------------------------------- -+ -+ [1] If the first response is a success we return success. -+ This ignores the state of the second answer and in fact -+ incorrectly sets errno and h_errno to that of the second -+ answer. However because the response is a success we ignore -+ *errnop and *h_errnop (though that means you touched errno on -+ success). We are being conservative here and returning the -+ likely IPv4 response in the first answer as a success. -+ -+ [2] If the first response is a recoverable TRYAGAIN we return -+ that instead of looking at the second response. The -+ expectation here is that we have failed to get an IPv4 response -+ and should retry both queries. -+ -+ [3] If the first response was not a SUCCESS and the second -+ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN, -+ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the -+ result from the second response, otherwise the first responses -+ status is used. Again we have some odd side-effects when the -+ second response is NOTFOUND because we overwrite *errnop and -+ *h_errnop that means that a first answer of NOTFOUND might see -+ its *errnop and *h_errnop values altered. Whether it matters -+ in practice that a first response NOTFOUND has the wrong -+ *errnop and *h_errnop is undecided. -+ -+ [4] If the first response is UNAVAIL we return that instead of -+ looking at the second response. The expectation here is that -+ it will have failed similarly e.g. configuration failure. -+ -+ [5] Testing this code is complicated by the fact that truncated -+ second response buffers might be returned as SUCCESS if the -+ first answer is a SUCCESS. To fix this we add symmetry to -+ TRYAGAIN with the second response. If the second response -+ is a recoverable error we now return TRYAGIN even if the first -+ response was SUCCESS. */ -+ - if (anslen1 > 0) - status = gaih_getanswer_slice(answer1, anslen1, qname, - &pat, &buffer, &buflen, - errnop, h_errnop, ttlp, - &first); -+ - if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND - || (status == NSS_STATUS_TRYAGAIN - /* We want to look at the second answer in case of an -@@ -1242,8 +1342,15 @@ gaih_getanswer (const querybuf *answer1, - &pat, &buffer, &buflen, - errnop, h_errnop, ttlp, - &first); -+ /* Use the second response status in some cases. */ - if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND) - status = status2; -+ /* Do not return a truncated second response (unless it was -+ unavoidable e.g. unrecoverable TRYAGAIN). */ -+ if (status == NSS_STATUS_SUCCESS -+ && (status2 == NSS_STATUS_TRYAGAIN -+ && *errnop == ERANGE && *h_errnop != NO_RECOVERY)) -+ status = NSS_STATUS_TRYAGAIN; - } - - return status; -Index: git/resolv/res_query.c -=================================================================== ---- git.orig/resolv/res_query.c -+++ git/resolv/res_query.c -@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp, - { - free (*answerp2); - *answerp2 = NULL; -+ *nanswerp2 = 0; - *answerp2_malloced = 0; - } - } -@@ -447,6 +448,7 @@ __libc_res_nsearch(res_state statp, - { - free (*answerp2); - *answerp2 = NULL; -+ *nanswerp2 = 0; - *answerp2_malloced = 0; - } - -@@ -521,6 +523,7 @@ __libc_res_nsearch(res_state statp, - { - free (*answerp2); - *answerp2 = NULL; -+ *nanswerp2 = 0; - *answerp2_malloced = 0; - } - if (saved_herrno != -1) -Index: git/resolv/res_send.c -=================================================================== ---- git.orig/resolv/res_send.c -+++ git/resolv/res_send.c -@@ -1,3 +1,20 @@ -+/* Copyright (C) 2016 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ <http://www.gnu.org/licenses/>. */ -+ - /* - * Copyright (c) 1985, 1989, 1993 - * The Regents of the University of California. All rights reserved. -@@ -363,6 +380,8 @@ __libc_res_nsend(res_state statp, const - #ifdef USE_HOOKS - if (__glibc_unlikely (statp->qhook || statp->rhook)) { - if (anssiz < MAXPACKET && ansp) { -+ /* Always allocate MAXPACKET, callers expect -+ this specific size. */ - u_char *buf = malloc (MAXPACKET); - if (buf == NULL) - return (-1); -@@ -638,6 +657,77 @@ get_nsaddr (res_state statp, int n) - return (struct sockaddr *) (void *) &statp->nsaddr_list[n]; - } - -+/* The send_vc function is responsible for sending a DNS query over TCP -+ to the nameserver numbered NS from the res_state STATP i.e. -+ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and -+ IPv6 queries at the same serially on the same socket. -+ -+ Please note that for TCP there is no way to disable sending both -+ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP -+ and sends the queries serially and waits for the result after each -+ sent query. This implemetnation should be corrected to honour these -+ options. -+ -+ Please also note that for TCP we send both queries over the same -+ socket one after another. This technically violates best practice -+ since the server is allowed to read the first query, respond, and -+ then close the socket (to service another client). If the server -+ does this, then the remaining second query in the socket data buffer -+ will cause the server to send the client an RST which will arrive -+ asynchronously and the client's OS will likely tear down the socket -+ receive buffer resulting in a potentially short read and lost -+ response data. This will force the client to retry the query again, -+ and this process may repeat until all servers and connection resets -+ are exhausted and then the query will fail. It's not known if this -+ happens with any frequency in real DNS server implementations. This -+ implementation should be corrected to use two sockets by default for -+ parallel queries. -+ -+ The query stored in BUF of BUFLEN length is sent first followed by -+ the query stored in BUF2 of BUFLEN2 length. Queries are sent -+ serially on the same socket. -+ -+ Answers to the query are stored firstly in *ANSP up to a max of -+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP -+ is non-NULL (to indicate that modifying the answer buffer is allowed) -+ then malloc is used to allocate a new response buffer and ANSCP and -+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes -+ are needed but ANSCP is NULL, then as much of the response as -+ possible is read into the buffer, but the results will be truncated. -+ When truncation happens because of a small answer buffer the DNS -+ packets header field TC will bet set to 1, indicating a truncated -+ message and the rest of the socket data will be read and discarded. -+ -+ Answers to the query are stored secondly in *ANSP2 up to a max of -+ *ANSSIZP2 bytes, with the actual response length stored in -+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2 -+ is non-NULL (required for a second query) then malloc is used to -+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer -+ size and *ANSP2_MALLOCED is set to 1. -+ -+ The ANSP2_MALLOCED argument will eventually be removed as the -+ change in buffer pointer can be used to detect the buffer has -+ changed and that the caller should use free on the new buffer. -+ -+ Note that the answers may arrive in any order from the server and -+ therefore the first and second answer buffers may not correspond to -+ the first and second queries. -+ -+ It is not supported to call this function with a non-NULL ANSP2 -+ but a NULL ANSCP. Put another way, you can call send_vc with a -+ single unmodifiable buffer or two modifiable buffers, but no other -+ combination is supported. -+ -+ It is the caller's responsibility to free the malloc allocated -+ buffers by detecting that the pointers have changed from their -+ original values i.e. *ANSCP or *ANSP2 has changed. -+ -+ If errors are encountered then *TERRNO is set to an appropriate -+ errno value and a zero result is returned for a recoverable error, -+ and a less-than zero result is returned for a non-recoverable error. -+ -+ If no errors are encountered then *TERRNO is left unmodified and -+ a the length of the first response in bytes is returned. */ - static int - send_vc(res_state statp, - const u_char *buf, int buflen, const u_char *buf2, int buflen2, -@@ -647,11 +737,7 @@ send_vc(res_state statp, - { - const HEADER *hp = (HEADER *) buf; - const HEADER *hp2 = (HEADER *) buf2; -- u_char *ans = *ansp; -- int orig_anssizp = *anssizp; -- // XXX REMOVE -- // int anssiz = *anssizp; -- HEADER *anhp = (HEADER *) ans; -+ HEADER *anhp = (HEADER *) *ansp; - struct sockaddr *nsap = get_nsaddr (statp, ns); - int truncating, connreset, n; - /* On some architectures compiler might emit a warning indicating -@@ -743,6 +829,8 @@ send_vc(res_state statp, - * Receive length & response - */ - int recvresp1 = 0; -+ /* Skip the second response if there is no second query. -+ To do that we mark the second response as received. */ - int recvresp2 = buf2 == NULL; - uint16_t rlen16; - read_len: -@@ -779,40 +867,14 @@ send_vc(res_state statp, - u_char **thisansp; - int *thisresplenp; - if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) { -+ /* We have not received any responses -+ yet or we only have one response to -+ receive. */ - thisanssizp = anssizp; - thisansp = anscp ?: ansp; - assert (anscp != NULL || ansp2 == NULL); - thisresplenp = &resplen; - } else { -- if (*anssizp != MAXPACKET) { -- /* No buffer allocated for the first -- reply. We can try to use the rest -- of the user-provided buffer. */ --#if __GNUC_PREREQ (4, 7) -- DIAG_PUSH_NEEDS_COMMENT; -- DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); --#endif --#if _STRING_ARCH_unaligned -- *anssizp2 = orig_anssizp - resplen; -- *ansp2 = *ansp + resplen; --#else -- int aligned_resplen -- = ((resplen + __alignof__ (HEADER) - 1) -- & ~(__alignof__ (HEADER) - 1)); -- *anssizp2 = orig_anssizp - aligned_resplen; -- *ansp2 = *ansp + aligned_resplen; --#endif --#if __GNUC_PREREQ (4, 7) -- DIAG_POP_NEEDS_COMMENT; --#endif -- } else { -- /* The first reply did not fit into the -- user-provided buffer. Maybe the second -- answer will. */ -- *anssizp2 = orig_anssizp; -- *ansp2 = *ansp; -- } -- - thisanssizp = anssizp2; - thisansp = ansp2; - thisresplenp = resplen2; -@@ -820,10 +882,14 @@ send_vc(res_state statp, - anhp = (HEADER *) *thisansp; - - *thisresplenp = rlen; -- if (rlen > *thisanssizp) { -- /* Yes, we test ANSCP here. If we have two buffers -- both will be allocatable. */ -- if (__glibc_likely (anscp != NULL)) { -+ /* Is the answer buffer too small? */ -+ if (*thisanssizp < rlen) { -+ /* If the current buffer is not the the static -+ user-supplied buffer then we can reallocate -+ it. */ -+ if (thisansp != NULL && thisansp != ansp) { -+ /* Always allocate MAXPACKET, callers expect -+ this specific size. */ - u_char *newp = malloc (MAXPACKET); - if (newp == NULL) { - *terrno = ENOMEM; -@@ -835,6 +901,9 @@ send_vc(res_state statp, - if (thisansp == ansp2) - *ansp2_malloced = 1; - anhp = (HEADER *) newp; -+ /* A uint16_t can't be larger than MAXPACKET -+ thus it's safe to allocate MAXPACKET but -+ read RLEN bytes instead. */ - len = rlen; - } else { - Dprint(statp->options & RES_DEBUG, -@@ -997,6 +1066,66 @@ reopen (res_state statp, int *terrno, in - return 1; - } - -+/* The send_dg function is responsible for sending a DNS query over UDP -+ to the nameserver numbered NS from the res_state STATP i.e. -+ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries -+ along with the ability to send the query in parallel for both stacks -+ (default) or serially (RES_SINGLKUP). It also supports serial lookup -+ with a close and reopen of the socket used to talk to the server -+ (RES_SNGLKUPREOP) to work around broken name servers. -+ -+ The query stored in BUF of BUFLEN length is sent first followed by -+ the query stored in BUF2 of BUFLEN2 length. Queries are sent -+ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP). -+ -+ Answers to the query are stored firstly in *ANSP up to a max of -+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP -+ is non-NULL (to indicate that modifying the answer buffer is allowed) -+ then malloc is used to allocate a new response buffer and ANSCP and -+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes -+ are needed but ANSCP is NULL, then as much of the response as -+ possible is read into the buffer, but the results will be truncated. -+ When truncation happens because of a small answer buffer the DNS -+ packets header field TC will bet set to 1, indicating a truncated -+ message, while the rest of the UDP packet is discarded. -+ -+ Answers to the query are stored secondly in *ANSP2 up to a max of -+ *ANSSIZP2 bytes, with the actual response length stored in -+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2 -+ is non-NULL (required for a second query) then malloc is used to -+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer -+ size and *ANSP2_MALLOCED is set to 1. -+ -+ The ANSP2_MALLOCED argument will eventually be removed as the -+ change in buffer pointer can be used to detect the buffer has -+ changed and that the caller should use free on the new buffer. -+ -+ Note that the answers may arrive in any order from the server and -+ therefore the first and second answer buffers may not correspond to -+ the first and second queries. -+ -+ It is not supported to call this function with a non-NULL ANSP2 -+ but a NULL ANSCP. Put another way, you can call send_vc with a -+ single unmodifiable buffer or two modifiable buffers, but no other -+ combination is supported. -+ -+ It is the caller's responsibility to free the malloc allocated -+ buffers by detecting that the pointers have changed from their -+ original values i.e. *ANSCP or *ANSP2 has changed. -+ -+ If an answer is truncated because of UDP datagram DNS limits then -+ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to -+ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1 -+ if any progress was made reading a response from the nameserver and -+ is used by the caller to distinguish between ECONNREFUSED and -+ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1). -+ -+ If errors are encountered then *TERRNO is set to an appropriate -+ errno value and a zero result is returned for a recoverable error, -+ and a less-than zero result is returned for a non-recoverable error. -+ -+ If no errors are encountered then *TERRNO is left unmodified and -+ a the length of the first response in bytes is returned. */ - static int - send_dg(res_state statp, - const u_char *buf, int buflen, const u_char *buf2, int buflen2, -@@ -1006,8 +1135,6 @@ send_dg(res_state statp, - { - const HEADER *hp = (HEADER *) buf; - const HEADER *hp2 = (HEADER *) buf2; -- u_char *ans = *ansp; -- int orig_anssizp = *anssizp; - struct timespec now, timeout, finish; - struct pollfd pfd[1]; - int ptimeout; -@@ -1040,6 +1167,8 @@ send_dg(res_state statp, - int need_recompute = 0; - int nwritten = 0; - int recvresp1 = 0; -+ /* Skip the second response if there is no second query. -+ To do that we mark the second response as received. */ - int recvresp2 = buf2 == NULL; - pfd[0].fd = EXT(statp).nssocks[ns]; - pfd[0].events = POLLOUT; -@@ -1203,55 +1332,56 @@ send_dg(res_state statp, - int *thisresplenp; - - if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) { -+ /* We have not received any responses -+ yet or we only have one response to -+ receive. */ - thisanssizp = anssizp; - thisansp = anscp ?: ansp; - assert (anscp != NULL || ansp2 == NULL); - thisresplenp = &resplen; - } else { -- if (*anssizp != MAXPACKET) { -- /* No buffer allocated for the first -- reply. We can try to use the rest -- of the user-provided buffer. */ --#if _STRING_ARCH_unaligned -- *anssizp2 = orig_anssizp - resplen; -- *ansp2 = *ansp + resplen; --#else -- int aligned_resplen -- = ((resplen + __alignof__ (HEADER) - 1) -- & ~(__alignof__ (HEADER) - 1)); -- *anssizp2 = orig_anssizp - aligned_resplen; -- *ansp2 = *ansp + aligned_resplen; --#endif -- } else { -- /* The first reply did not fit into the -- user-provided buffer. Maybe the second -- answer will. */ -- *anssizp2 = orig_anssizp; -- *ansp2 = *ansp; -- } -- - thisanssizp = anssizp2; - thisansp = ansp2; - thisresplenp = resplen2; - } - - if (*thisanssizp < MAXPACKET -- /* Yes, we test ANSCP here. If we have two buffers -- both will be allocatable. */ -- && anscp -+ /* If the current buffer is not the the static -+ user-supplied buffer then we can reallocate -+ it. */ -+ && (thisansp != NULL && thisansp != ansp) - #ifdef FIONREAD -+ /* Is the size too small? */ - && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0 - || *thisanssizp < *thisresplenp) - #endif - ) { -+ /* Always allocate MAXPACKET, callers expect -+ this specific size. */ - u_char *newp = malloc (MAXPACKET); - if (newp != NULL) { -- *anssizp = MAXPACKET; -- *thisansp = ans = newp; -+ *thisanssizp = MAXPACKET; -+ *thisansp = newp; - if (thisansp == ansp2) - *ansp2_malloced = 1; - } - } -+ /* We could end up with truncation if anscp was NULL -+ (not allowed to change caller's buffer) and the -+ response buffer size is too small. This isn't a -+ reliable way to detect truncation because the ioctl -+ may be an inaccurate report of the UDP message size. -+ Therefore we use this only to issue debug output. -+ To do truncation accurately with UDP we need -+ MSG_TRUNC which is only available on Linux. We -+ can abstract out the Linux-specific feature in the -+ future to detect truncation. */ -+ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) { -+ Dprint(statp->options & RES_DEBUG, -+ (stdout, ";; response may be truncated (UDP)\n") -+ ); -+ } -+ - HEADER *anhp = (HEADER *) *thisansp; - socklen_t fromlen = sizeof(struct sockaddr_in6); - assert (sizeof(from) <= fromlen); -Index: git/ChangeLog -=================================================================== ---- git.orig/ChangeLog -+++ git/ChangeLog -@@ -1,3 +1,18 @@ -+2016-02-15 Carlos O'Donell <carlos@redhat.com> -+ -+ [BZ #18665] -+ * resolv/nss_dns/dns-host.c (gaih_getanswer_slice): Always set -+ *herrno_p. -+ (gaih_getanswer): Document functional behviour. Return tryagain -+ if any result is tryagain. -+ * resolv/res_query.c (__libc_res_nsearch): Set buffer size to zero -+ when freed. -+ * resolv/res_send.c: Add copyright text. -+ (__libc_res_nsend): Document that MAXPACKET is expected. -+ (send_vc): Document. Remove buffer reuse. -+ (send_dg): Document. Remove buffer reuse. Set *thisanssizp to set the -+ size of the buffer. Add Dprint for truncated UDP buffer. -+ - 2015-09-26 Paul Pluzhnikov <ppluzhnikov@google.com> - - [BZ #18985] diff --git a/meta/recipes-core/glibc/glibc/strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch b/meta/recipes-core/glibc/glibc/strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch deleted file mode 100644 index 8ce255f1107..00000000000 --- a/meta/recipes-core/glibc/glibc/strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch +++ /dev/null @@ -1,323 +0,0 @@ -Upstream-Status: Backport - -Signed-off-by: Li Xin <lixin.fnst@cn.fujitsu.com> - -From https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=6c84109cfa26f35c3dfed3acb97d347361bd5849 -Author: Carlos O'Donell <carlos@systemhalted.org> -Date: Thu Oct 8 16:34:53 2015 -0400 - - strcoll: Remove incorrect STRDIFF-based optimization (Bug 18589). - - The optimization introduced in commit - f13c2a8dff2329c6692a80176262ceaaf8a6f74e, causes regressions in - sorting for languages that have digraphs that change sort order, like - cs_CZ which sorts ch between h and i. - - My analysis shows the fast-forwarding optimization in STRCOLL advances - through a digraph while possibly stopping in the middle which results - in a subsequent skipping of the digraph and incorrect sorting. The - optimization is incorrect as implemented and because of that I'm - removing it for 2.23, and I will also commit this fix for 2.22 where - it was originally introduced. - - This patch reverts the optimization, introduces a new bug-strcoll2.c - regression test that tests both cs_CZ.UTF-8 and da_DK.ISO-8859-1 and - ensures they sort one digraph each correctly. The optimization can't be - applied without regressing this test. - - Checked on x86_64, bug-strcoll2.c fails without this patch and passes - after. This will also get a fix on 2.22 which has the same bug. - - (cherry picked from commit 87701a58e291bd7ac3b407d10a829dac52c9c16e) ---- - locale/C-collate.c | 4 +- - locale/categories.def | 1 - - locale/langinfo.h | 1 - - locale/localeinfo.h | 7 ---- - locale/programs/ld-collate.c | 9 ----- - string/bug-strcoll2.c | 95 ++++++++++++++++++++++++++++++++++++++++++++ - string/strcoll_l.c | 39 +----------------- - wcsmbs/wcscoll_l.c | 1 - - 8 files changed, 98 insertions(+), 59 deletions(-) - create mode 100644 string/bug-strcoll2.c - -diff --git a/locale/C-collate.c b/locale/C-collate.c -index d7f3c55..06dfdfa 100644 ---- a/locale/C-collate.c -+++ b/locale/C-collate.c -@@ -144,8 +144,6 @@ const struct __locale_data _nl_C_LC_COLLATE attribute_hidden = - /* _NL_COLLATE_COLLSEQWC */ - { .string = (const char *) collseqwc }, - /* _NL_COLLATE_CODESET */ -- { .string = _nl_C_codeset }, -- /* _NL_COLLATE_ENCODING_TYPE */ -- { .word = __cet_8bit } -+ { .string = _nl_C_codeset } - } - }; -diff --git a/locale/categories.def b/locale/categories.def -index 045489d..a8dda53 100644 ---- a/locale/categories.def -+++ b/locale/categories.def -@@ -58,7 +58,6 @@ DEFINE_CATEGORY - DEFINE_ELEMENT (_NL_COLLATE_COLLSEQMB, "collate-collseqmb", std, wstring) - DEFINE_ELEMENT (_NL_COLLATE_COLLSEQWC, "collate-collseqwc", std, wstring) - DEFINE_ELEMENT (_NL_COLLATE_CODESET, "collate-codeset", std, string) -- DEFINE_ELEMENT (_NL_COLLATE_ENCODING_TYPE, "collate-encoding-type", std, word) - ), NO_POSTLOAD) - - -diff --git a/locale/langinfo.h b/locale/langinfo.h -index ffc5c7f..a565d9d 100644 ---- a/locale/langinfo.h -+++ b/locale/langinfo.h -@@ -255,7 +255,6 @@ enum - _NL_COLLATE_COLLSEQMB, - _NL_COLLATE_COLLSEQWC, - _NL_COLLATE_CODESET, -- _NL_COLLATE_ENCODING_TYPE, - _NL_NUM_LC_COLLATE, - - /* LC_CTYPE category: character classification. -diff --git a/locale/localeinfo.h b/locale/localeinfo.h -index a7516c0..c076d8e 100644 ---- a/locale/localeinfo.h -+++ b/locale/localeinfo.h -@@ -110,13 +110,6 @@ enum coll_sort_rule - sort_mask - }; - --/* Collation encoding type. */ --enum collation_encoding_type --{ -- __cet_other, -- __cet_8bit, -- __cet_utf8 --}; - - /* We can map the types of the entries into a few categories. */ - enum value_type -diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c -index 16e9039..3c88c6d 100644 ---- a/locale/programs/ld-collate.c -+++ b/locale/programs/ld-collate.c -@@ -32,7 +32,6 @@ - #include "linereader.h" - #include "locfile.h" - #include "elem-hash.h" --#include "../localeinfo.h" - - /* Uncomment the following line in the production version. */ - /* #define NDEBUG 1 */ -@@ -2130,8 +2129,6 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, - /* The words have to be handled specially. */ - if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB)) - add_locale_uint32 (&file, 0); -- else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE)) -- add_locale_uint32 (&file, __cet_other); - else - add_locale_empty (&file); - } -@@ -2495,12 +2492,6 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, - add_locale_raw_data (&file, collate->mbseqorder, 256); - add_locale_collseq_table (&file, &collate->wcseqorder); - add_locale_string (&file, charmap->code_set_name); -- if (strcmp (charmap->code_set_name, "UTF-8") == 0) -- add_locale_uint32 (&file, __cet_utf8); -- else if (charmap->mb_cur_max == 1) -- add_locale_uint32 (&file, __cet_8bit); -- else -- add_locale_uint32 (&file, __cet_other); - write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file); - - obstack_free (&weightpool, NULL); -diff --git a/string/bug-strcoll2.c b/string/bug-strcoll2.c -new file mode 100644 -index 0000000..950b090 ---- /dev/null -+++ b/string/bug-strcoll2.c -@@ -0,0 +1,95 @@ -+/* Bug 18589: sort-test.sh fails at random. -+ * Copyright (C) 1998-2015 Free Software Foundation, Inc. -+ * This file is part of the GNU C Library. -+ * Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. -+ * -+ * The GNU C Library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * The GNU C Library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with the GNU C Library; if not, see -+ * <http://www.gnu.org/licenses/>. */ -+ -+#include <stdio.h> -+#include <string.h> -+#include <locale.h> -+ -+/* An incorrect strcoll optimization resulted in incorrect -+ * results from strcoll for cs_CZ and da_DK. */ -+ -+int -+test_cs_CZ (void) -+{ -+ const char t1[] = "config"; -+ const char t2[] = "choose"; -+ if (setlocale (LC_ALL, "cs_CZ.UTF-8") == NULL) -+ { -+ perror ("setlocale"); -+ return 1; -+ } -+ /* In Czech the digraph ch sorts after c, therefore we expect -+ * config to sort before choose. */ -+ int a = strcoll (t1, t2); -+ int b = strcoll (t2, t1); -+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a); -+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b); -+ if (a < 0 && b > 0) -+ { -+ puts ("PASS: config < choose"); -+ return 0; -+ } -+ else -+ { -+ puts ("FAIL: Wrong sorting in cz_CZ.UTF-8."); -+ return 1; -+ } -+} -+ -+int -+test_da_DK (void) -+{ -+ const char t1[] = "AS"; -+ const char t2[] = "AA"; -+ if (setlocale (LC_ALL, "da_DK.ISO-8859-1") == NULL) -+ { -+ perror ("setlocale"); -+ return 1; -+ } -+ /* AA should be treated as the last letter of the Danish alphabet, -+ * hence sorting after AS. */ -+ int a = strcoll (t1, t2); -+ int b = strcoll (t2, t1); -+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a); -+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b); -+ if (a < 0 && b > 0) -+ { -+ puts ("PASS: AS < AA"); -+ return 0; -+ } -+ else -+ { -+ puts ("FAIL: Wrong sorting in da_DK.ISO-8859-1"); -+ return 1; -+ } -+} -+ -+static int -+do_test (void) -+{ -+ int err = 0; -+ err |= test_cs_CZ (); -+ err |= test_da_DK (); -+ return err; -+} -+ -+#define TEST_FUNCTION do_test () -+#include "../test-skeleton.c" -+ -+ -diff --git a/string/strcoll_l.c b/string/strcoll_l.c -index b36b18c..a18b65e 100644 ---- a/string/strcoll_l.c -+++ b/string/strcoll_l.c -@@ -30,7 +30,6 @@ - # define STRING_TYPE char - # define USTRING_TYPE unsigned char - # define STRCOLL __strcoll_l --# define STRDIFF __strdiff - # define STRCMP strcmp - # define WEIGHT_H "../locale/weight.h" - # define SUFFIX MB -@@ -43,19 +42,6 @@ - #include "../locale/localeinfo.h" - #include WEIGHT_H - --#define MASK_UTF8_7BIT (1 << 7) --#define MASK_UTF8_START (3 << 6) -- --size_t --STRDIFF (const STRING_TYPE *s, const STRING_TYPE *t) --{ -- size_t n; -- -- for (n = 0; *s != '\0' && *s++ == *t++; ++n) -- continue; -- -- return n; --} - - /* Track status while looking for sequences in a string. */ - typedef struct -@@ -274,29 +260,9 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) - const USTRING_TYPE *extra; - const int32_t *indirect; - -- /* In case there is no locale specific sort order (C / POSIX). */ - if (nrules == 0) - return STRCMP (s1, s2); - -- /* Fast forward to the position of the first difference. Needs to be -- encoding aware as the byte-by-byte comparison can stop in the middle -- of a char sequence for multibyte encodings like UTF-8. */ -- uint_fast32_t encoding = -- current->values[_NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE)].word; -- if (encoding != __cet_other) -- { -- size_t diff = STRDIFF (s1, s2); -- if (diff > 0) -- { -- if (encoding == __cet_utf8 && (*(s1 + diff) & MASK_UTF8_7BIT) != 0) -- do -- diff--; -- while (diff > 0 && (*(s1 + diff) & MASK_UTF8_START) != MASK_UTF8_START); -- s1 += diff; -- s2 += diff; -- } -- } -- - /* Catch empty strings. */ - if (__glibc_unlikely (*s1 == '\0') || __glibc_unlikely (*s2 == '\0')) - return (*s1 != '\0') - (*s2 != '\0'); -@@ -363,9 +329,8 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) - byte-level comparison to ensure that we don't waste time - going through multiple passes for totally equal strings - before proceeding to subsequent passes. */ -- if (pass == 0 && encoding == __cet_other && -- STRCMP (s1, s2) == 0) -- return result; -+ if (pass == 0 && STRCMP (s1, s2) == 0) -+ return result; - else - break; - } -diff --git a/wcsmbs/wcscoll_l.c b/wcsmbs/wcscoll_l.c -index 6d9384a..87f240d 100644 ---- a/wcsmbs/wcscoll_l.c -+++ b/wcsmbs/wcscoll_l.c -@@ -23,7 +23,6 @@ - #define STRING_TYPE wchar_t - #define USTRING_TYPE wint_t - #define STRCOLL __wcscoll_l --#define STRDIFF __wcsdiff - #define STRCMP __wcscmp - #define WEIGHT_H "../locale/weightwc.h" - #define SUFFIX WC --- -1.8.4.2 - diff --git a/meta/recipes-core/glibc/glibc/use_64bit_atomics.patch b/meta/recipes-core/glibc/glibc/use_64bit_atomics.patch deleted file mode 100644 index 16d7698207d..00000000000 --- a/meta/recipes-core/glibc/glibc/use_64bit_atomics.patch +++ /dev/null @@ -1,24 +0,0 @@ -This patch alows using 64 bit atomic instructions on a -32 bit platform. This is safe, providing x86 is Pentium or -later (would not work on i386, i486). Using 64 bit atomic -instructions bypasses code containing a bug as documented in -https://bugzilla.yoctoproject.org/show_bug.cgi?id=8140 - -Upstream-Status: Pending - -Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> - - -Index: libc/sysdeps/i386/i486/bits/atomic.h -=================================================================== ---- libc.orig/sysdeps/i386/i486/bits/atomic.h -+++ libc/sysdeps/i386/i486/bits/atomic.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 - - diff --git a/meta/recipes-core/glibc/glibc_2.22.bb b/meta/recipes-core/glibc/glibc_2.23.bb index c70d16e05ad..18f40660ece 100644 --- a/meta/recipes-core/glibc/glibc_2.22.bb +++ b/meta/recipes-core/glibc/glibc_2.23.bb @@ -5,9 +5,9 @@ LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \ file://posix/rxspencer/COPYRIGHT;md5=dc5485bb394a13b2332ec1c785f5d83a \ file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c" -DEPENDS += "gperf-native kconfig-frontends-native" +DEPENDS += "gperf-native" -SRCREV ?= "a34d1c6afc86521d6ad17662a3b5362d8481514c" +SRCREV ?= "e742928c1592b43db6809db4f39e67be151cdd27" SRCBRANCH ?= "release/${PV}/master" @@ -15,7 +15,6 @@ GLIBC_GIT_URI ?= "git://sourceware.org/git/glibc.git" UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+\.\d+(\.\d+)*)" SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \ - file://0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch \ file://0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch \ file://0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch \ file://0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch \ @@ -26,29 +25,17 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \ file://0012-Make-ld-version-output-matching-grok-gold-s-output.patch \ file://0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch \ file://0014-Add-unused-attribute.patch \ - file://0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch \ - file://0016-yes-within-the-path-sets-wrong-config-variables.patch \ - file://0017-timezone-re-written-tzselect-as-posix-sh.patch \ + file://0015-yes-within-the-path-sets-wrong-config-variables.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://nscd-no-bash.patch \ - file://0028-Clear-ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA-for-prel.patch \ - file://strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch \ - file://0029-fix-getmntent-empty-lines.patch \ - file://CVE-2015-8777.patch \ - file://CVE-2015-8779.patch \ - file://CVE-2015-9761_1.patch \ - file://CVE-2015-9761_2.patch \ - file://CVE-2015-8776.patch \ - file://CVE-2015-7547.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 \ + file://0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch \ " SRC_URI += "\ @@ -60,7 +47,7 @@ SRC_URI_append_class-nativesdk = "\ file://0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch \ file://0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch \ file://0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch \ - file://use_64bit_atomics.patch \ + file://0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch \ " S = "${WORKDIR}/git" @@ -89,7 +76,6 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \ --with-headers=${STAGING_INCDIR} \ --without-selinux \ --enable-obsolete-rpc \ - --with-kconfig=${STAGING_BINDIR_NATIVE} \ ${GLIBC_EXTRA_OECONF}" EXTRA_OECONF += "${@get_libc_fpu_setting(bb, d)}" diff --git a/meta/recipes-devtools/gcc/gcc-5.3.inc b/meta/recipes-devtools/gcc/gcc-5.3.inc index a2e347adfeb..06672995cd0 100644 --- a/meta/recipes-devtools/gcc/gcc-5.3.inc +++ b/meta/recipes-devtools/gcc/gcc-5.3.inc @@ -118,13 +118,13 @@ EXTRA_OECONF_BASE = "\ EXTRA_OECONF_INITIAL = "\ --disable-libmudflap \ --disable-libgomp \ - --disable-libssp \ --disable-libquadmath \ --with-system-zlib \ --disable-lto \ --disable-plugin \ --enable-decimal-float=no \ --without-isl \ + gcc_cv_libc_provides_ssp=yes \ " EXTRA_OECONF_append_libc-uclibc = " --disable-decimal-float " |