summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2016-01-02 21:37:22 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-02-21 09:32:43 +0000
commit91a1baaf57153a86b7e14318c9d36e1cc38e3077 (patch)
tree51bb1d2724bbc5d3b98d9412de9cab8fb7b02524
parentc1f9507c69cac8cc28fec837a4bbb070c52a8a39 (diff)
downloadpoky-91a1baaf57153a86b7e14318c9d36e1cc38e3077.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 (From OE-Core rev: 9c3d461c4d54d684b38ec4c038a1c3c2fb9923f0) Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/conf/distro/include/tcmode-default.inc4
-rw-r--r--meta/recipes-core/glibc/cross-localedef-native_2.23.bb (renamed from meta/recipes-core/glibc/cross-localedef-native_2.22.bb)23
-rw-r--r--meta/recipes-core/glibc/glibc-initial.inc1
-rw-r--r--meta/recipes-core/glibc/glibc-initial_2.23.bb (renamed from meta/recipes-core/glibc/glibc-initial_2.22.bb)2
-rw-r--r--meta/recipes-core/glibc/glibc-locale_2.23.bb (renamed from meta/recipes-core/glibc/glibc-locale_2.22.bb)0
-rw-r--r--meta/recipes-core/glibc/glibc-mtrace_2.23.bb (renamed from meta/recipes-core/glibc/glibc-mtrace_2.22.bb)0
-rw-r--r--meta/recipes-core/glibc/glibc-options.inc162
-rw-r--r--meta/recipes-core/glibc/glibc-scripts_2.23.bb (renamed from meta/recipes-core/glibc/glibc-scripts_2.22.bb)0
-rw-r--r--meta/recipes-core/glibc/glibc.inc17
-rw-r--r--meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch23
-rw-r--r--meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch10
-rw-r--r--meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch16
-rw-r--r--meta/recipes-core/glibc/glibc/0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch34
-rw-r--r--meta/recipes-core/glibc/glibc/0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch32
-rw-r--r--meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch8
-rw-r--r--meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch14
-rw-r--r--meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch8
-rw-r--r--meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch32
-rw-r--r--meta/recipes-core/glibc/glibc/0015-yes-within-the-path-sets-wrong-config-variables.patch (renamed from meta/recipes-core/glibc/glibc/0016-yes-within-the-path-sets-wrong-config-variables.patch)20
-rw-r--r--meta/recipes-core/glibc/glibc/0016-timezone-re-written-tzselect-as-posix-sh.patch (renamed from meta/recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch)10
-rw-r--r--meta/recipes-core/glibc/glibc/0017-Remove-bash-dependency-for-nscd-init-script.patch (renamed from meta/recipes-core/glibc/glibc/nscd-no-bash.patch)16
-rw-r--r--meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch6
-rw-r--r--meta/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch1436
-rw-r--r--meta/recipes-core/glibc/glibc/0019-eglibc-Help-bootstrap-cross-toolchain.patch (renamed from meta/recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch)8
-rw-r--r--meta/recipes-core/glibc/glibc/0020-eglibc-cherry-picked-from.patch (renamed from meta/recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch)36
-rw-r--r--meta/recipes-core/glibc/glibc/0021-eglibc-Clear-cache-lines-on-ppc8xx.patch (renamed from meta/recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch)28
-rw-r--r--meta/recipes-core/glibc/glibc/0022-eglibc-Resolve-__fpscr_values-on-SH4.patch (renamed from meta/recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch)6
-rw-r--r--meta/recipes-core/glibc/glibc/0023-eglibc-Install-PIC-archives.patch (renamed from meta/recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch)20
-rw-r--r--meta/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch16842
-rw-r--r--meta/recipes-core/glibc/glibc/0025-eglibc-Forward-port-cross-locale-generation-support.patch566
-rw-r--r--meta/recipes-core/glibc/glibc/0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch48
-rw-r--r--meta/recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch556
-rw-r--r--meta/recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch145
-rw-r--r--meta/recipes-core/glibc/glibc/0028-Clear-ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA-for-prel.patch84
-rw-r--r--meta/recipes-core/glibc/glibc/0029-fix-getmntent-empty-lines.patch40
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2015-7547.patch642
-rw-r--r--meta/recipes-core/glibc/glibc/strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch323
-rw-r--r--meta/recipes-core/glibc/glibc/use_64bit_atomics.patch24
-rw-r--r--meta/recipes-core/glibc/glibc_2.23.bb (renamed from meta/recipes-core/glibc/glibc_2.22.bb)40
-rw-r--r--meta/recipes-devtools/gcc/gcc-5.3.inc2
47 files changed, 816 insertions, 20510 deletions
diff --git a/meta/conf/distro/include/tcmode-default.inc b/meta/conf/distro/include/tcmode-default.inc
index 5622f3ec16..c412420eaf 100644
--- a/meta/conf/distro/include/tcmode-default.inc
+++ b/meta/conf/distro/include/tcmode-default.inc
@@ -22,11 +22,11 @@ PREFERRED_PROVIDER_virtual/${TARGET_PREFIX}libc-initial = "${TCLIBC}-initial"
22PREFERRED_PROVIDER_virtual/nativesdk-${SDK_PREFIX}libc-initial ?= "nativesdk-glibc-initial" 22PREFERRED_PROVIDER_virtual/nativesdk-${SDK_PREFIX}libc-initial ?= "nativesdk-glibc-initial"
23PREFERRED_PROVIDER_virtual/gettext ??= "gettext" 23PREFERRED_PROVIDER_virtual/gettext ??= "gettext"
24 24
25GCCVERSION ?= "5.%" 25GCCVERSION ?= "5.3%"
26SDKGCCVERSION ?= "${GCCVERSION}" 26SDKGCCVERSION ?= "${GCCVERSION}"
27BINUVERSION ?= "2.26%" 27BINUVERSION ?= "2.26%"
28GDBVERSION ?= "7.10%" 28GDBVERSION ?= "7.10%"
29GLIBCVERSION ?= "2.22" 29GLIBCVERSION ?= "2.23"
30UCLIBCVERSION ?= "1.0%" 30UCLIBCVERSION ?= "1.0%"
31LINUXLIBCVERSION ?= "4.4" 31LINUXLIBCVERSION ?= "4.4"
32 32
diff --git a/meta/recipes-core/glibc/cross-localedef-native_2.22.bb b/meta/recipes-core/glibc/cross-localedef-native_2.23.bb
index efcdf4dc63..fa930fd480 100644
--- a/meta/recipes-core/glibc/cross-localedef-native_2.22.bb
+++ b/meta/recipes-core/glibc/cross-localedef-native_2.23.bb
@@ -24,22 +24,19 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
24 ${EGLIBCPATCHES} \ 24 ${EGLIBCPATCHES} \
25" 25"
26EGLIBCPATCHES = "\ 26EGLIBCPATCHES = "\
27 file://0017-timezone-re-written-tzselect-as-posix-sh.patch \ 27 file://0016-timezone-re-written-tzselect-as-posix-sh.patch \
28 file://0017-Remove-bash-dependency-for-nscd-init-script.patch \
28 file://0018-eglibc-Cross-building-and-testing-instructions.patch \ 29 file://0018-eglibc-Cross-building-and-testing-instructions.patch \
29 file://0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch \ 30 file://0019-eglibc-Help-bootstrap-cross-toolchain.patch \
30 file://0020-eglibc-Help-bootstrap-cross-toolchain.patch \ 31 file://0020-eglibc-cherry-picked-from.patch \
31 file://0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch \ 32 file://0021-eglibc-Clear-cache-lines-on-ppc8xx.patch \
32 file://0022-eglibc-Clear-cache-lines-on-ppc8xx.patch \ 33 file://0022-eglibc-Resolve-__fpscr_values-on-SH4.patch \
33 file://0023-eglibc-Resolve-__fpscr_values-on-SH4.patch \ 34 file://0023-eglibc-Install-PIC-archives.patch \
34 file://0024-eglibc-Forward-port-eglibc-options-groups-support.patch \ 35 file://0025-eglibc-Forward-port-cross-locale-generation-support.patch \
35 file://0025-eglibc-Install-PIC-archives.patch \
36 file://0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch \
37 file://0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch \
38 file://strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch \
39" 36"
40 37
41SRCREV_glibc ?= "a34d1c6afc86521d6ad17662a3b5362d8481514c" 38SRCREV_glibc ?= "e742928c1592b43db6809db4f39e67be151cdd27"
42SRCREV_localedef ?= "c833367348d39dad7ba018990bfdaffaec8e9ed3" 39SRCREV_localedef ?= "5a81ff9f06a7a808d4c3d37bbf34077a4c5902ed"
43 40
44# Makes for a rather long rev (22 characters), but... 41# Makes for a rather long rev (22 characters), but...
45# 42#
diff --git a/meta/recipes-core/glibc/glibc-initial.inc b/meta/recipes-core/glibc/glibc-initial.inc
index 7214f71404..5975fd26c7 100644
--- a/meta/recipes-core/glibc/glibc-initial.inc
+++ b/meta/recipes-core/glibc/glibc-initial.inc
@@ -16,7 +16,6 @@ do_configure () {
16 --prefix=/usr \ 16 --prefix=/usr \
17 --without-cvs --disable-sanity-checks \ 17 --without-cvs --disable-sanity-checks \
18 --with-headers=${STAGING_DIR_TARGET}${includedir} \ 18 --with-headers=${STAGING_DIR_TARGET}${includedir} \
19 --with-kconfig=${STAGING_BINDIR_NATIVE} \
20 --enable-hacker-mode --enable-addons 19 --enable-hacker-mode --enable-addons
21} 20}
22 21
diff --git a/meta/recipes-core/glibc/glibc-initial_2.22.bb b/meta/recipes-core/glibc/glibc-initial_2.23.bb
index 8ab01dc79d..e86770e12d 100644
--- a/meta/recipes-core/glibc/glibc-initial_2.22.bb
+++ b/meta/recipes-core/glibc/glibc-initial_2.23.bb
@@ -1,8 +1,6 @@
1require glibc_${PV}.bb 1require glibc_${PV}.bb
2require glibc-initial.inc 2require glibc-initial.inc
3 3
4DEPENDS += "kconfig-frontends-native"
5
6# main glibc recipes muck with TARGET_CPPFLAGS to point into 4# main glibc recipes muck with TARGET_CPPFLAGS to point into
7# final target sysroot but we 5# final target sysroot but we
8# are not there when building glibc-initial 6# are not there when building glibc-initial
diff --git a/meta/recipes-core/glibc/glibc-locale_2.22.bb b/meta/recipes-core/glibc/glibc-locale_2.23.bb
index f7702e0358..f7702e0358 100644
--- a/meta/recipes-core/glibc/glibc-locale_2.22.bb
+++ b/meta/recipes-core/glibc/glibc-locale_2.23.bb
diff --git a/meta/recipes-core/glibc/glibc-mtrace_2.22.bb b/meta/recipes-core/glibc/glibc-mtrace_2.23.bb
index 0b69bad46a..0b69bad46a 100644
--- a/meta/recipes-core/glibc/glibc-mtrace_2.22.bb
+++ b/meta/recipes-core/glibc/glibc-mtrace_2.23.bb
diff --git a/meta/recipes-core/glibc/glibc-options.inc b/meta/recipes-core/glibc/glibc-options.inc
deleted file mode 100644
index 9fd27f32f9..0000000000
--- a/meta/recipes-core/glibc/glibc-options.inc
+++ /dev/null
@@ -1,162 +0,0 @@
1def glibc_cfg(feature, tokens, cnf):
2 if type(tokens) == type(""):
3 tokens = [tokens]
4 if feature:
5 cnf.extend([token + '=y' for token in tokens])
6 else:
7 for token in tokens:
8 cnf.extend([token + '=n'])
9 if token == 'OPTION_EGLIBC_NSSWITCH':
10 cnf.extend(["OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG=\"${S}/nss/nsswitch.conf\""])
11 cnf.extend(["OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS=\"${S}/nss/fixed-nsswitch.functions\""])
12
13# Map distro features to glibc options settings
14def features_to_glibc_settings(d):
15 cnf = ([])
16
17 ipv4 = bb.utils.contains('DISTRO_FEATURES', 'ipv4', True, False, d)
18 ipv6 = bb.utils.contains('DISTRO_FEATURES', 'ipv6', True, False, d)
19 libc_backtrace = bb.utils.contains('DISTRO_FEATURES', 'libc-backtrace', True, False, d)
20 libc_big_macros = bb.utils.contains('DISTRO_FEATURES', 'libc-big-macros', True, False, d)
21 libc_bsd = bb.utils.contains('DISTRO_FEATURES', 'libc-bsd', True, False, d)
22 libc_cxx_tests = bb.utils.contains('DISTRO_FEATURES', 'libc-cxx-tests', True, False, d)
23 libc_catgets = bb.utils.contains('DISTRO_FEATURES', 'libc-catgets', True, False, d)
24 libc_charsets = bb.utils.contains('DISTRO_FEATURES', 'libc-charsets', True, False, d)
25 libc_crypt = bb.utils.contains('DISTRO_FEATURES', 'libc-crypt', True, False, d)
26 libc_crypt_ufc = bb.utils.contains('DISTRO_FEATURES', 'libc-crypt-ufc', True, False, d)
27 libc_db_aliases = bb.utils.contains('DISTRO_FEATURES', 'libc-db-aliases', True, False, d)
28 libc_envz = bb.utils.contains('DISTRO_FEATURES', 'libc-envz', True, False, d)
29 libc_fcvt = bb.utils.contains('DISTRO_FEATURES', 'libc-fcvt', True, False, d)
30 libc_fmtmsg = bb.utils.contains('DISTRO_FEATURES', 'libc-fmtmsg', True, False, d)
31 libc_fstab = bb.utils.contains('DISTRO_FEATURES', 'libc-fstab', True, False, d)
32 libc_ftraverse = bb.utils.contains('DISTRO_FEATURES', 'libc-ftraverse', True, False, d)
33 libc_getlogin = bb.utils.contains('DISTRO_FEATURES', 'libc-getlogin', True, False, d)
34 libc_idn = bb.utils.contains('DISTRO_FEATURES', 'libc-idn', True, False, d)
35 libc_inet_anl = bb.utils.contains('DISTRO_FEATURES', 'libc-inet-anl', True, False, d)
36 libc_libm = bb.utils.contains('DISTRO_FEATURES', 'libc-libm', True, False, d)
37 libc_locales = bb.utils.contains('DISTRO_FEATURES', 'libc-locales', True, False, d)
38 libc_locale_code = bb.utils.contains('DISTRO_FEATURES', 'libc-locale-code', True, False, d)
39 libc_memusage = bb.utils.contains('DISTRO_FEATURES', 'libc-memusage', True, False, d)
40 libc_nis = bb.utils.contains('DISTRO_FEATURES', 'libc-nis', True, False, d)
41 libc_nsswitch = bb.utils.contains('DISTRO_FEATURES', 'libc-nsswitch', True, False, d)
42 libc_rcmd = bb.utils.contains('DISTRO_FEATURES', 'libc-rcmd', True, False, d)
43 libc_rtld_debug = bb.utils.contains('DISTRO_FEATURES', 'libc-rtld-debug', True, False, d)
44 libc_spawn = bb.utils.contains('DISTRO_FEATURES', 'libc-spawn', True, False, d)
45 libc_streams = bb.utils.contains('DISTRO_FEATURES', 'libc-streams', True, False, d)
46 libc_sunrpc = bb.utils.contains('DISTRO_FEATURES', 'libc-sunrpc', True, False, d)
47 libc_utmp = bb.utils.contains('DISTRO_FEATURES', 'libc-utmp', True, False, d)
48 libc_utmpx = bb.utils.contains('DISTRO_FEATURES', 'libc-utmpx', True, False, d)
49 libc_wordexp = bb.utils.contains('DISTRO_FEATURES', 'libc-wordexp', True, False, d)
50 libc_posix_clang_wchar = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-clang-wchar', True, False, d)
51 libc_posix_regexp = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-regexp', True, False, d)
52 libc_posix_regexp_glibc = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-regexp-glibc', True, False, d)
53 libc_posix_wchar_io = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-wchar-io', True, False, d)
54
55 # arrange the dependencies among glibc configuable options according to file option-groups.def from glibc source code
56 new_dep = True
57 while new_dep:
58 new_dep = False
59
60 if ipv6 and not ipv4:
61 new_dep = True
62 ipv4 = True
63
64 if ipv4 and not libc_nsswitch:
65 new_dep = True
66 libc_nsswitch = True
67
68 if libc_cxx_tests:
69 if not libc_posix_wchar_io:
70 new_dep = True
71 libc_posix_wchar_io = True
72 if not libc_libm:
73 new_dep = True
74 libc_libm = True
75
76 if libc_catgets and not libc_locale_code:
77 new_dep = True
78 libc_locale_code = True
79
80 if libc_crypt_ufc and not libc_crypt:
81 new_dep = True
82 libc_crypt = True
83
84 if libc_getlogin and not libc_utmp:
85 new_dep = True
86 libc_utmp = True
87
88 if libc_inet_anl and not ipv4:
89 new_dep = True
90 ipv4 = True
91
92 if libc_locale_code and not libc_posix_clang_wchar:
93 new_dep = True
94 libc_posix_clang_wchar = True
95
96 if libc_nis:
97 if not ipv4:
98 new_dep = True
99 ipv4 = True
100 if not libc_sunrpc:
101 new_dep = True
102 libc_sunrpc = True
103
104 if libc_rcmd and not ipv4:
105 new_dep = True
106 ipv4 = True
107
108 if libc_sunrpc and not ipv4:
109 new_dep = True
110 ipv4 = True
111
112 if libc_utmpx and not libc_utmp:
113 new_dep = True
114 libc_utmp = True
115
116 if libc_posix_regexp_glibc and not libc_posix_regexp:
117 new_dep = True
118 libc_posix_regexp = True
119
120 if libc_posix_wchar_io and not libc_posix_clang_wchar:
121 new_dep = True
122 libc_posix_clang_wchar = True
123
124 glibc_cfg(ipv6, 'OPTION_EGLIBC_ADVANCED_INET6', cnf)
125 glibc_cfg(libc_backtrace, 'OPTION_EGLIBC_BACKTRACE', cnf)
126 glibc_cfg(libc_big_macros, 'OPTION_EGLIBC_BIG_MACROS', cnf)
127 glibc_cfg(libc_bsd, 'OPTION_EGLIBC_BSD', cnf)
128 glibc_cfg(libc_cxx_tests, 'OPTION_EGLIBC_CXX_TESTS', cnf)
129 glibc_cfg(libc_catgets, 'OPTION_EGLIBC_CATGETS', cnf)
130 glibc_cfg(libc_charsets, 'OPTION_EGLIBC_CHARSETS', cnf)
131 glibc_cfg(libc_crypt, 'OPTION_EGLIBC_CRYPT', cnf)
132 glibc_cfg(libc_crypt_ufc, 'OPTION_EGLIBC_CRYPT_UFC', cnf)
133 glibc_cfg(libc_db_aliases, 'OPTION_EGLIBC_DB_ALIASES', cnf)
134 glibc_cfg(libc_envz, 'OPTION_EGLIBC_ENVZ', cnf)
135 glibc_cfg(libc_fcvt, 'OPTION_EGLIBC_FCVT', cnf)
136 glibc_cfg(libc_fmtmsg, 'OPTION_EGLIBC_FMTMSG', cnf)
137 glibc_cfg(libc_fstab, 'OPTION_EGLIBC_FSTAB', cnf)
138 glibc_cfg(libc_ftraverse, 'OPTION_EGLIBC_FTRAVERSE', cnf)
139 glibc_cfg(libc_getlogin, 'OPTION_EGLIBC_GETLOGIN', cnf)
140 glibc_cfg(libc_idn, 'OPTION_EGLIBC_IDN', cnf)
141 glibc_cfg(ipv4, 'OPTION_EGLIBC_INET', cnf)
142 glibc_cfg(libc_inet_anl, 'OPTION_EGLIBC_INET_ANL', cnf)
143 glibc_cfg(libc_libm, 'OPTION_EGLIBC_LIBM', cnf)
144 glibc_cfg(libc_locales, 'OPTION_EGLIBC_LOCALES', cnf)
145 glibc_cfg(libc_locale_code, 'OPTION_EGLIBC_LOCALE_CODE', cnf)
146 glibc_cfg(libc_memusage, 'OPTION_EGLIBC_MEMUSAGE', cnf)
147 glibc_cfg(libc_nis, 'OPTION_EGLIBC_NIS', cnf)
148 glibc_cfg(libc_nsswitch, 'OPTION_EGLIBC_NSSWITCH', cnf)
149 glibc_cfg(libc_rcmd, 'OPTION_EGLIBC_RCMD', cnf)
150 glibc_cfg(libc_rtld_debug, 'OPTION_EGLIBC_RTLD_DEBUG', cnf)
151 glibc_cfg(libc_spawn, 'OPTION_EGLIBC_SPAWN', cnf)
152 glibc_cfg(libc_streams, 'OPTION_EGLIBC_STREAMS', cnf)
153 glibc_cfg(libc_sunrpc, 'OPTION_EGLIBC_SUNRPC', cnf)
154 glibc_cfg(libc_utmp, 'OPTION_EGLIBC_UTMP', cnf)
155 glibc_cfg(libc_utmpx, 'OPTION_EGLIBC_UTMPX', cnf)
156 glibc_cfg(libc_wordexp, 'OPTION_EGLIBC_WORDEXP', cnf)
157 glibc_cfg(libc_posix_clang_wchar, 'OPTION_POSIX_C_LANG_WIDE_CHAR', cnf)
158 glibc_cfg(libc_posix_regexp, 'OPTION_POSIX_REGEXP', cnf)
159 glibc_cfg(libc_posix_regexp_glibc, 'OPTION_POSIX_REGEXP_GLIBC', cnf)
160 glibc_cfg(libc_posix_wchar_io, 'OPTION_POSIX_WIDE_CHAR_DEVICE_IO', cnf)
161
162 return "\n".join(cnf)
diff --git a/meta/recipes-core/glibc/glibc-scripts_2.22.bb b/meta/recipes-core/glibc/glibc-scripts_2.23.bb
index 5a89bd8022..5a89bd8022 100644
--- a/meta/recipes-core/glibc/glibc-scripts_2.22.bb
+++ b/meta/recipes-core/glibc/glibc-scripts_2.23.bb
diff --git a/meta/recipes-core/glibc/glibc.inc b/meta/recipes-core/glibc/glibc.inc
index 7c4551a4aa..5711209c71 100644
--- a/meta/recipes-core/glibc/glibc.inc
+++ b/meta/recipes-core/glibc/glibc.inc
@@ -44,12 +44,6 @@ DEPENDS = "virtual/${TARGET_PREFIX}gcc-initial libgcc-initial linux-libc-headers
44PROVIDES = "virtual/libc virtual/${TARGET_PREFIX}libc-for-gcc" 44PROVIDES = "virtual/libc virtual/${TARGET_PREFIX}libc-for-gcc"
45PROVIDES += "virtual/libintl virtual/libiconv" 45PROVIDES += "virtual/libintl virtual/libiconv"
46inherit autotools texinfo distro_features_check systemd 46inherit autotools texinfo distro_features_check systemd
47require glibc-options.inc
48
49# The main purpose of setting this variable is to prevent users from accidently
50# overriding DISTRO_FEATRUES, causing obscure build failures because of lack
51# of libc functions.
52REQUIRED_DISTRO_FEATURES = "${DISTRO_FEATURES_LIBC}"
53 47
54LEAD_SONAME = "libc.so" 48LEAD_SONAME = "libc.so"
55 49
@@ -58,6 +52,7 @@ CACHED_CONFIGUREVARS += " \
58 libc_cv_slibdir=${base_libdir} \ 52 libc_cv_slibdir=${base_libdir} \
59 libc_cv_rootsbindir=${base_sbindir} \ 53 libc_cv_rootsbindir=${base_sbindir} \
60 libc_cv_localedir=${localedir} \ 54 libc_cv_localedir=${localedir} \
55 libc_cv_ssp_strong=no \
61 libc_cv_ssp=no \ 56 libc_cv_ssp=no \
62" 57"
63 58
@@ -82,18 +77,8 @@ PARALLEL_MAKE = ""
82# ensure make uses /bin/bash 77# ensure make uses /bin/bash
83EXTRA_OEMAKE += "SHELL=/bin/bash" 78EXTRA_OEMAKE += "SHELL=/bin/bash"
84 79
85OE_FEATURES = "${@features_to_glibc_settings(d)}"
86do_configure_prepend() { 80do_configure_prepend() {
87 sed -e "s#@BASH@#/bin/sh#" -i ${S}/elf/ldd.bash.in 81 sed -e "s#@BASH@#/bin/sh#" -i ${S}/elf/ldd.bash.in
88 echo '${OE_FEATURES}' > ${B}/option-groups.config
89}
90
91do_configure_append() {
92 yes '' | oe_runmake config
93
94 # Remove quotation marks from OPTION_EGLIBC_NSSWITCH_FIXED_*. This will
95 # avoid install error.
96 sed -i 's/^OPTION_EGLIBC_NSSWITCH_FIXED_\(.*\)="\(.*\)"$/OPTION_EGLIBC_NSSWITCH_FIXED_\1=\2/' option-groups.config
97} 82}
98 83
99GLIBC_ADDONS ?= "nptl,libidn" 84GLIBC_ADDONS ?= "nptl,libidn"
diff --git a/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch b/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch
index 3d66348133..97c280059f 100644
--- a/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch
+++ b/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch
@@ -1,7 +1,7 @@
1From 0876fea1b5b26da84f298714a2e23ba696607dba Mon Sep 17 00:00:00 2001 1From 66d04e2cd8badb0984050e4e9f2732f47151fbbf Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 01:48:24 +0000 3Date: Wed, 18 Mar 2015 01:48:24 +0000
4Subject: [PATCH 01/27] nativesdk-glibc: Look for host system ld.so.cache as 4Subject: [PATCH 01/24] nativesdk-glibc: Look for host system ld.so.cache as
5 well 5 well
6 6
7Upstream-Status: Inappropriate [embedded specific] 7Upstream-Status: Inappropriate [embedded specific]
@@ -27,18 +27,17 @@ RP 14/10/2010
27 27
28Signed-off-by: Khem Raj <raj.khem@gmail.com> 28Signed-off-by: Khem Raj <raj.khem@gmail.com>
29--- 29---
30 elf/dl-load.c | 17 ++++++++--------- 30 elf/dl-load.c | 16 ++++++++--------
31 1 file changed, 8 insertions(+), 9 deletions(-) 31 1 file changed, 8 insertions(+), 8 deletions(-)
32 32
33diff --git a/elf/dl-load.c b/elf/dl-load.c 33diff --git a/elf/dl-load.c b/elf/dl-load.c
34index 0c052e4..f45085a 100644 34index 6fb615e..ee3d1e6 100644
35--- a/elf/dl-load.c 35--- a/elf/dl-load.c
36+++ b/elf/dl-load.c 36+++ b/elf/dl-load.c
37@@ -2040,7 +2040,14 @@ _dl_map_object (struct link_map *loader, const char *name, 37@@ -2094,6 +2094,14 @@ _dl_map_object (struct link_map *loader, const char *name,
38 fd = open_path (name, namelen, mode, 38 }
39 &loader->l_runpath_dirs, &realname, &fb, loader, 39 }
40 LA_SER_RUNPATH, &found_other_class); 40
41-
42+ /* try the default path. */ 41+ /* try the default path. */
43+ if (fd == -1 42+ if (fd == -1
44+ && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL 43+ && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
@@ -50,7 +49,7 @@ index 0c052e4..f45085a 100644
50 #ifdef USE_LDCONFIG 49 #ifdef USE_LDCONFIG
51 if (fd == -1 50 if (fd == -1
52 && (__glibc_likely ((mode & __RTLD_SECURE) == 0) 51 && (__glibc_likely ((mode & __RTLD_SECURE) == 0)
53@@ -2099,14 +2106,6 @@ _dl_map_object (struct link_map *loader, const char *name, 52@@ -2152,14 +2160,6 @@ _dl_map_object (struct link_map *loader, const char *name,
54 } 53 }
55 #endif 54 #endif
56 55
@@ -66,5 +65,5 @@ index 0c052e4..f45085a 100644
66 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) 65 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
67 _dl_debug_printf ("\n"); 66 _dl_debug_printf ("\n");
68-- 67--
692.1.4 682.6.4
70 69
diff --git a/meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch b/meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch
index b568fc6bdc..473b89449d 100644
--- a/meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch
+++ b/meta/recipes-core/glibc/glibc/0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch
@@ -1,7 +1,7 @@
1From 086b65d9aacffc47fcd8df68818a476a5ae76fa1 Mon Sep 17 00:00:00 2001 1From 179dc5f1e13c3ff96d5f21a2a78c089cf120ceb8 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 01:50:00 +0000 3Date: Wed, 18 Mar 2015 01:50:00 +0000
4Subject: [PATCH 02/27] nativesdk-glibc: Fix buffer overrun with a relocated 4Subject: [PATCH 02/24] nativesdk-glibc: Fix buffer overrun with a relocated
5 SDK 5 SDK
6 6
7When ld-linux-*.so.2 is relocated to a path that is longer than the 7When 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>
22 1 file changed, 12 insertions(+) 22 1 file changed, 12 insertions(+)
23 23
24diff --git a/elf/dl-load.c b/elf/dl-load.c 24diff --git a/elf/dl-load.c b/elf/dl-load.c
25index f45085a..f1eb5ed 100644 25index ee3d1e6..c4a42e9 100644
26--- a/elf/dl-load.c 26--- a/elf/dl-load.c
27+++ b/elf/dl-load.c 27+++ b/elf/dl-load.c
28@@ -1765,7 +1765,19 @@ open_path (const char *name, size_t namelen, int mode, 28@@ -1793,7 +1793,19 @@ open_path (const char *name, size_t namelen, int mode,
29 given on the command line when rtld is run directly. */ 29 given on the command line when rtld is run directly. */
30 return -1; 30 return -1;
31 31
@@ -46,5 +46,5 @@ index f45085a..f1eb5ed 100644
46 { 46 {
47 struct r_search_path_elem *this_dir = *dirs; 47 struct r_search_path_elem *this_dir = *dirs;
48-- 48--
492.1.4 492.6.4
50 50
diff --git a/meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch b/meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch
index a681a64e85..dde94b450c 100644
--- a/meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch
+++ b/meta/recipes-core/glibc/glibc/0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch
@@ -1,7 +1,7 @@
1From fd595a5ec885bcb4c14417daa21c2e61c5b72e42 Mon Sep 17 00:00:00 2001 1From e76048898ae9aa49dc70d6f9b1bbc22082e61fe3 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 01:51:38 +0000 3Date: Wed, 18 Mar 2015 01:51:38 +0000
4Subject: [PATCH 03/27] nativesdk-glibc: Raise the size of arrays containing dl 4Subject: [PATCH 03/24] nativesdk-glibc: Raise the size of arrays containing dl
5 paths 5 paths
6 6
7This patch puts the dynamic loader path in the binaries, SYSTEM_DIRS strings 7This patch puts the dynamic loader path in the binaries, SYSTEM_DIRS strings
@@ -40,10 +40,10 @@ index dec49bc..862f1d8 100644
40 internal_function 40 internal_function
41 _dl_cache_libcmp (const char *p1, const char *p2) 41 _dl_cache_libcmp (const char *p1, const char *p2)
42diff --git a/elf/dl-load.c b/elf/dl-load.c 42diff --git a/elf/dl-load.c b/elf/dl-load.c
43index f1eb5ed..f664f50 100644 43index c4a42e9..acf6c03 100644
44--- a/elf/dl-load.c 44--- a/elf/dl-load.c
45+++ b/elf/dl-load.c 45+++ b/elf/dl-load.c
46@@ -104,8 +104,8 @@ static size_t max_capstrlen attribute_relro; 46@@ -106,8 +106,8 @@ static size_t max_capstrlen attribute_relro;
47 /* Get the generated information about the trusted directories. */ 47 /* Get the generated information about the trusted directories. */
48 #include "trusted-dirs.h" 48 #include "trusted-dirs.h"
49 49
@@ -80,7 +80,7 @@ index f54ec22..0e78a83 100644
80 a platform. */ 80 a platform. */
81 static int 81 static int
82diff --git a/elf/rtld.c b/elf/rtld.c 82diff --git a/elf/rtld.c b/elf/rtld.c
83index 69873c2..6d3add7 100644 83index 52160df..80f0582 100644
84--- a/elf/rtld.c 84--- a/elf/rtld.c
85+++ b/elf/rtld.c 85+++ b/elf/rtld.c
86@@ -99,6 +99,7 @@ uintptr_t __pointer_chk_guard_local 86@@ -99,6 +99,7 @@ uintptr_t __pointer_chk_guard_local
@@ -91,7 +91,7 @@ index 69873c2..6d3add7 100644
91 91
92 /* List of auditing DSOs. */ 92 /* List of auditing DSOs. */
93 static struct audit_list 93 static struct audit_list
94@@ -877,12 +878,12 @@ of this helper program; chances are you did not intend to run this program.\n\ 94@@ -873,12 +874,12 @@ of this helper program; chances are you did not intend to run this program.\n\
95 --list list all dependencies and how they are resolved\n\ 95 --list list all dependencies and how they are resolved\n\
96 --verify verify that given object really is a dynamically linked\n\ 96 --verify verify that given object really is a dynamically linked\n\
97 object we can handle\n\ 97 object we can handle\n\
@@ -107,7 +107,7 @@ index 69873c2..6d3add7 100644
107 ++_dl_skip_args; 107 ++_dl_skip_args;
108 --_dl_argc; 108 --_dl_argc;
109diff --git a/sysdeps/generic/dl-cache.h b/sysdeps/generic/dl-cache.h 109diff --git a/sysdeps/generic/dl-cache.h b/sysdeps/generic/dl-cache.h
110index 4b49869..1800d03 100644 110index 70d4aeb..5c726d0 100644
111--- a/sysdeps/generic/dl-cache.h 111--- a/sysdeps/generic/dl-cache.h
112+++ b/sysdeps/generic/dl-cache.h 112+++ b/sysdeps/generic/dl-cache.h
113@@ -27,10 +27,6 @@ 113@@ -27,10 +27,6 @@
@@ -122,5 +122,5 @@ index 4b49869..1800d03 100644
122 # define add_system_dir(dir) add_dir (dir) 122 # define add_system_dir(dir) add_dir (dir)
123 #endif 123 #endif
124-- 124--
1252.1.4 1252.6.4
126 126
diff --git a/meta/recipes-core/glibc/glibc/0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch b/meta/recipes-core/glibc/glibc/0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch
deleted file mode 100644
index 748750304f..0000000000
--- a/meta/recipes-core/glibc/glibc/0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch
+++ /dev/null
@@ -1,34 +0,0 @@
1From 2560b564b5674bf2990e5607f6342c1647a5dc4f Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Sun, 8 Mar 2015 04:01:01 +0000
4Subject: [PATCH 04/27] Backport
5 https://sourceware.org/ml/libc-ports/2007-12/msg00000.html
6
7Upstream-Status: Pending
8
92007-12-03 Kristian Van Der Vliet <vanders@liqwyd.com>
10
11 * bits/stdio-lock.h (_IO_acquire_lock_clear_flags2): Define
12
13Signed-off-by: Kristian Van Der Vliet <vanders@liqwyd.com>
14Signed-off-by: Khem Raj <raj.khem@gmail.com>
15---
16 bits/stdio-lock.h | 2 ++
17 1 file changed, 2 insertions(+)
18
19diff --git a/bits/stdio-lock.h b/bits/stdio-lock.h
20index 0c5bb65..66304a6 100644
21--- a/bits/stdio-lock.h
22+++ b/bits/stdio-lock.h
23@@ -49,6 +49,8 @@ __libc_lock_define_recursive (typedef, _IO_lock_t)
24 _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, (_fp)); \
25 _IO_flockfile (_fp)
26
27+# define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp)
28+
29 # define _IO_release_lock(_fp) \
30 _IO_funlockfile (_fp); \
31 _IO_cleanup_region_end (0)
32--
332.1.4
34
diff --git a/meta/recipes-core/glibc/glibc/0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch b/meta/recipes-core/glibc/glibc/0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch
new file mode 100644
index 0000000000..21f04a1321
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch
@@ -0,0 +1,32 @@
1From 2e1638115f0f924ee8235eee9265047054c15cfd Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Thu, 31 Dec 2015 14:35:35 -0800
4Subject: [PATCH 04/24] nativesdk-glibc: Allow 64 bit atomics for x86
5
6The fix consist of allowing 64bit atomic ops for x86.
7This should be safe for i586 and newer CPUs.
8It also makes the synchronization more efficient.
9
10Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
11Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
12Signed-off-by: Khem Raj <raj.khem@gmail.com>
13---
14 sysdeps/i386/atomic-machine.h | 2 +-
15 1 file changed, 1 insertion(+), 1 deletion(-)
16
17diff --git a/sysdeps/i386/atomic-machine.h b/sysdeps/i386/atomic-machine.h
18index 59f3d34..6f6b7ff 100644
19--- a/sysdeps/i386/atomic-machine.h
20+++ b/sysdeps/i386/atomic-machine.h
21@@ -54,7 +54,7 @@ typedef uintmax_t uatomic_max_t;
22 # endif
23 #endif
24
25-#define __HAVE_64B_ATOMICS 0
26+#define __HAVE_64B_ATOMICS 1
27 #define USE_ATOMIC_COMPILER_BUILTINS 0
28
29
30--
312.6.4
32
diff --git a/meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch b/meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch
index 8d3f859555..ba8c92e112 100644
--- a/meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch
+++ b/meta/recipes-core/glibc/glibc/0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch
@@ -1,7 +1,7 @@
1From aa0cd82892f32e58602143c697ef0524696a6428 Mon Sep 17 00:00:00 2001 1From 7ff57edfe24b4243373fcb896ee0b613938c1ec9 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:01:50 +0000 3Date: Wed, 18 Mar 2015 00:01:50 +0000
4Subject: [PATCH 05/27] fsl e500/e5500/e6500/603e fsqrt implementation 4Subject: [PATCH 05/24] fsl e500/e5500/e6500/603e fsqrt implementation
5 5
6Upstream-Status: Pending 6Upstream-Status: Pending
7Signed-off-by: Edmar Wienskoski <edmar@freescale.com> 7Signed-off-by: Edmar Wienskoski <edmar@freescale.com>
@@ -1580,5 +1580,5 @@ index 0000000..04ff8cc
1580@@ -0,0 +1 @@ 1580@@ -0,0 +1 @@
1581+powerpc/powerpc64/e6500/fpu 1581+powerpc/powerpc64/e6500/fpu
1582-- 1582--
15832.1.4 15832.6.4
1584 1584
diff --git a/meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch b/meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch
index 65c227ff20..086a73dd26 100644
--- a/meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch
+++ b/meta/recipes-core/glibc/glibc/0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch
@@ -1,7 +1,7 @@
1From 5ec1bc5172851278231ce940b68b35ce9cbf8500 Mon Sep 17 00:00:00 2001 1From 61129ef3ee735b300604f75d50e01cb29f4387f4 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:11:22 +0000 3Date: Wed, 18 Mar 2015 00:11:22 +0000
4Subject: [PATCH 06/27] readlib: Add OECORE_KNOWN_INTERPRETER_NAMES to known 4Subject: [PATCH 06/24] readlib: Add OECORE_KNOWN_INTERPRETER_NAMES to known
5 names 5 names
6 6
7This bolts in a hook for OE to pass its own version of interpreter 7This bolts in a hook for OE to pass its own version of interpreter
@@ -29,5 +29,5 @@ index 7fd5b8a..2f5da9f 100644
29 29
30 static struct known_names known_libs[] = 30 static struct known_names known_libs[] =
31-- 31--
322.1.4 322.6.4
33 33
diff --git a/meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch b/meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch
index aec8fbeb9a..952784b1cc 100644
--- a/meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch
+++ b/meta/recipes-core/glibc/glibc/0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch
@@ -1,7 +1,7 @@
1From ea98b1a12b5f779fd79478ff930a79ef60387851 Mon Sep 17 00:00:00 2001 1From f936548decac99501f9a4c522a3211d16542fa49 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:15:07 +0000 3Date: Wed, 18 Mar 2015 00:15:07 +0000
4Subject: [PATCH 07/27] ppc/sqrt: Fix undefined reference to `__sqrt_finite' 4Subject: [PATCH 07/24] ppc/sqrt: Fix undefined reference to `__sqrt_finite'
5 5
6on ppc fixes the errors like below 6on ppc fixes the errors like below
7| ./.libs/libpulsecore-1.1.so: undefined reference to `__sqrt_finite' 7| ./.libs/libpulsecore-1.1.so: undefined reference to `__sqrt_finite'
@@ -204,5 +204,5 @@ index 26fa067..9d17512 100644
204 } 204 }
205+strong_alias (__ieee754_sqrtf, __sqrtf_finite) 205+strong_alias (__ieee754_sqrtf, __sqrtf_finite)
206-- 206--
2072.1.4 2072.6.4
208 208
diff --git a/meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch b/meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
index b3fa931c6c..8d513ab42a 100644
--- a/meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
+++ b/meta/recipes-core/glibc/glibc/0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
@@ -1,7 +1,7 @@
1From 2456ea44aeeedae87edb522f77a7969d636399b0 Mon Sep 17 00:00:00 2001 1From d02704895fdce917e337619a4414042f63edd88b Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:16:38 +0000 3Date: Wed, 18 Mar 2015 00:16:38 +0000
4Subject: [PATCH 08/27] __ieee754_sqrt{,f} are now inline functions and call 4Subject: [PATCH 08/24] __ieee754_sqrt{,f} are now inline functions and call
5 out __slow versions 5 out __slow versions
6 6
7Upstream-Status: Pending 7Upstream-Status: Pending
@@ -383,5 +383,5 @@ index 9d17512..10de1f0 100644
383+ 383+
384 strong_alias (__ieee754_sqrtf, __sqrtf_finite) 384 strong_alias (__ieee754_sqrtf, __sqrtf_finite)
385-- 385--
3862.1.4 3862.6.4
387 387
diff --git a/meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch b/meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch
index 1f5475912c..12f24fb685 100644
--- a/meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch
+++ b/meta/recipes-core/glibc/glibc/0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch
@@ -1,7 +1,7 @@
1From acf7a028817e71eb99d785037659abd4d120ffe2 Mon Sep 17 00:00:00 2001 1From 502f061d846e58aac7aca67e4e0d6ba9e0763b17 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:20:09 +0000 3Date: Wed, 18 Mar 2015 00:20:09 +0000
4Subject: [PATCH 09/27] Quote from bug 1443 which explains what the patch does 4Subject: [PATCH 09/24] Quote from bug 1443 which explains what the patch does
5 : 5 :
6 6
7 We build some random program and link it with -lust. When we run it, 7 We build some random program and link it with -lust. When we run it,
@@ -58,5 +58,5 @@ index 6fb20bd..8805537 100644
58 58
59 case R_ARM_TLS_TPOFF32: 59 case R_ARM_TLS_TPOFF32:
60-- 60--
612.1.4 612.6.4
62 62
diff --git a/meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch b/meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch
index df3c1ef21f..77bd7d1324 100644
--- a/meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch
+++ b/meta/recipes-core/glibc/glibc/0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch
@@ -1,7 +1,7 @@
1From 017322ee28c1579ce6c81904842aaada9c82403c Mon Sep 17 00:00:00 2001 1From 69a3e30b49d28a7386d18725528652931510cbfc Mon Sep 17 00:00:00 2001
2From: Ting Liu <b28495@freescale.com> 2From: Ting Liu <b28495@freescale.com>
3Date: Wed, 19 Dec 2012 04:39:57 -0600 3Date: Wed, 19 Dec 2012 04:39:57 -0600
4Subject: [PATCH 10/27] eglibc: run libm-err-tab.pl with specific dirs in ${S} 4Subject: [PATCH 10/24] eglibc: run libm-err-tab.pl with specific dirs in ${S}
5 5
6libm-err-tab.pl will parse all the files named "libm-test-ulps" 6libm-err-tab.pl will parse all the files named "libm-test-ulps"
7in the given dir recursively. To avoid parsing the one in 7in the given dir recursively. To avoid parsing the one in
@@ -18,7 +18,7 @@ Signed-off-by: Ting Liu <b28495@freescale.com>
18 1 file changed, 2 insertions(+), 1 deletion(-) 18 1 file changed, 2 insertions(+), 1 deletion(-)
19 19
20diff --git a/manual/Makefile b/manual/Makefile 20diff --git a/manual/Makefile b/manual/Makefile
21index 5382208..6b701b0 100644 21index cdb6763..0b32a0a 100644
22--- a/manual/Makefile 22--- a/manual/Makefile
23+++ b/manual/Makefile 23+++ b/manual/Makefile
24@@ -105,7 +105,8 @@ $(objpfx)libm-err.texi: $(objpfx)stamp-libm-err 24@@ -105,7 +105,8 @@ $(objpfx)libm-err.texi: $(objpfx)stamp-libm-err
@@ -32,5 +32,5 @@ index 5382208..6b701b0 100644
32 touch $@ 32 touch $@
33 33
34-- 34--
352.1.4 352.6.4
36 36
diff --git a/meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch b/meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
index 07a112b218..251e5f5af3 100644
--- a/meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
+++ b/meta/recipes-core/glibc/glibc/0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch
@@ -1,7 +1,7 @@
1From 1be45f870ebbb0259bea5250a6d2c2fbcb33409d Mon Sep 17 00:00:00 2001 1From 4cf52971a841304aec30b2e975f81d7ad9d42ef0 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:24:46 +0000 3Date: Wed, 18 Mar 2015 00:24:46 +0000
4Subject: [PATCH 11/27] __ieee754_sqrt{,f} are now inline functions and call 4Subject: [PATCH 11/24] __ieee754_sqrt{,f} are now inline functions and call
5 out __slow versions 5 out __slow versions
6 6
7Upstream-Status: Pending 7Upstream-Status: Pending
@@ -57,5 +57,5 @@ index 8126535..10de1f0 100644
57 #endif 57 #endif
58 { 58 {
59-- 59--
602.1.4 602.6.4
61 61
diff --git a/meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch b/meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch
index 267791393e..3208a0c89b 100644
--- a/meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch
+++ b/meta/recipes-core/glibc/glibc/0012-Make-ld-version-output-matching-grok-gold-s-output.patch
@@ -1,7 +1,7 @@
1From 49471ab1f90e392da9520eea831ce8731be9fc8b Mon Sep 17 00:00:00 2001 1From b356816d6e005ecda7adbed9627a4315ad39de39 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:25:45 +0000 3Date: Wed, 18 Mar 2015 00:25:45 +0000
4Subject: [PATCH 12/27] Make ld --version output matching grok gold's output 4Subject: [PATCH 12/24] Make ld --version output matching grok gold's output
5 5
6adapted from from upstream branch roland/gold-vs-libc 6adapted from from upstream branch roland/gold-vs-libc
7 7
@@ -14,10 +14,10 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
14 2 files changed, 2 insertions(+), 2 deletions(-) 14 2 files changed, 2 insertions(+), 2 deletions(-)
15 15
16diff --git a/configure b/configure 16diff --git a/configure b/configure
17index 45cc7cb..7d7299a 100755 17index aa05d49..6dabd11 100755
18--- a/configure 18--- a/configure
19+++ b/configure 19+++ b/configure
20@@ -4709,7 +4709,7 @@ else 20@@ -4486,7 +4486,7 @@ else
21 # Found it, now check the version. 21 # Found it, now check the version.
22 { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5 22 { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5
23 $as_echo_n "checking version of $LD... " >&6; } 23 $as_echo_n "checking version of $LD... " >&6; }
@@ -27,10 +27,10 @@ index 45cc7cb..7d7299a 100755
27 '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; 27 '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
28 2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*) 28 2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*)
29diff --git a/configure.ac b/configure.ac 29diff --git a/configure.ac b/configure.ac
30index 7e9383a..a467a69 100644 30index ee7a3f1..b4b95b9 100644
31--- a/configure.ac 31--- a/configure.ac
32+++ b/configure.ac 32+++ b/configure.ac
33@@ -941,7 +941,7 @@ AC_CHECK_PROG_VER(AS, $AS, --version, 33@@ -948,7 +948,7 @@ AC_CHECK_PROG_VER(AS, $AS, --version,
34 [2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], 34 [2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*],
35 AS=: critic_missing="$critic_missing as") 35 AS=: critic_missing="$critic_missing as")
36 AC_CHECK_PROG_VER(LD, $LD, --version, 36 AC_CHECK_PROG_VER(LD, $LD, --version,
@@ -40,5 +40,5 @@ index 7e9383a..a467a69 100644
40 LD=: critic_missing="$critic_missing ld") 40 LD=: critic_missing="$critic_missing ld")
41 41
42-- 42--
432.1.4 432.6.4
44 44
diff --git a/meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch b/meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch
index c1fda9d433..82fa100442 100644
--- a/meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch
+++ b/meta/recipes-core/glibc/glibc/0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch
@@ -1,7 +1,7 @@
1From b55e49b199c46a278ab66b6b1e3eab483b913197 Mon Sep 17 00:00:00 2001 1From 10003d48f83f7a4f7fa562ed89af904a544b6323 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:27:10 +0000 3Date: Wed, 18 Mar 2015 00:27:10 +0000
4Subject: [PATCH 13/27] sysdeps/gnu/configure.ac: handle correctly 4Subject: [PATCH 13/24] sysdeps/gnu/configure.ac: handle correctly
5 $libc_cv_rootsbindir 5 $libc_cv_rootsbindir
6 6
7Upstream-Status:Pending 7Upstream-Status:Pending
@@ -14,7 +14,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
14 2 files changed, 2 insertions(+), 2 deletions(-) 14 2 files changed, 2 insertions(+), 2 deletions(-)
15 15
16diff --git a/sysdeps/gnu/configure b/sysdeps/gnu/configure 16diff --git a/sysdeps/gnu/configure b/sysdeps/gnu/configure
17index 9239297..c5ed3ca 100644 17index 71243ad..f578187 100644
18--- a/sysdeps/gnu/configure 18--- a/sysdeps/gnu/configure
19+++ b/sysdeps/gnu/configure 19+++ b/sysdeps/gnu/configure
20@@ -32,6 +32,6 @@ case "$prefix" in 20@@ -32,6 +32,6 @@ case "$prefix" in
@@ -38,5 +38,5 @@ index 634fe4d..3db1697 100644
38 ;; 38 ;;
39 esac 39 esac
40-- 40--
412.1.4 412.6.4
42 42
diff --git a/meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch b/meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch
index 0ba5d2fbad..ea3e1670f8 100644
--- a/meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch
+++ b/meta/recipes-core/glibc/glibc/0014-Add-unused-attribute.patch
@@ -1,7 +1,7 @@
1From 0229d6c9c0e7721773118d5ae1d172c269bc9826 Mon Sep 17 00:00:00 2001 1From cafa8a7ef830e02cdbf928471e06d11054946940 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:28:41 +0000 3Date: Wed, 18 Mar 2015 00:28:41 +0000
4Subject: [PATCH 14/27] Add unused attribute 4Subject: [PATCH 14/24] Add unused attribute
5 5
6Helps in avoiding gcc warning when header is is included in 6Helps in avoiding gcc warning when header is is included in
7a source file which does not use both functions 7a source file which does not use both functions
@@ -30,5 +30,5 @@ index 80290bc..7890a8e 100644
30 { 30 {
31 int slash_count = 0; 31 int slash_count = 0;
32-- 32--
332.1.4 332.6.4
34 34
diff --git a/meta/recipes-core/glibc/glibc/0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch b/meta/recipes-core/glibc/glibc/0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch
deleted file mode 100644
index 4b261ca1ef..0000000000
--- a/meta/recipes-core/glibc/glibc/0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch
+++ /dev/null
@@ -1,32 +0,0 @@
1From f058c884dd26d10c94550ca5252ed6576614d659 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Thu, 19 Feb 2015 03:23:45 +0000
4Subject: [PATCH 15/27] When disabling SSE also make sure that fpmath is not
5 set to use SSE as well
6
7This fixes errors when we inject sse options through CFLAGS and now
8that we have -Werror turned on by default this warning turns to become
9error on x86
10
11Signed-off-by: Khem Raj <raj.khem@gmail.com>
12
13Upstream-Status: Pending
14---
15 sysdeps/x86/Makefile | 2 +-
16 1 file changed, 1 insertion(+), 1 deletion(-)
17
18diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
19index 19f5eca..827ea71 100644
20--- a/sysdeps/x86/Makefile
21+++ b/sysdeps/x86/Makefile
22@@ -1,6 +1,6 @@
23 ifeq ($(subdir),elf)
24 CFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\
25- -mno-sse -mno-mmx)
26+ -mno-sse -mno-mmx -mfpmath=387)
27
28 tests-special += $(objpfx)tst-ld-sse-use.out
29 $(objpfx)tst-ld-sse-use.out: ../sysdeps/x86/tst-ld-sse-use.sh $(objpfx)ld.so
30--
312.1.4
32
diff --git a/meta/recipes-core/glibc/glibc/0016-yes-within-the-path-sets-wrong-config-variables.patch b/meta/recipes-core/glibc/glibc/0015-yes-within-the-path-sets-wrong-config-variables.patch
index 089e8b1b0b..90e12b8835 100644
--- a/meta/recipes-core/glibc/glibc/0016-yes-within-the-path-sets-wrong-config-variables.patch
+++ b/meta/recipes-core/glibc/glibc/0015-yes-within-the-path-sets-wrong-config-variables.patch
@@ -1,7 +1,7 @@
1From 70199fe59c38b621ab4121d7a55719b2b29b36de Mon Sep 17 00:00:00 2001 1From 4d6bead19874e519752ceeb2a15897ff2ffbe5e8 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:31:06 +0000 3Date: Wed, 18 Mar 2015 00:31:06 +0000
4Subject: [PATCH 16/27] 'yes' within the path sets wrong config variables 4Subject: [PATCH 15/24] 'yes' within the path sets wrong config variables
5 5
6It seems that the 'AC_EGREP_CPP(yes...' example is quite popular 6It seems that the 'AC_EGREP_CPP(yes...' example is quite popular
7but being such a short word to grep it is likely to produce 7but being such a short word to grep it is likely to produce
@@ -63,7 +63,7 @@ index 7851dd4..6e92381 100644
63 ], libc_cv_aarch64_be=yes, libc_cv_aarch64_be=no)]) 63 ], libc_cv_aarch64_be=yes, libc_cv_aarch64_be=no)])
64 if test $libc_cv_aarch64_be = yes; then 64 if test $libc_cv_aarch64_be = yes; then
65diff --git a/sysdeps/arm/configure b/sysdeps/arm/configure 65diff --git a/sysdeps/arm/configure b/sysdeps/arm/configure
66index 158116b..5eaf54e 100644 66index 431e843..e152461 100644
67--- a/sysdeps/arm/configure 67--- a/sysdeps/arm/configure
68+++ b/sysdeps/arm/configure 68+++ b/sysdeps/arm/configure
69@@ -151,12 +151,12 @@ else 69@@ -151,12 +151,12 @@ else
@@ -82,7 +82,7 @@ index 158116b..5eaf54e 100644
82 else 82 else
83 libc_cv_arm_pcs_vfp=no 83 libc_cv_arm_pcs_vfp=no
84diff --git a/sysdeps/arm/configure.ac b/sysdeps/arm/configure.ac 84diff --git a/sysdeps/arm/configure.ac b/sysdeps/arm/configure.ac
85index 859c92a..2f4a6e2 100644 85index 90cdd69..05a262b 100644
86--- a/sysdeps/arm/configure.ac 86--- a/sysdeps/arm/configure.ac
87+++ b/sysdeps/arm/configure.ac 87+++ b/sysdeps/arm/configure.ac
88@@ -15,8 +15,8 @@ AC_DEFINE(PI_STATIC_AND_HIDDEN) 88@@ -15,8 +15,8 @@ AC_DEFINE(PI_STATIC_AND_HIDDEN)
@@ -165,10 +165,10 @@ index f05f438..dc86399 100644
165 ], libc_cv_nios2_be=yes, libc_cv_nios2_be=no)]) 165 ], libc_cv_nios2_be=yes, libc_cv_nios2_be=no)])
166 if test $libc_cv_nios2_be = yes; then 166 if test $libc_cv_nios2_be = yes; then
167diff --git a/sysdeps/unix/sysv/linux/mips/configure b/sysdeps/unix/sysv/linux/mips/configure 167diff --git a/sysdeps/unix/sysv/linux/mips/configure b/sysdeps/unix/sysv/linux/mips/configure
168index 83f8b13..2b6cbee 100644 168index dee56aa..f2049ed 100644
169--- a/sysdeps/unix/sysv/linux/mips/configure 169--- a/sysdeps/unix/sysv/linux/mips/configure
170+++ b/sysdeps/unix/sysv/linux/mips/configure 170+++ b/sysdeps/unix/sysv/linux/mips/configure
171@@ -387,11 +387,11 @@ else 171@@ -414,11 +414,11 @@ else
172 /* end confdefs.h. */ 172 /* end confdefs.h. */
173 dnl 173 dnl
174 #ifdef __mips_nan2008 174 #ifdef __mips_nan2008
@@ -183,10 +183,10 @@ index 83f8b13..2b6cbee 100644
183 else 183 else
184 libc_cv_mips_nan2008=no 184 libc_cv_mips_nan2008=no
185diff --git a/sysdeps/unix/sysv/linux/mips/configure.ac b/sysdeps/unix/sysv/linux/mips/configure.ac 185diff --git a/sysdeps/unix/sysv/linux/mips/configure.ac b/sysdeps/unix/sysv/linux/mips/configure.ac
186index 5039ec9..1035f76 100644 186index 45147c5..4224af1 100644
187--- a/sysdeps/unix/sysv/linux/mips/configure.ac 187--- a/sysdeps/unix/sysv/linux/mips/configure.ac
188+++ b/sysdeps/unix/sysv/linux/mips/configure.ac 188+++ b/sysdeps/unix/sysv/linux/mips/configure.ac
189@@ -98,9 +98,9 @@ AC_COMPILE_IFELSE( 189@@ -105,9 +105,9 @@ AC_COMPILE_IFELSE(
190 LIBC_CONFIG_VAR([mips-mode-switch],[${libc_mips_mode_switch}]) 190 LIBC_CONFIG_VAR([mips-mode-switch],[${libc_mips_mode_switch}])
191 191
192 AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding], 192 AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding],
@@ -199,7 +199,7 @@ index 5039ec9..1035f76 100644
199 199
200 libc_mips_nan= 200 libc_mips_nan=
201diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure b/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure 201diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure b/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure
202index 70bb18a..ffd9e3e 100644 202index af06970..27b8c1b 100644
203--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure 203--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure
204+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure 204+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure
205@@ -155,12 +155,12 @@ else 205@@ -155,12 +155,12 @@ else
@@ -259,5 +259,5 @@ index 0822915..9a32fdd 100644
259 ], libc_cv_ppc64_def_call_elf=yes, libc_cv_ppc64_def_call_elf=no)]) 259 ], libc_cv_ppc64_def_call_elf=yes, libc_cv_ppc64_def_call_elf=no)])
260 if test $libc_cv_ppc64_def_call_elf = no; then 260 if test $libc_cv_ppc64_def_call_elf = no; then
261-- 261--
2622.1.4 2622.6.4
263 263
diff --git a/meta/recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch b/meta/recipes-core/glibc/glibc/0016-timezone-re-written-tzselect-as-posix-sh.patch
index 0ce823087d..e51b611f37 100644
--- a/meta/recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch
+++ b/meta/recipes-core/glibc/glibc/0016-timezone-re-written-tzselect-as-posix-sh.patch
@@ -1,7 +1,7 @@
1From c90306107fbbe2979012917e87747ce78c82ab88 Mon Sep 17 00:00:00 2001 1From 3e8586eb3509e2f0d6dfb74be8f89a30b06b56e9 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:33:03 +0000 3Date: Wed, 18 Mar 2015 00:33:03 +0000
4Subject: [PATCH 17/27] timezone: re-written tzselect as posix sh 4Subject: [PATCH 16/24] timezone: re-written tzselect as posix sh
5 5
6To avoid the bash dependency. 6To avoid the bash dependency.
7 7
@@ -15,10 +15,10 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
15 2 files changed, 2 insertions(+), 2 deletions(-) 15 2 files changed, 2 insertions(+), 2 deletions(-)
16 16
17diff --git a/timezone/Makefile b/timezone/Makefile 17diff --git a/timezone/Makefile b/timezone/Makefile
18index 24c93c6..886b06e 100644 18index 99566cb..b6e757e 100644
19--- a/timezone/Makefile 19--- a/timezone/Makefile
20+++ b/timezone/Makefile 20+++ b/timezone/Makefile
21@@ -126,7 +126,7 @@ $(testdata)/XT%: testdata/XT% 21@@ -122,7 +122,7 @@ $(testdata)/XT%: testdata/XT%
22 cp $< $@ 22 cp $< $@
23 23
24 $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make 24 $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
@@ -41,5 +41,5 @@ index 9d70691..25f45a8 100755
41 # Check for awk Posix compliance. 41 # Check for awk Posix compliance.
42 ($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1 42 ($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
43-- 43--
442.1.4 442.6.4
45 45
diff --git a/meta/recipes-core/glibc/glibc/nscd-no-bash.patch b/meta/recipes-core/glibc/glibc/0017-Remove-bash-dependency-for-nscd-init-script.patch
index c306ce6afe..0c9ae6c139 100644
--- a/meta/recipes-core/glibc/glibc/nscd-no-bash.patch
+++ b/meta/recipes-core/glibc/glibc/0017-Remove-bash-dependency-for-nscd-init-script.patch
@@ -1,7 +1,16 @@
1Don't use bashisms (except for echo -n, which busybox supports) to avoid needing bash to start nscd. 1From cd9d9fe7316f4ce4ca9d8e67e22f5718879535e4 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Thu, 31 Dec 2015 14:33:02 -0800
4Subject: [PATCH 17/24] Remove bash dependency for nscd init script
5
6The nscd init script uses #! /bin/bash but only really uses one bashism
7(translated strings), so remove them and switch the shell to #!/bin/sh.
2 8
3Upstream-Status: Pending
4Signed-off-by: Ross Burton <ross.burton@intel.com> 9Signed-off-by: Ross Burton <ross.burton@intel.com>
10Signed-off-by: Khem Raj <raj.khem@gmail.com>
11---
12 nscd/nscd.init | 14 +++++++-------
13 1 file changed, 7 insertions(+), 7 deletions(-)
5 14
6diff --git a/nscd/nscd.init b/nscd/nscd.init 15diff --git a/nscd/nscd.init b/nscd/nscd.init
7index a882da7..b02986e 100644 16index a882da7..b02986e 100644
@@ -59,3 +68,6 @@ index a882da7..b02986e 100644
59 RETVAL=1 68 RETVAL=1
60 ;; 69 ;;
61 esac 70 esac
71--
722.6.4
73
diff --git a/meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch b/meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch
index 8eacbc059f..e282e60ebd 100644
--- a/meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch
+++ b/meta/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch
@@ -1,7 +1,7 @@
1From eff048074ac7b5258bb615e5a5b221daa19b18ae Mon Sep 17 00:00:00 2001 1From 8f554f4a1beb39182aad9cd9b5e1da69464dff7e Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:42:58 +0000 3Date: Wed, 18 Mar 2015 00:42:58 +0000
4Subject: [PATCH 18/27] eglibc: Cross building and testing instructions 4Subject: [PATCH 18/24] eglibc: Cross building and testing instructions
5 5
6Ported from eglibc 6Ported from eglibc
7Upstream-Status: Pending 7Upstream-Status: Pending
@@ -615,5 +615,5 @@ index 0000000..b67b468
615+ simply place copies of these libraries in the top GLIBC build 615+ simply place copies of these libraries in the top GLIBC build
616+ directory. 616+ directory.
617-- 617--
6182.1.4 6182.6.4
619 619
diff --git a/meta/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch b/meta/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch
deleted file mode 100644
index dcb80f9c80..0000000000
--- a/meta/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch
+++ /dev/null
@@ -1,1436 +0,0 @@
1From aa7c5fe86d04584a9aed4dc40ba856c65a1ef9c4 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:45:18 +0000
4Subject: [PATCH 19/27] eglibc: Bring Eglibc option group infrastructure to
5 glibc
6
7Upstream-Status: Pending
8
9Signed-off-by: Khem Raj <raj.khem@gmail.com>
10---
11 EGLIBC.option-groups | 122 ++++++
12 Makefile | 1 +
13 config.make.in | 2 +
14 configure | 13 +
15 configure.ac | 10 +
16 option-groups.def | 868 ++++++++++++++++++++++++++++++++++++++
17 option-groups.defaults | 47 +++
18 option-groups.mak | 41 ++
19 options-config/Makefile | 55 +++
20 options-config/config-postproc.pl | 58 +++
21 options-config/config-preproc.pl | 8 +
22 scripts/option-groups.awk | 63 +++
23 12 files changed, 1288 insertions(+)
24 create mode 100644 EGLIBC.option-groups
25 create mode 100644 option-groups.def
26 create mode 100644 option-groups.defaults
27 create mode 100644 option-groups.mak
28 create mode 100644 options-config/Makefile
29 create mode 100644 options-config/config-postproc.pl
30 create mode 100644 options-config/config-preproc.pl
31 create mode 100644 scripts/option-groups.awk
32
33diff --git a/EGLIBC.option-groups b/EGLIBC.option-groups
34new file mode 100644
35index 0000000..6a50b8d
36--- /dev/null
37+++ b/EGLIBC.option-groups
38@@ -0,0 +1,122 @@
39+ -*- mode: text -*-
40+
41+ The EGLIBC Component Configuration System
42+ Jim Blandy <jimb@codesourcery.com>
43+
44+Introduction
45+
46+The GNU C library (GLIBC) provides a broad range of functionality,
47+ranging from internationalization support to transcendental
48+mathematical functions. Its website boasts that "nearly all known and
49+useful functions from any other C library are available." This
50+exhaustive approach has been one of GLIBC's strengths on desktop and
51+server systems, but it has also given GLIBC a large footprint, both in
52+memory and on disk, making it a challenge to use in embedded systems
53+with limited resources.
54+
55+The Embedded GNU C library (EGLIBC) is a variant of the GNU C library
56+designed to work well on embedded systems. In particular, EGLIBC's
57+component configuration system allows embedded developers to build
58+customized versions of the library that include only the features
59+their application uses, reducing its space requirements.
60+
61+EGLIBC's component configuration system categorizes the library's
62+functions into "option groups", and allows you to include or exclude
63+option groups individually. Some option groups depend on others;
64+EGLIBC tracks these relationships, and ensures that the selected
65+configuration yields a functioning library.
66+
67+
68+Consistent and Predictable Behavior
69+
70+A flexible configuration system is a mixed blessing: if the options
71+offered are poorly designed, it can be hard to see which choices will
72+have the desired effects, and choices with obscure consequences can
73+make debugging difficult. EGLIBC's configuration follows some general
74+principles to reduce these risks:
75+
76+- EGLIBC has a single default configuration for each target
77+ architecture.
78+
79+- In the default configuration, all option groups are enabled, and
80+ EGLIBC is upwardly API- and ABI-compatible with GLIBC.
81+
82+- As much as possible, configurations only affect what functions are
83+ present, not how they behave. If the system works with an option
84+ group disabled, it will still work with it enabled.
85+
86+- As much as possible, configurations only select option groups ---
87+ they do not describe characteristics of the target architecture.
88+
89+These rules mean that you have a simple debugging strategy available
90+if you suspect that your EGLIBC configuration might be the source of a
91+problem: fall back to the default configuration, re-test, and then
92+disable option groups one by one, until the problem reappears.
93+
94+
95+The Option Groups
96+
97+To see the current full list of implemented option groups, refer to the
98+file 'option-groups.def' at the top of the source tree, or run
99+'make menuconfig' from the top-level build directory.
100+
101+The POSIX.1-2001 specification includes a suggested partition of all
102+the functions in the POSIX C API into option groups: math functions
103+like 'sin' and 'cos'; networking functions like 'socket' and
104+'connect'; and so on. EGLIBC could use this partitioning as the basis
105+for future option groups.
106+
107+
108+Implementation
109+
110+The EGLIBC component configuration system resembles the approach used
111+by the Linux kernel to select device drivers, network protocols, and
112+other features. A file named 'option-groups.config' in the top-level
113+build directory contains assignments to Make variables, each of which
114+enables or disables a particular option group. If the variable's
115+value is set to 'y', then the option group is enabled; if it set to
116+anything else, the option group is omitted. The file
117+'option-groups.defaults', at the top of the source tree, establishes
118+default values for all variables; all option groups are enabled by
119+default.
120+
121+For example, the following 'option-groups.config' would omit locale
122+data, but include mathematical functions, and everything else:
123+
124+ OPTION_EGLIBC_LOCALES = n
125+ OPTION_EGLIBC_LIBM = y
126+
127+Like the Linux kernel, EGLIBC supports a similar set of '*config' make
128+targets to make it easier to create 'option-groups.config', with all
129+dependencies between option groups automatically satisfied. Run
130+'make help' to see the list of supported make config targets. For
131+example, 'make menuconfig' will update the current config utilising a
132+menu based program.
133+
134+The option group names and their type (boolean, int, hex, string), help
135+description, and dependencies with other option groups, are described by
136+'option-groups.def' at the top of the source tree, analogous to the
137+'Kconfig' files in the Linux kernel.
138+
139+In general, each option group variable controls whether a given set of
140+object files in EGLIBC is compiled and included in the final
141+libraries, or omitted from the build.
142+
143+Each subdirectory's Makefile categorizes its routines, libraries, and
144+executables by option group. For example, EGLIBC's 'math/Makefile'
145+places the 'libm' library in the OPTION_EGLIBC_LIBM group as follows:
146+
147+ extra-libs-$(OPTION_EGLIBC_LIBM) := libm
148+
149+Finally, common code in 'Makerules' cites the value of the variable
150+'extra-libs-y', selecting only those libraries that belong to enabled
151+option groups to be built.
152+
153+
154+Current Status and Future Directions
155+
156+The EGLIBC component configuration system described here is still
157+under development.
158+
159+We have used the system to subset some portions of EGLIBC's
160+Index: libc/configure.ac
161diff --git a/Makefile b/Makefile
162index 658ccfa..f906391 100644
163--- a/Makefile
164+++ b/Makefile
165@@ -24,6 +24,7 @@ endif
166
167 include Makeconfig
168
169+include options-config/Makefile
170
171 # This is the default target; it makes everything except the tests.
172 .PHONY: all
173diff --git a/config.make.in b/config.make.in
174index a9f5696..294f8d1 100644
175--- a/config.make.in
176+++ b/config.make.in
177@@ -47,6 +47,8 @@ c++-sysincludes = @CXX_SYSINCLUDES@
178 all-warnings = @all_warnings@
179 enable-werror = @enable_werror@
180
181+kconfig_tools = @KCONFIG_TOOLS@
182+
183 have-z-combreloc = @libc_cv_z_combreloc@
184 have-z-execstack = @libc_cv_z_execstack@
185 have-Bgroup = @libc_cv_Bgroup@
186diff --git a/configure b/configure
187index 7d7299a..4116404 100755
188--- a/configure
189+++ b/configure
190@@ -641,6 +641,7 @@ INSTALL_INFO
191 PERL
192 BASH_SHELL
193 libc_cv_gcc_static_libgcc
194+KCONFIG_TOOLS
195 CXX_SYSINCLUDES
196 SYSINCLUDES
197 AUTOCONF
198@@ -755,6 +756,7 @@ with_fp
199 with_binutils
200 with_selinux
201 with_headers
202+with_kconfig
203 with_default_link
204 enable_sanity_checks
205 enable_shared
206@@ -1459,6 +1461,9 @@ Optional Packages:
207 --with-selinux if building with SELinux support
208 --with-headers=PATH location of system headers to use (for example
209 /usr/src/linux/include) [default=compiler default]
210+ --with-kconfig=PATH location of kconfig tools to use (from Linux kernel
211+ builds) to re-use for configuring EGLIBC option
212+ groups
213 --with-default-link do not use explicit linker scripts
214 --with-cpu=CPU select code for CPU variant
215
216@@ -3517,6 +3522,14 @@ fi
217
218
219
220+# Check whether --with-kconfig was given.
221+if test "${with_kconfig+set}" = set; then
222+ withval=$with_kconfig; KCONFIG_TOOLS=$withval
223+else
224+ KCONFIG_TOOLS=''
225+fi
226+
227+
228
229 # Check whether --with-default-link was given.
230 if test "${with_default_link+set}" = set; then :
231diff --git a/configure.ac b/configure.ac
232index a467a69..fc0ed4d 100644
233--- a/configure.ac
234+++ b/configure.ac
235@@ -136,6 +136,16 @@ AC_ARG_WITH([headers],
236 [sysheaders=''])
237 AC_SUBST(sysheaders)
238
239+AC_ARG_WITH([kconfig],
240+ AC_HELP_STRING([--with-kconfig=PATH],
241+ [location of kconfig tools to use (from Linux
242+ kernel builds) to re-use for configuring EGLIBC
243+ option groups]),
244+ [KCONFIG_TOOLS=$withval],
245+ [KCONFIG_TOOLS=''])
246+AC_SUBST(KCONFIG_TOOLS)
247+
248+
249 AC_SUBST(use_default_link)
250 AC_ARG_WITH([default-link],
251 AC_HELP_STRING([--with-default-link],
252diff --git a/option-groups.def b/option-groups.def
253new file mode 100644
254index 0000000..6aebd94
255--- /dev/null
256+++ b/option-groups.def
257@@ -0,0 +1,868 @@
258+# This file documents the option groups EGLIBC currently supports, in
259+# a format akin to the Linux Kconfig system's. The syntax may change
260+# over time.
261+#
262+# An entry of the form:
263+#
264+# config GROUP_NAME
265+# bool "one-line explanation of what this option group controls"
266+# help
267+# Multi-line help explaining the option group's meaning in
268+# some detail, terminated by indentation level.
269+#
270+# defines an option group whose variable is GROUP_NAME, with
271+# meaningful values 'y' (enabled) and 'n' (disabled). The
272+# documentation is formatted to be consumed by some sort of
273+# interactive configuration interface, but EGLIBC doesn't have such an
274+# interface yet.
275+#
276+# An option may have a 'depends on' line, indicating which other options
277+# must also be enabled if this option is. At present, EGLIBC doesn't
278+# check that these dependencies are satisfied.
279+#
280+# Option group variables get their default values from the file
281+# 'option-groups.defaults', in the top directory of the EGLIBC source
282+# tree. By default, all EGLIBC option groups are enabled --- their
283+# variables are set to 'y'.
284+#
285+# After including 'option-groups.defaults', the EGLIBC make machinery
286+# includes the file 'option-groups.config' from the top of the build
287+# tree, if it is present. Developers can place assignments to option
288+# group variables in that file to override the defaults. For example,
289+# to disable an option group, place a line of the form:
290+#
291+# OPTION_GROUP_NAME = n
292+#
293+# in 'option-groups.config' at the top of your build tree. To
294+# explicitly enable an option group, you may also write:
295+#
296+# OPTION_GROUP_NAME = y
297+#
298+# although this simply reestablishes the value already set by
299+# 'option-groups.defaults'.
300+
301+config EGLIBC_ADVANCED_INET6
302+ bool "IPv6 Advanced Sockets API support (RFC3542)"
303+ depends on EGLIBC_INET
304+ help
305+ This option group includes the functions specified by RFC 3542,
306+ "Advanced Sockets Application Program Interface (API) for
307+ IPv6".
308+
309+ This option group includes the following functions:
310+
311+ inet6_opt_append
312+ inet6_opt_find
313+ inet6_opt_finish
314+ inet6_opt_get_val
315+ inet6_opt_init
316+ inet6_option_alloc
317+ inet6_option_append
318+ inet6_option_find
319+ inet6_option_init
320+ inet6_option_next
321+ inet6_option_space
322+ inet6_opt_next
323+ inet6_opt_set_val
324+ inet6_rth_add
325+ inet6_rth_getaddr
326+ inet6_rth_init
327+ inet6_rth_reverse
328+ inet6_rth_segments
329+ inet6_rth_space
330+
331+config EGLIBC_BACKTRACE
332+ bool "Functions for producing backtraces"
333+ help
334+ This option group includes functions for producing a list of
335+ the function calls that are currently active in a thread, from
336+ within the thread itself. These functions are often used
337+ within signal handlers, to produce diagnostic output.
338+
339+ This option group includes the following functions:
340+
341+ backtrace
342+ backtrace_symbols
343+ backtrace_symbols_fd
344+
345+config EGLIBC_BIG_MACROS
346+ bool "Use extensive inline code"
347+ help
348+ This option group specifies whether certain pieces of code
349+ should be inlined to achieve maximum speed. If this option
350+ group is not selected, function calls will be used instead,
351+ hence reducing the library footprint.
352+
353+config EGLIBC_BSD
354+ bool "BSD-specific functions, and their compatibility stubs"
355+ help
356+ This option group includes functions specific to BSD kernels.
357+ A number of these functions have stub versions that are also
358+ included in libraries built for non-BSD systems for
359+ compatibility.
360+
361+ This option group includes the following functions:
362+
363+ chflags
364+ fchflags
365+ lchmod
366+ revoke
367+ setlogin
368+
369+config EGLIBC_CXX_TESTS
370+ bool "Tests that link against the standard C++ library."
371+ depends on POSIX_WIDE_CHAR_DEVICE_IO && EGLIBC_LIBM
372+ help
373+ This option group does not include any C library functions;
374+ instead, it controls which EGLIBC tests an ordinary 'make
375+ tests' runs. With this group disabled, tests that would
376+ normally link against the standard C++ library are not
377+ run.
378+
379+ The standard C++ library depends on the math library 'libm' and
380+ the wide character I/O functions included in EGLIBC. So those
381+ option groups must be enabled if this test is enabled.
382+
383+config EGLIBC_CATGETS
384+ bool "Functions for accessing message catalogs"
385+ depends on EGLIBC_LOCALE_CODE
386+ help
387+ This option group includes functions for accessing message
388+ catalogs: catopen, catclose, and catgets.
389+
390+ This option group depends on the EGLIBC_LOCALE_CODE
391+ option group.
392+
393+config EGLIBC_CHARSETS
394+ bool "iconv/gconv character set conversion libraries"
395+ help
396+ This option group includes support for character sets other
397+ than ASCII (ANSI_X3.4-1968) and Unicode and ISO-10646 in their
398+ various encodings. This affects both the character sets
399+ supported by the wide and multibyte character functions, and
400+ those supported by the 'iconv' functions.
401+
402+ With this option group disabled, EGLIBC supports only the
403+ following character sets:
404+
405+ ANSI_X3.4 - ASCII
406+ ANSI_X3.4-1968
407+ ANSI_X3.4-1986
408+ ASCII
409+ CP367
410+ CSASCII
411+ IBM367
412+ ISO-IR-6
413+ ISO646-US
414+ ISO_646.IRV:1991
415+ OSF00010020
416+ US
417+ US-ASCII
418+
419+ 10646-1:1993 - ISO 10646, in big-endian UCS4 form
420+ 10646-1:1993/UCS4
421+ CSUCS4
422+ ISO-10646
423+ ISO-10646/UCS4
424+ OSF00010104
425+ OSF00010105
426+ OSF00010106
427+ UCS-4
428+ UCS-4BE
429+ UCS4
430+
431+ UCS-4LE - ISO 10646, in little-endian UCS4 form
432+
433+ ISO-10646/UTF-8 - ISO 10646, in UTF-8 form
434+ ISO-10646/UTF8
435+ ISO-IR-193
436+ OSF05010001
437+ UTF-8
438+ UTF8
439+
440+ ISO-10646/UCS2 - ISO 10646, in target-endian UCS2 form
441+ OSF00010100
442+ OSF00010101
443+ OSF00010102
444+ UCS-2
445+ UCS2
446+
447+ UCS-2BE - ISO 10646, in big-endian UCS2 form
448+ UNICODEBIG
449+
450+ UCS-2LE - ISO 10646, in little-endian UCS2 form
451+ UNICODELITTLE
452+
453+ WCHAR_T - EGLIBC's internal form (target-endian,
454+ 32-bit ISO 10646)
455+
456+config EGLIBC_CRYPT
457+ bool "Encryption library"
458+ help
459+ This option group includes the `libcrypt' library which
460+ provides functions for one-way encryption. Supported
461+ encryption algorithms include MD5, SHA-256, SHA-512 and DES.
462+
463+config EGLIBC_CRYPT_UFC
464+ bool "Ultra fast `crypt' implementation"
465+ depends on EGLIBC_CRYPT
466+ help
467+ This option group provides ultra fast DES-based implementation of
468+ the `crypt' function. When this option group is disabled,
469+ (a) the library will not provide the setkey[_r] and encrypt[_r]
470+ functions and (b) the crypt[_r] function will return NULL and set the
471+ errno to ENOSYS if /salt/ passed does not correspond to either MD5,
472+ SHA-256 or SHA-512 algorithm.
473+
474+config EGLIBC_DB_ALIASES
475+ bool "Functions for accessing the mail aliases database"
476+ help
477+ This option group includues functions for looking up mail
478+ aliases in '/etc/aliases' or using nsswitch. It includes the
479+ following functions:
480+
481+ endaliasent
482+ getaliasbyname
483+ getaliasbyname_r
484+ getaliasent
485+ getaliasent_r
486+ setaliasent
487+
488+ When this option group is disabled, the NSS service libraries
489+ also lack support for querying their mail alias tables.
490+
491+config EGLIBC_ENVZ
492+ bool "Functions for handling envz-style environment vectors."
493+ help
494+ This option group contains functions for creating and operating
495+ on envz vectors. An "envz vector" is a vector of strings in a
496+ contiguous block of memory, where each element is a name-value
497+ pair, and elements are separated from their neighbors by null
498+ characters.
499+
500+ This option group includes the following functions:
501+
502+ envz_add envz_merge
503+ envz_entry envz_remove
504+ envz_get envz_strip
505+
506+config EGLIBC_FCVT
507+ bool "Functions for converting floating-point numbers to strings"
508+ help
509+ This option group includes functions for converting
510+ floating-point numbers to strings.
511+
512+ This option group includes the following functions:
513+
514+ ecvt qecvt
515+ ecvt_r qecvt_r
516+ fcvt qfcvt
517+ fcvt_r qfcvt_r
518+ gcvt qgcvt
519+
520+config EGLIBC_FMTMSG
521+ bool "Functions for formatting messages"
522+ help
523+ This option group includes the following functions:
524+
525+ addseverity fmtmsg
526+
527+config EGLIBC_FSTAB
528+ bool "Access functions for 'fstab'"
529+ help
530+ This option group includes functions for reading the mount
531+ point specification table, '/etc/fstab'. These functions are
532+ not included in the POSIX standard, which provides the
533+ 'getmntent' family of functions instead.
534+
535+ This option group includes the following functions:
536+
537+ endfsent getfsspec
538+ getfsent setfsent
539+ getfsfile
540+
541+config EGLIBC_FTRAVERSE
542+ bool "Functions for traversing file hierarchies"
543+ help
544+ This option group includes functions for traversing file
545+ UNIX file hierachies.
546+
547+ This option group includes the following functions:
548+
549+ fts_open ftw
550+ fts_read nftw
551+ fts_children ftw64
552+ fts_set nftw64
553+ fts_close
554+
555+config EGLIBC_GETLOGIN
556+ bool "The getlogin function"
557+ depends on EGLIBC_UTMP
558+ help
559+ This function group includes the 'getlogin' and 'getlogin_r'
560+ functions, which return the user name associated by the login
561+ activity with the current process's controlling terminal.
562+
563+ With this option group disabled, the 'glob' function will not
564+ fall back on 'getlogin' to find the user's login name for tilde
565+ expansion when the 'HOME' environment variable is not set.
566+
567+config EGLIBC_IDN
568+ bool "International domain names support"
569+ help
570+ This option group includes the `libcidn' library which
571+ provides support for international domain names.
572+
573+config EGLIBC_INET
574+ bool "Networking support"
575+ help
576+ This option group includes networking-specific functions and
577+ data. With EGLIBC_INET disabled, the EGLIBC
578+ installation and API changes as follows:
579+
580+ - The following libraries are not installed:
581+
582+ libnsl
583+ libnss_compat
584+ libnss_dns
585+ libnss_hesiod
586+ libnss_nis
587+ libnss_nisplus
588+ libresolv
589+
590+ - The following functions and variables are omitted from libc:
591+
592+ authdes_create hstrerror svc_fdset
593+ authdes_getucred htonl svc_getreq
594+ authdes_pk_create htons svc_getreq_common
595+ authnone_create if_freenameindex svc_getreq_poll
596+ authunix_create if_indextoname svc_getreqset
597+ authunix_create_default if_nameindex svc_max_pollfd
598+ bindresvport if_nametoindex svc_pollfd
599+ callrpc in6addr_any svcraw_create
600+ cbc_crypt in6addr_loopback svc_register
601+ clnt_broadcast inet6_opt_append svc_run
602+ clnt_create inet6_opt_find svc_sendreply
603+ clnt_pcreateerror inet6_opt_finish svctcp_create
604+ clnt_perrno inet6_opt_get_val svcudp_bufcreate
605+ clnt_perror inet6_opt_init svcudp_create
606+ clntraw_create inet6_option_alloc svcudp_enablecache
607+ clnt_spcreateerror inet6_option_append svcunix_create
608+ clnt_sperrno inet6_option_find svcunixfd_create
609+ clnt_sperror inet6_option_init svc_unregister
610+ clnttcp_create inet6_option_next user2netname
611+ clntudp_bufcreate inet6_option_space xdecrypt
612+ clntudp_create inet6_opt_next xdr_accepted_reply
613+ clntunix_create inet6_opt_set_val xdr_array
614+ des_setparity inet6_rth_add xdr_authdes_cred
615+ ecb_crypt inet6_rth_getaddr xdr_authdes_verf
616+ endaliasent inet6_rth_init xdr_authunix_parms
617+ endhostent inet6_rth_reverse xdr_bool
618+ endnetent inet6_rth_segments xdr_bytes
619+ endnetgrent inet6_rth_space xdr_callhdr
620+ endprotoent inet_addr xdr_callmsg
621+ endrpcent inet_aton xdr_char
622+ endservent inet_lnaof xdr_cryptkeyarg
623+ ether_aton inet_makeaddr xdr_cryptkeyarg2
624+ ether_aton_r inet_netof xdr_cryptkeyres
625+ ether_hostton inet_network xdr_des_block
626+ ether_line inet_nsap_addr xdr_double
627+ ether_ntoa inet_nsap_ntoa xdr_enum
628+ ether_ntoa_r inet_ntoa xdr_float
629+ ether_ntohost inet_ntop xdr_free
630+ freeaddrinfo inet_pton xdr_getcredres
631+ freeifaddrs innetgr xdr_hyper
632+ gai_strerror iruserok xdr_int
633+ getaddrinfo iruserok_af xdr_int16_t
634+ getaliasbyname key_decryptsession xdr_int32_t
635+ getaliasbyname_r key_decryptsession_pk xdr_int64_t
636+ getaliasent key_encryptsession xdr_int8_t
637+ getaliasent_r key_encryptsession_pk xdr_keybuf
638+ gethostbyaddr key_gendes xdr_key_netstarg
639+ gethostbyaddr_r key_get_conv xdr_key_netstres
640+ gethostbyname key_secretkey_is_set xdr_keystatus
641+ gethostbyname2 key_setnet xdr_long
642+ gethostbyname2_r key_setsecret xdr_longlong_t
643+ gethostbyname_r netname2host xdrmem_create
644+ gethostent netname2user xdr_netnamestr
645+ gethostent_r ntohl xdr_netobj
646+ getifaddrs ntohs xdr_opaque
647+ getipv4sourcefilter passwd2des xdr_opaque_auth
648+ get_myaddress pmap_getmaps xdr_pmap
649+ getnameinfo pmap_getport xdr_pmaplist
650+ getnetbyaddr pmap_rmtcall xdr_pointer
651+ getnetbyaddr_r pmap_set xdr_quad_t
652+ getnetbyname pmap_unset xdrrec_create
653+ getnetbyname_r rcmd xdrrec_endofrecord
654+ getnetent rcmd_af xdrrec_eof
655+ getnetent_r registerrpc xdrrec_skiprecord
656+ getnetgrent res_init xdr_reference
657+ getnetgrent_r rexec xdr_rejected_reply
658+ getnetname rexec_af xdr_replymsg
659+ getprotobyname rexecoptions xdr_rmtcall_args
660+ getprotobyname_r rpc_createerr xdr_rmtcallres
661+ getprotobynumber rresvport xdr_short
662+ getprotobynumber_r rresvport_af xdr_sizeof
663+ getprotoent rtime xdrstdio_create
664+ getprotoent_r ruserok xdr_string
665+ getpublickey ruserok_af xdr_u_char
666+ getrpcbyname ruserpass xdr_u_hyper
667+ getrpcbyname_r setaliasent xdr_u_int
668+ getrpcbynumber sethostent xdr_uint16_t
669+ getrpcbynumber_r setipv4sourcefilter xdr_uint32_t
670+ getrpcent setnetent xdr_uint64_t
671+ getrpcent_r setnetgrent xdr_uint8_t
672+ getrpcport setprotoent xdr_u_long
673+ getsecretkey setrpcent xdr_u_longlong_t
674+ getservbyname setservent xdr_union
675+ getservbyname_r setsourcefilter xdr_unixcred
676+ getservbyport svcauthdes_stats xdr_u_quad_t
677+ getservbyport_r svcerr_auth xdr_u_short
678+ getservent svcerr_decode xdr_vector
679+ getservent_r svcerr_noproc xdr_void
680+ getsourcefilter svcerr_noprog xdr_wrapstring
681+ h_errlist svcerr_progvers xencrypt
682+ h_errno svcerr_systemerr xprt_register
683+ herror svcerr_weakauth xprt_unregister
684+ h_nerr svc_exit
685+ host2netname svcfd_create
686+
687+ - The rpcgen, nscd, and rpcinfo commands are not installed.
688+
689+ - The 'rpc' file (a text file listing RPC services) is not installed.
690+
691+ Socket-related system calls do not fall in this option group,
692+ because many are also used for other inter-process
693+ communication mechanisms. For example, the 'syslog' routines
694+ use Unix-domain sockets to communicate with the syslog daemon;
695+ syslog is valuable in non-networked contexts.
696+
697+config EGLIBC_INET_ANL
698+ bool "Asynchronous name lookup"
699+ depends on EGLIBC_INET
700+ help
701+ This option group includes the `libanl' library which
702+ provides support for asynchronous name lookup.
703+
704+config EGLIBC_LIBM
705+ bool "libm (math library)"
706+ help
707+ This option group includes the 'libm' library, containing
708+ mathematical functions. If this option group is omitted, then
709+ an EGLIBC installation does not include shared or unshared versions
710+ of the math library.
711+
712+ Note that this does not remove all floating-point related
713+ functionality from EGLIBC; for example, 'printf' and 'scanf'
714+ can still print and read floating-point values with this option
715+ group disabled.
716+
717+ Note that the ISO Standard C++ library 'libstdc++' depends on
718+ EGLIBC's math library 'libm'. If you disable this option
719+ group, you will not be able to build 'libstdc++' against the
720+ resulting EGLIBC installation.
721+
722+config EGLIBC_LOCALES
723+ bool "Locale definitions"
724+ help
725+ This option group includes all locale definitions other than
726+ that for the "C" locale. If this option group is omitted, then
727+ only the "C" locale is supported.
728+
729+
730+config EGLIBC_LOCALE_CODE
731+ bool "Locale functions"
732+ depends on POSIX_C_LANG_WIDE_CHAR
733+ help
734+ This option group includes locale support functions, programs,
735+ and libraries. With EGLIBC_LOCALE_CODE disabled,
736+ EGLIBC supports only the 'C' locale (also known as 'POSIX'),
737+ and ignores the settings of the 'LANG' and 'LC_*' environment
738+ variables.
739+
740+ With EGLIBC_LOCALE_CODE disabled, the following
741+ functions are omitted from libc:
742+
743+ duplocale localeconv nl_langinfo rpmatch strfmon_l
744+ freelocale newlocale nl_langinfo_l strfmon uselocale
745+
746+ Furthermore, only the LC_CTYPE and LC_TIME categories of the
747+ standard "C" locale are available.
748+
749+ The EGLIBC_CATGETS option group depends on this option group.
750+
751+
752+config EGLIBC_MEMUSAGE
753+ bool "Memory profiling library"
754+ help
755+ This option group includes the `libmemusage' library and
756+ the `memusage' and `memusagestat' utilities.
757+ These components provide memory profiling functions.
758+
759+config EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
760+ int "Memory profiling library buffer size"
761+ depends on EGLIBC_MEMUSAGE
762+ default "32768"
763+ help
764+ Libmemusage library buffers the profiling data in memory
765+ before writing it out to disk. By default, the library
766+ allocates 1.5M buffer, which can be substantial for some
767+ systems. EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE option
768+ allows to change the default buffer size. It specifies
769+ the number of entries the buffer should have.
770+ On most architectures one buffer entry amounts to 48 bytes,
771+ so setting this option to the value of 512 will reduce the size of
772+ the memory buffer to 24K.
773+
774+config EGLIBC_NIS
775+ bool "Support for NIS, NIS+, and the special 'compat' services."
776+ depends on EGLIBC_INET && EGLIBC_SUNRPC
777+ help
778+ This option group includes the NIS, NIS+, and 'compat' Name
779+ Service Switch service libraries. When it is disabled, those
780+ services libraries are not installed; you should remove any
781+ references to them from your 'nsswitch.conf' file.
782+
783+ This option group depends on the EGLIBC_INET option
784+ group; you must enable that to enable this option group.
785+
786+config EGLIBC_NSSWITCH
787+ bool "Name service switch (nsswitch) support"
788+ help
789+ This option group includes support for the 'nsswitch' facility.
790+ With this option group enabled, all EGLIBC functions for
791+ accessing various system databases (passwords and groups;
792+ networking; aliases; public keys; and so on) consult the
793+ '/etc/nsswitch.conf' configuration file to decide how to handle
794+ queries.
795+
796+ With this option group disabled, EGLIBC uses a fixed list of
797+ services to satisfy queries on each database, as requested by
798+ configuration files specified when EGLIBC is built. Your
799+ 'option-groups.config' file must set the following two
800+ variables:
801+
802+config EGLIBC_NSSWITCH_FIXED_CONFIG
803+ string "Nsswitch fixed config filename"
804+ depends on !EGLIBC_NSSWITCH
805+ default ""
806+ help
807+ Set this to the name of a file whose contents observe the
808+ same syntax as an ordinary '/etc/nsswitch.conf' file. The
809+ EGLIBC build process parses this file just as EGLIBC would
810+ at run time if EGLIBC_NSSWITCH were enabled, and
811+ produces a C library that uses the nsswitch service
812+ libraries to search for database entries as this file
813+ specifies, instead of consulting '/etc/nsswitch.conf' at run
814+ time.
815+
816+ This should be an absolute filename. The EGLIBC build
817+ process may use it from several different working
818+ directories. It may include references to Makefile
819+ variables like 'common-objpfx' (the top of the build tree,
820+ with a trailing slash), or '..' (the top of the source tree,
821+ with a trailing slash).
822+
823+ The EGLIBC source tree includes a sample configuration file
824+ named 'nss/fixed-nsswitch.conf'; for simple configurations,
825+ you will probably want to delete references to databases not
826+ needed on your system.
827+
828+config EGLIBC_NSSWITCH_FIXED_FUNCTIONS
829+ string "Nsswitch fixed functions filename"
830+ depends on !EGLIBC_NSSWITCH
831+ default ""
832+ help
833+ The EGLIBC build process uses this file to decide which
834+ functions to make available from which service libraries.
835+ The file 'nss/fixed-nsswitch.functions' serves as a sample
836+ configuration file for this setting, and explains its syntax
837+ and meaning in more detail.
838+
839+ This should be an absolute file name. The EGLIBC build
840+ process may use it from several different working
841+ directories. It may include references to Makefile
842+ variables like 'common-objpfx' (the top of the build tree,
843+ with a trailing slash), or '..' (the top of the source tree,
844+ with a trailing slash).
845+
846+ Be sure to mention each function in each service you wish to
847+ use. If you do not mention a service's function here, the
848+ EGLIBC database access functions will not find it, even if
849+ it is listed in the EGLIBC_NSSWITCH_FIXED_CONFIG
850+ file.
851+
852+ In this arrangement, EGLIBC will not use the 'dlopen' and
853+ 'dlsym' functions to find database access functions. Instead,
854+ libc hard-codes references to the service libraries' database
855+ access functions. You must explicitly link your program
856+ against the name service libraries (those whose names start
857+ with 'libnss_', in the sysroot's '/lib' directory) whose
858+ functions you intend to use. This arrangement helps
859+ system-wide static analysis tools decide which functions a
860+ system actually uses.
861+
862+ Note that some nsswitch service libraries require other option
863+ groups to be enabled; for example, the EGLIBC_INET
864+ option group must be enabled to use the 'libnss_dns.so.2'
865+ service library, which uses the Domain Name System network
866+ protocol to answer queries.
867+
868+config EGLIBC_RCMD
869+ bool "Support for 'rcmd' and related library functions"
870+ depends on EGLIBC_INET
871+ help
872+ This option group includes functions for running commands on
873+ remote machines via the 'rsh' protocol, and doing authentication
874+ related to those functions. This also includes functions that
875+ use the 'rexec' protocol.
876+
877+ This option group includes the following functions:
878+
879+ rcmd ruserok
880+ rcmd_af ruserok_af
881+ rexec iruserok
882+ rexec_af iruserok_af
883+ rresvport ruserpass
884+ rresvport_af
885+
886+config EGLIBC_RTLD_DEBUG
887+ bool "Runtime linker debug print outs"
888+ help
889+ This option group enables debug output of the runtime linker
890+ which is activated via LD_DEBUG and LD_TRACE_PRELINKING
891+ environment variables. Disabling this option group yields
892+ a smaller runtime linker binary.
893+ BEWARE: Disabling this option group is likely to break
894+ the `ldd' utility which may also be used by the prelinker.
895+ In particular, the `--unused' ldd option will not work correctly.
896+
897+config EGLIBC_SPAWN
898+ bool "Support for POSIX posix_spawn functions"
899+ help
900+ This option group includes the POSIX functions for executing
901+ programs in child processes without using 'fork' or 'vfork'.
902+
903+ This option group includes the following functions:
904+
905+ posix_spawn
906+ posix_spawnattr_destroy
907+ posix_spawnattr_getflags
908+ posix_spawnattr_getpgroup
909+ posix_spawnattr_getschedparam
910+ posix_spawnattr_getschedpolicy
911+ posix_spawnattr_getsigdefault
912+ posix_spawnattr_getsigmask
913+ posix_spawnattr_init
914+ posix_spawnattr_setflags
915+ posix_spawnattr_setpgroup
916+ posix_spawnattr_setschedparam
917+ posix_spawnattr_setschedpolicy
918+ posix_spawnattr_setsigdefault
919+ posix_spawnattr_setsigmask
920+ posix_spawn_file_actions_addclose
921+ posix_spawn_file_actions_adddup2
922+ posix_spawn_file_actions_addopen
923+ posix_spawn_file_actions_destroy
924+ posix_spawn_file_actions_init
925+ posix_spawnp
926+
927+ This option group also provides the ability for the iconv,
928+ localedef, and locale programs to operate transparently on
929+ compressed charset definitions. When this option group is
930+ disabled, those programs will only operate on uncompressed
931+ charmap files.
932+
933+config EGLIBC_STREAMS
934+ bool "Support for accessing STREAMS."
935+ help
936+ This option group includes functions for reading and writing
937+ messages to and from STREAMS. The STREAMS interface provides a
938+ uniform mechanism for implementing networking services and other
939+ character-based I/O. (STREAMS are not to be confused with
940+ <stdio.h> FILE objects, also called 'streams'.)
941+
942+ This option group includes the following functions:
943+
944+ getmsg putpmsg
945+ getpmsg fattach
946+ isastream fdetach
947+ putmsg
948+
949+config EGLIBC_SUNRPC
950+ bool "Support for the Sun 'RPC' protocol."
951+ depends on EGLIBC_INET
952+ help
953+ This option group includes support for the Sun RPC protocols,
954+ including the 'rpcgen' and 'rpcinfo' programs.
955+
956+config EGLIBC_UTMP
957+ bool "Older access functions for 'utmp' login records"
958+ help
959+ This option group includes the older 'utent' family of
960+ functions for accessing user login records in the 'utmp' file.
961+ POSIX omits these functions in favor of the 'utxent' family,
962+ and they are obsolete on systems other than Linux.
963+
964+ This option group includes the following functions:
965+
966+ endutent
967+ getutent
968+ getutent_r
969+ getutid
970+ getutid_r
971+ getutline
972+ getutline_r
973+ logwtmp
974+ pututline
975+ setutent
976+ updwtmp
977+ utmpname
978+
979+ This option group includes the following libraries:
980+
981+ libutil.so (and libutil.a)
982+
983+config EGLIBC_UTMPX
984+ bool "POSIX access functions for 'utmp' login records"
985+ depends on EGLIBC_UTMP
986+ help
987+ This option group includes the POSIX functions for reading and
988+ writing user login records in the 'utmp' file (usually
989+ '/var/run/utmp'). The POSIX functions operate on 'struct
990+ utmpx' structures, as opposed to the family of older 'utent'
991+ functions, which operate on 'struct utmp' structures.
992+
993+ This option group includes the following functions:
994+
995+ endutxent
996+ getutmp
997+ getutmpx
998+ getutxent
999+ getutxid
1000+ getutxline
1001+ pututxline
1002+ setutxent
1003+ updwtmpx
1004+ utmpxname
1005+
1006+config EGLIBC_WORDEXP
1007+ bool "Shell-style word expansion"
1008+ help
1009+ This option group includes the 'wordexp' function for
1010+ performing word expansion in the manner of the shell, and the
1011+ accompanying 'wordfree' function.
1012+
1013+config POSIX_C_LANG_WIDE_CHAR
1014+ bool "ISO C library wide character functions, excluding I/O"
1015+ help
1016+ This option group includes the functions defined by the ISO C
1017+ standard for working with wide and multibyte characters in
1018+ memory. Functions for reading and writing wide and multibyte
1019+ characters from and to files call in the
1020+ POSIX_WIDE_CHAR_DEVICE_IO option group.
1021+
1022+ This option group includes the following functions:
1023+
1024+ btowc mbsinit wcscspn wcstoll
1025+ iswalnum mbsrtowcs wcsftime wcstombs
1026+ iswalpha mbstowcs wcslen wcstoul
1027+ iswblank mbtowc wcsncat wcstoull
1028+ iswcntrl swprintf wcsncmp wcstoumax
1029+ iswctype swscanf wcsncpy wcsxfrm
1030+ iswdigit towctrans wcspbrk wctob
1031+ iswgraph towlower wcsrchr wctomb
1032+ iswlower towupper wcsrtombs wctrans
1033+ iswprint vswprintf wcsspn wctype
1034+ iswpunct vswscanf wcsstr wmemchr
1035+ iswspace wcrtomb wcstod wmemcmp
1036+ iswupper wcscat wcstof wmemcpy
1037+ iswxdigit wcschr wcstoimax wmemmove
1038+ mblen wcscmp wcstok wmemset
1039+ mbrlen wcscoll wcstol
1040+ mbrtowc wcscpy wcstold
1041+
1042+config POSIX_REGEXP
1043+ bool "Regular expressions"
1044+ help
1045+ This option group includes the POSIX regular expression
1046+ functions, and the associated non-POSIX extensions and
1047+ compatibility functions.
1048+
1049+ With POSIX_REGEXP disabled, the following functions are
1050+ omitted from libc:
1051+
1052+ re_comp re_max_failures regcomp
1053+ re_compile_fastmap re_search regerror
1054+ re_compile_pattern re_search_2 regexec
1055+ re_exec re_set_registers regfree
1056+ re_match re_set_syntax rpmatch
1057+ re_match_2 re_syntax_options
1058+
1059+ Furthermore, the compatibility regexp interface defined in the
1060+ <regexp.h> header file, 'compile', 'step', and 'advance', is
1061+ omitted.
1062+
1063+config POSIX_REGEXP_GLIBC
1064+ bool "Regular expressions from GLIBC"
1065+ depends on POSIX_REGEXP
1066+ help
1067+ This option group specifies which regular expression
1068+ library to use. The choice is between regex
1069+ implementation from GLIBC and regex implementation from
1070+ libiberty. The GLIBC variant is fully POSIX conformant and
1071+ optimized for speed; regex from libiberty is more than twice
1072+ as small while still is enough for most practical purposes.
1073+
1074+config POSIX_WIDE_CHAR_DEVICE_IO
1075+ bool "Input and output functions for wide characters"
1076+ depends on POSIX_C_LANG_WIDE_CHAR
1077+ help
1078+ This option group includes functions for reading and writing
1079+ wide characters to and from <stdio.h> streams.
1080+
1081+ This option group includes the following functions:
1082+
1083+ fgetwc fwprintf putwchar vwscanf
1084+ fgetws fwscanf ungetwc wprintf
1085+ fputwc getwc vfwprintf wscanf
1086+ fputws getwchar vfwscanf
1087+ fwide putwc vwprintf
1088+
1089+ This option group further includes the following unlocked
1090+ variants of the above functions:
1091+
1092+ fgetwc_unlocked getwc_unlocked
1093+ fgetws_unlocked getwchar_unlocked
1094+ fputwc_unlocked putwc_unlocked
1095+ fputws_unlocked putwchar_unlocked
1096+
1097+ Note that the GNU standard C++ library, 'libstdc++.so', uses
1098+ some of these functions; you will not be able to link or run
1099+ C++ programs if you disable this option group.
1100+
1101+ This option group also affects the behavior of the following
1102+ functions:
1103+
1104+ fdopen
1105+ fopen
1106+ fopen64
1107+ freopen
1108+ freopen64
1109+
1110+ These functions all take an OPENTYPE parameter which may
1111+ contain a string of the form ",ccs=CHARSET", indicating that
1112+ the underlying file uses the character set named CHARSET.
1113+ This produces a wide-oriented stream, which is only useful
1114+ when the functions included in this option group are present.
1115+ If the user attempts to open a file specifying a character set
1116+ in the OPENTYPE parameter, and EGLIBC was built with this
1117+ option group disabled, the function returns NULL, and sets
1118+ errno to EINVAL.
1119+
1120+
1121+# This helps Emacs users browse this file using the page motion commands
1122+# and commands like 'pages-directory'.
1123+# Local Variables:
1124+# page-delimiter: "^config\\s-"
1125+# End:
1126diff --git a/option-groups.defaults b/option-groups.defaults
1127new file mode 100644
1128index 0000000..8141201
1129--- /dev/null
1130+++ b/option-groups.defaults
1131@@ -0,0 +1,47 @@
1132+# This file sets default values for all option group variables
1133+# mentioned in option-groups.def; see that file for a description of
1134+# each option group.
1135+#
1136+# Subdirectory makefiles include this file before including the user's
1137+# settings from option-groups.config at the top of the build tree;
1138+# that file need only refer to those options whose default settings
1139+# are to be changed.
1140+#
1141+# By default, all option groups are enabled.
1142+OPTION_EGLIBC_ADVANCED_INET6 = y
1143+OPTION_EGLIBC_BACKTRACE = y
1144+OPTION_EGLIBC_BIG_MACROS = y
1145+OPTION_EGLIBC_BSD = y
1146+OPTION_EGLIBC_CXX_TESTS = y
1147+OPTION_EGLIBC_CATGETS = y
1148+OPTION_EGLIBC_CHARSETS = y
1149+OPTION_EGLIBC_CRYPT = y
1150+OPTION_EGLIBC_CRYPT_UFC = y
1151+OPTION_EGLIBC_DB_ALIASES = y
1152+OPTION_EGLIBC_ENVZ = y
1153+OPTION_EGLIBC_FCVT = y
1154+OPTION_EGLIBC_FMTMSG = y
1155+OPTION_EGLIBC_FSTAB = y
1156+OPTION_EGLIBC_FTRAVERSE = y
1157+OPTION_EGLIBC_GETLOGIN = y
1158+OPTION_EGLIBC_IDN = y
1159+OPTION_EGLIBC_INET = y
1160+OPTION_EGLIBC_INET_ANL = y
1161+OPTION_EGLIBC_LIBM = y
1162+OPTION_EGLIBC_LOCALES = y
1163+OPTION_EGLIBC_LOCALE_CODE = y
1164+OPTION_EGLIBC_MEMUSAGE = y
1165+OPTION_EGLIBC_NIS = y
1166+OPTION_EGLIBC_NSSWITCH = y
1167+OPTION_EGLIBC_RCMD = y
1168+OPTION_EGLIBC_RTLD_DEBUG = y
1169+OPTION_EGLIBC_SPAWN = y
1170+OPTION_EGLIBC_STREAMS = y
1171+OPTION_EGLIBC_SUNRPC = y
1172+OPTION_EGLIBC_UTMP = y
1173+OPTION_EGLIBC_UTMPX = y
1174+OPTION_EGLIBC_WORDEXP = y
1175+OPTION_POSIX_C_LANG_WIDE_CHAR = y
1176+OPTION_POSIX_REGEXP = y
1177+OPTION_POSIX_REGEXP_GLIBC = y
1178+OPTION_POSIX_WIDE_CHAR_DEVICE_IO = y
1179diff --git a/option-groups.mak b/option-groups.mak
1180new file mode 100644
1181index 0000000..f83e0c1
1182--- /dev/null
1183+++ b/option-groups.mak
1184@@ -0,0 +1,41 @@
1185+# Setup file for subdirectory Makefiles that define EGLIBC option groups.
1186+
1187+# EGLIBC shouldn't need to override this. However, the
1188+# cross-build-friendly localedef includes this makefile to get option
1189+# group variable definitions; it uses a single build tree for all the
1190+# multilibs, and needs to be able to specify a different option group
1191+# configuration file for each multilib.
1192+option_group_config_file ?= $(objdir)/option-groups.config
1193+
1194+# Read the default settings for all options.
1195+# We're included before ../Rules, so we can't assume $(..) is set.
1196+include $(firstword $(..) ../)option-groups.defaults
1197+
1198+# Read the developer's option group selections, overriding the
1199+# defaults from option-groups.defaults.
1200+-include $(option_group_config_file)
1201+
1202+# $(call option-disabled, VAR) is 'y' if VAR is not 'y', or 'n' otherwise.
1203+# VAR should be a variable name, not a variable reference; this is
1204+# less general, but more terse for the intended use.
1205+# You can use it to add a file to a list if an option group is
1206+# disabled, like this:
1207+# routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) += ...
1208+define option-disabled
1209+$(firstword $(subst y,n,$(filter y,$($(strip $(1))))) y)
1210+endef
1211+
1212+# Establish 'routines-y', etc. as simply-expanded variables.
1213+aux-y :=
1214+extra-libs-others-y :=
1215+extra-libs-y :=
1216+extra-objs-y :=
1217+install-bin-y :=
1218+install-others-y :=
1219+install-sbin-y :=
1220+others-y :=
1221+others-pie-y :=
1222+routines-y :=
1223+test-srcs-y :=
1224+tests-y :=
1225+xtests-y :=
1226diff --git a/options-config/Makefile b/options-config/Makefile
1227new file mode 100644
1228index 0000000..db00708
1229--- /dev/null
1230+++ b/options-config/Makefile
1231@@ -0,0 +1,55 @@
1232+# ===========================================================================
1233+# EGLIBC option-groups configuration targets
1234+# These targets are included from top-level makefile
1235+
1236+ifneq ($(kconfig_tools),)
1237+ifneq (no,$(PERL))
1238+
1239+ocdir := options-config
1240+
1241+OconfigDefaults := option-groups.defaults
1242+OconfigDefaults_tmp := $(common-objpfx).tmp.defconfig
1243+OconfigDef := option-groups.def
1244+Oconfig := $(common-objpfx)option-groups.config
1245+Oconfig_tmp := $(common-objpfx).tmp.config
1246+
1247+conf := $(kconfig_tools)/conf
1248+mconf := $(kconfig_tools)/mconf
1249+
1250+preproc := $(PERL) $(ocdir)/config-preproc.pl
1251+postproc := $(PERL) $(ocdir)/config-postproc.pl
1252+
1253+PHONY += defconfig config menuconfig
1254+
1255+defconfig: $(conf) $(OconfigDefaults) $(OconfigDef)
1256+ rm -f $(OconfigDefaults_tmp)
1257+ rm -f $(Oconfig_tmp)
1258+ $(preproc) $(OconfigDefaults) > $(OconfigDefaults_tmp)
1259+ KCONFIG_CONFIG=$(Oconfig_tmp) $< --defconfig=$(OconfigDefaults_tmp) \
1260+ $(OconfigDef)
1261+ $(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
1262+ rm $(Oconfig_tmp)
1263+ rm $(OconfigDefaults_tmp)
1264+
1265+config: $(conf) $(OconfigDefaults) $(OconfigDef)
1266+ rm -f $(Oconfig_tmp)
1267+ $(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
1268+ KCONFIG_CONFIG=$(Oconfig_tmp) $< --oldaskconfig $(OconfigDef)
1269+ $(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
1270+ rm $(Oconfig_tmp)
1271+
1272+menuconfig: $(mconf) $(OconfigDefaults) $(OconfigDef)
1273+ rm -f $(Oconfig_tmp)
1274+ $(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
1275+ KCONFIG_CONFIG=$(Oconfig_tmp) $< $(OconfigDef)
1276+ $(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
1277+ rm $(Oconfig_tmp)
1278+
1279+# Help text used by make help
1280+help:
1281+ @echo ' defconfig - New config with default from default config'
1282+ @echo ' config - Update current config utilising a line-oriented program'
1283+ @echo ' menuconfig - Update current config utilising a menu based program'
1284+
1285+endif
1286+endif
1287diff --git a/options-config/config-postproc.pl b/options-config/config-postproc.pl
1288new file mode 100644
1289index 0000000..4dd1c63
1290--- /dev/null
1291+++ b/options-config/config-postproc.pl
1292@@ -0,0 +1,58 @@
1293+#!/usr/bin/perl
1294+
1295+$usage = "usage: $0 <default config file> <config file>\n";
1296+
1297+die "$usage" unless @ARGV;
1298+$defaults = shift @ARGV;
1299+die "$usage" unless @ARGV;
1300+die "Could not open $ARGV[0]" unless -T $ARGV[0];
1301+
1302+sub yank {
1303+ @option = grep(!($_ =~ /$_[0]\s*=/), @option);
1304+}
1305+
1306+open(DEFAULTS, $defaults) || die "Could not open $defaults\n";
1307+
1308+# get the full list of available options using the default config file
1309+$i = 0;
1310+while (<DEFAULTS>) {
1311+ if (/^\s*OPTION_(\w+\s*=.*$)/) {
1312+ $option[$i++] = $1;
1313+ }
1314+}
1315+
1316+# now go through the config file, making the necessary changes
1317+while (<>) {
1318+ if (/Linux Kernel Configuration/) {
1319+ # change title
1320+ s/Linux Kernel/Option Groups/;
1321+ print;
1322+ } elsif (/^\s*CONFIG_(\w+)\s*=/) {
1323+ # this is an explicit option set line, change CONFIG_ to OPTION_
1324+ # before printing and remove this option from option list
1325+ $opt = $1;
1326+ yank($opt);
1327+ s/CONFIG_/OPTION_/g;
1328+ print;
1329+ } elsif (/^\s*#\s+CONFIG_(\w+) is not set/) {
1330+ # this is a comment line for an unset boolean option, change CONFIG_
1331+ # to OPTION_, remove this option from option list, and convert to
1332+ # explicit OPTION_FOO=n
1333+ $opt = $1;
1334+ yank($opt);
1335+ s/CONFIG_/OPTION_/g;
1336+ print "OPTION_$opt=n\n";
1337+ } else {
1338+ print;
1339+ }
1340+}
1341+
1342+# any boolean options left in @options, are options that were not mentioned in
1343+# the config file, and implicitly that means the option must be set =n,
1344+# so do that here.
1345+foreach $opt (@option) {
1346+ if ($opt =~ /=\s*[yn]/) {
1347+ $opt =~ s/=\s*[yn]/=n/;
1348+ print "OPTION_$opt\n";
1349+ }
1350+}
1351diff --git a/options-config/config-preproc.pl b/options-config/config-preproc.pl
1352new file mode 100644
1353index 0000000..b83bb85
1354--- /dev/null
1355+++ b/options-config/config-preproc.pl
1356@@ -0,0 +1,8 @@
1357+#!/usr/bin/perl
1358+
1359+if (@ARGV) {
1360+ while (<>) {
1361+ s/OPTION_/CONFIG_/g;
1362+ print;
1363+ }
1364+}
1365diff --git a/scripts/option-groups.awk b/scripts/option-groups.awk
1366new file mode 100644
1367index 0000000..533af0c
1368--- /dev/null
1369+++ b/scripts/option-groups.awk
1370@@ -0,0 +1,63 @@
1371+# option-groups.awk --- generate option group header file
1372+# Given input files containing makefile-style assignments to variables,
1373+# print out a header file that #defines an appropriate preprocessor
1374+# symbol for each variable left set to 'y'.
1375+
1376+BEGIN { FS="=" }
1377+
1378+# Trim spaces.
1379+{ gsub (/[[:blank:]]/, "") }
1380+
1381+# Skip comments.
1382+/^#/ { next }
1383+
1384+# Process assignments.
1385+NF == 2 {
1386+ vars[$1] = $2
1387+}
1388+
1389+# Print final values.
1390+END {
1391+ print "/* This file is automatically generated by scripts/option-groups.awk"
1392+ print " in the EGLIBC source tree."
1393+ print ""
1394+ print " It defines macros that indicate which EGLIBC option groups were"
1395+ print " configured in 'option-groups.config' when this C library was"
1396+ print " built. For each option group named OPTION_foo, it #defines"
1397+ print " __OPTION_foo to be 1 if the group is enabled, or #defines that"
1398+ print " symbol to be 0 if the group is disabled. */"
1399+ print ""
1400+ print "#ifndef __GNU_OPTION_GROUPS_H"
1401+ print "#define __GNU_OPTION_GROUPS_H"
1402+ print ""
1403+
1404+ # Produce a sorted list of variable names.
1405+ i=0
1406+ for (var in vars)
1407+ names[i++] = var
1408+ n = asort (names)
1409+
1410+ for (i = 1; i <= n; i++)
1411+ {
1412+ var = names[i]
1413+ if (var ~ /^OPTION_/)
1414+ {
1415+ if (vars[var] == "y")
1416+ print "#define __" var " 1"
1417+ else if (vars[var] == "n")
1418+ print "#define __" var " 0"
1419+ else if (vars[var] ~ /^[0-9]+/ ||
1420+ vars[var] ~ /^0x[0-9aAbBcCdDeEfF]+/ ||
1421+ vars[var] ~ /^\"/)
1422+ print "#define __" var " " vars[var]
1423+ else
1424+ print "/* #undef __" var " */"
1425+ # Ignore variables that don't have boolean, int, hex, or
1426+ # string values. Ideally, this would be driven by the types
1427+ # given in option-groups.def.
1428+ }
1429+ }
1430+
1431+ print ""
1432+ print "#endif /* __GNU_OPTION_GROUPS_H */"
1433+}
1434--
14352.1.4
1436
diff --git a/meta/recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch b/meta/recipes-core/glibc/glibc/0019-eglibc-Help-bootstrap-cross-toolchain.patch
index df93094543..c04e0a11d4 100644
--- a/meta/recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch
+++ b/meta/recipes-core/glibc/glibc/0019-eglibc-Help-bootstrap-cross-toolchain.patch
@@ -1,7 +1,7 @@
1From 8fe0d29488b376011cdaaa462d557ffc0b31fb63 Mon Sep 17 00:00:00 2001 1From c2d49eab20db4ab02b6de62092fedc623d757146 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:49:28 +0000 3Date: Wed, 18 Mar 2015 00:49:28 +0000
4Subject: [PATCH 20/27] eglibc: Help bootstrap cross toolchain 4Subject: [PATCH 19/24] eglibc: Help bootstrap cross toolchain
5 5
6Taken from EGLIBC, r1484 + r1525 6Taken from EGLIBC, r1484 + r1525
7 7
@@ -29,7 +29,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
29 create mode 100644 include/stubs-bootstrap.h 29 create mode 100644 include/stubs-bootstrap.h
30 30
31diff --git a/Makefile b/Makefile 31diff --git a/Makefile b/Makefile
32index f906391..e4e149e 100644 32index 9a01c93..a6ae003 100644
33--- a/Makefile 33--- a/Makefile
34+++ b/Makefile 34+++ b/Makefile
35@@ -69,9 +69,18 @@ subdir-dirs = include 35@@ -69,9 +69,18 @@ subdir-dirs = include
@@ -96,5 +96,5 @@ index 0000000..1d2b669
96+ EGLIBC subdir 'stubs' make targets, on every .o file in EGLIBC, but 96+ EGLIBC subdir 'stubs' make targets, on every .o file in EGLIBC, but
97+ an empty stubs.h like this will do fine for GCC. */ 97+ an empty stubs.h like this will do fine for GCC. */
98-- 98--
992.1.4 992.6.4
100 100
diff --git a/meta/recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch b/meta/recipes-core/glibc/glibc/0020-eglibc-cherry-picked-from.patch
index 38bb8a15e3..4362efae77 100644
--- a/meta/recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch
+++ b/meta/recipes-core/glibc/glibc/0020-eglibc-cherry-picked-from.patch
@@ -1,30 +1,32 @@
1From fe2ae4f877928dd6bff5bac3f15bce4b50d2bd12 Mon Sep 17 00:00:00 2001 1From 588d936b9aa65e7cc8b1eb2cad1d209087db43a9 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:51:16 +0000 3Date: Thu, 31 Dec 2015 15:10:33 -0800
4Subject: [PATCH 21/27] eglibc: cherry-picked from 4Subject: [PATCH 20/24] eglibc: cherry-picked from
5 http://www.eglibc.org/archives/patches/msg00772.html
6 5
7It hasn't yet been merged into glibc 6http://www.eglibc.org/archives/patches/msg00772.html
7
8Not yet merged into glibc
8 9
9Upstream-Status: Pending 10Upstream-Status: Pending
10 11
11Signed-off-by: Khem Raj <raj.khem@gmail.com> 12Signed-off-by: Khem Raj <raj.khem@gmail.com>
12--- 13---
13 resolv/res_libc.c | 15 +++++++++++++-- 14 resolv/res_libc.c | 14 +++++++++++++-
14 1 file changed, 13 insertions(+), 2 deletions(-) 15 1 file changed, 13 insertions(+), 1 deletion(-)
15 16
16diff --git a/resolv/res_libc.c b/resolv/res_libc.c 17diff --git a/resolv/res_libc.c b/resolv/res_libc.c
17index ee3fa21..29e2340 100644 18index a8394e0..981ac7c 100644
18--- a/resolv/res_libc.c 19--- a/resolv/res_libc.c
19+++ b/resolv/res_libc.c 20+++ b/resolv/res_libc.c
20@@ -22,12 +22,13 @@ 21@@ -18,6 +18,7 @@
22 #include <atomic.h>
23 #include <limits.h>
24 #include <sys/types.h>
25+#include <sys/stat.h>
26 #include <netinet/in.h>
21 #include <arpa/nameser.h> 27 #include <arpa/nameser.h>
22 #include <resolv.h> 28 #include <resolv.h>
23 #include <bits/libc-lock.h> 29@@ -28,6 +29,7 @@
24-
25+#include <sys/stat.h>
26
27 /* The following bit is copied from res_data.c (where it is #ifdef'ed
28 out) since res_init() should go into libc.so but the rest of that 30 out) since res_init() should go into libc.so but the rest of that
29 file should not. */ 31 file should not. */
30 32
@@ -32,7 +34,7 @@ index ee3fa21..29e2340 100644
32 extern unsigned long long int __res_initstamp attribute_hidden; 34 extern unsigned long long int __res_initstamp attribute_hidden;
33 /* We have atomic increment operations on 64-bit platforms. */ 35 /* We have atomic increment operations on 64-bit platforms. */
34 #if __WORDSIZE == 64 36 #if __WORDSIZE == 64
35@@ -35,7 +36,6 @@ extern unsigned long long int __res_initstamp attribute_hidden; 37@@ -35,7 +37,6 @@ extern unsigned long long int __res_initstamp attribute_hidden;
36 # define atomicincunlock(lock) (void) 0 38 # define atomicincunlock(lock) (void) 0
37 # define atomicinc(var) catomic_increment (&(var)) 39 # define atomicinc(var) catomic_increment (&(var))
38 #else 40 #else
@@ -40,7 +42,7 @@ index ee3fa21..29e2340 100644
40 # define atomicinclock(lock) __libc_lock_lock (lock) 42 # define atomicinclock(lock) __libc_lock_lock (lock)
41 # define atomicincunlock(lock) __libc_lock_unlock (lock) 43 # define atomicincunlock(lock) __libc_lock_unlock (lock)
42 # define atomicinc(var) ++var 44 # define atomicinc(var) ++var
43@@ -94,7 +94,18 @@ res_init(void) { 45@@ -94,7 +95,18 @@ res_init(void) {
44 int 46 int
45 __res_maybe_init (res_state resp, int preinit) 47 __res_maybe_init (res_state resp, int preinit)
46 { 48 {
@@ -60,5 +62,5 @@ index ee3fa21..29e2340 100644
60 if (resp->nscount > 0) 62 if (resp->nscount > 0)
61 __res_iclose (resp, true); 63 __res_iclose (resp, true);
62-- 64--
632.1.4 652.6.4
64 66
diff --git a/meta/recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch b/meta/recipes-core/glibc/glibc/0021-eglibc-Clear-cache-lines-on-ppc8xx.patch
index 8a4c9c3e89..225f22f013 100644
--- a/meta/recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch
+++ b/meta/recipes-core/glibc/glibc/0021-eglibc-Clear-cache-lines-on-ppc8xx.patch
@@ -1,7 +1,7 @@
1From be7273225698074347a71de58006977bb304d7f7 Mon Sep 17 00:00:00 2001 1From b74e34e6f53816ad57b13ba6fd70a97db1bc1eae Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:53:47 +0000 3Date: Thu, 31 Dec 2015 15:15:09 -0800
4Subject: [PATCH 22/27] eglibc: Clear cache lines on ppc8xx 4Subject: [PATCH 21/24] eglibc: Clear cache lines on ppc8xx
5 5
62007-06-13 Nathan Sidwell <nathan@codesourcery.com> 62007-06-13 Nathan Sidwell <nathan@codesourcery.com>
7 Mark Shinwell <shinwell@codesourcery.com> 7 Mark Shinwell <shinwell@codesourcery.com>
@@ -13,11 +13,12 @@ Subject: [PATCH 22/27] eglibc: Clear cache lines on ppc8xx
13 (DL_PLATFORM_AUXV): Likewise. 13 (DL_PLATFORM_AUXV): Likewise.
14 14
15Upstream-Status: Pending 15Upstream-Status: Pending
16
16Signed-off-by: Khem Raj <raj.khem@gmail.com> 17Signed-off-by: Khem Raj <raj.khem@gmail.com>
17--- 18---
18 sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c | 14 +++++++++++++- 19 sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c | 14 +++++++++++++-
19 sysdeps/unix/sysv/linux/powerpc/libc-start.c | 15 ++++++++++++++- 20 sysdeps/unix/sysv/linux/powerpc/libc-start.c | 16 +++++++++++++++-
20 2 files changed, 27 insertions(+), 2 deletions(-) 21 2 files changed, 28 insertions(+), 2 deletions(-)
21 22
22diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c 23diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
23index c2504ff..d50f1cb 100644 24index c2504ff..d50f1cb 100644
@@ -47,15 +48,16 @@ index c2504ff..d50f1cb 100644
47 break; 48 break;
48 49
49diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c 50diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
50index a9364c7..a3ed1d4 100644 51index 209a16d..5d8572d 100644
51--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c 52--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
52+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c 53+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
53@@ -68,11 +68,24 @@ __libc_start_main (int argc, char **argv, 54@@ -73,11 +73,25 @@ __libc_start_main (int argc, char **argv,
54 rtld_fini = NULL;
55 }
56 55
57- /* Initialize the __cache_line_size variable from the aux vector. */ 56 /* Initialize the __cache_line_size variable from the aux vector. For the
58+ /* Initialize the __cache_line_size variable from the aux vector. 57 static case, we also need _dl_hwcap, _dl_hwcap2 and _dl_platform, so we
58- can call __tcb_parse_hwcap_and_convert_at_platform (). */
59+ can call __tcb_parse_hwcap_and_convert_at_platform ().
60+
59+ This is used by memset to optimize setting to zero. We have to 61+ This is used by memset to optimize setting to zero. We have to
60+ detect 8xx processors, which have buggy dcbz implementations that 62+ detect 8xx processors, which have buggy dcbz implementations that
61+ cannot report page faults correctly. That requires reading SPR, 63+ cannot report page faults correctly. That requires reading SPR,
@@ -75,7 +77,7 @@ index a9364c7..a3ed1d4 100644
75+ } 77+ }
76 __cache_line_size = av->a_un.a_val; 78 __cache_line_size = av->a_un.a_val;
77 break; 79 break;
78 } 80 #ifndef SHARED
79-- 81--
802.1.4 822.6.4
81 83
diff --git a/meta/recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch b/meta/recipes-core/glibc/glibc/0022-eglibc-Resolve-__fpscr_values-on-SH4.patch
index 9f3d753d70..88b20f67ad 100644
--- a/meta/recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch
+++ b/meta/recipes-core/glibc/glibc/0022-eglibc-Resolve-__fpscr_values-on-SH4.patch
@@ -1,7 +1,7 @@
1From 718e7e5db1c8b073adb9a79ec6f167238c2d8bda Mon Sep 17 00:00:00 2001 1From 8f483cb1f21ab6431ff99e8d30d56b91607ae918 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:55:53 +0000 3Date: Wed, 18 Mar 2015 00:55:53 +0000
4Subject: [PATCH 23/27] eglibc: Resolve __fpscr_values on SH4 4Subject: [PATCH 22/24] eglibc: Resolve __fpscr_values on SH4
5 5
62010-09-29 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> 62010-09-29 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
7 Andrew Stubbs <ams@codesourcery.com> 7 Andrew Stubbs <ams@codesourcery.com>
@@ -52,5 +52,5 @@ index a02b7e2..b9be326 100644
52+weak_alias (___fpscr_values, __fpscr_values) 52+weak_alias (___fpscr_values, __fpscr_values)
53+ 53+
54-- 54--
552.1.4 552.6.4
56 56
diff --git a/meta/recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch b/meta/recipes-core/glibc/glibc/0023-eglibc-Install-PIC-archives.patch
index c359cce9c5..d95ea3ba3d 100644
--- a/meta/recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch
+++ b/meta/recipes-core/glibc/glibc/0023-eglibc-Install-PIC-archives.patch
@@ -1,7 +1,7 @@
1From 5773417fa91a18cd39fb35c9907d72af0ed9ea33 Mon Sep 17 00:00:00 2001 1From 58d424884eed7efde6c90af0cd7c6c37cf9b444a Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com> 2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 01:57:01 +0000 3Date: Wed, 18 Mar 2015 01:57:01 +0000
4Subject: [PATCH 25/27] eglibc: Install PIC archives 4Subject: [PATCH 23/24] eglibc: Install PIC archives
5 5
6Forward port from eglibc 6Forward port from eglibc
7 7
@@ -29,10 +29,10 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
29 1 file changed, 40 insertions(+), 2 deletions(-) 29 1 file changed, 40 insertions(+), 2 deletions(-)
30 30
31diff --git a/Makerules b/Makerules 31diff --git a/Makerules b/Makerules
32index 1dd41aa..41778e1 100644 32index fa24030..1ff4634 100644
33--- a/Makerules 33--- a/Makerules
34+++ b/Makerules 34+++ b/Makerules
35@@ -713,6 +713,9 @@ ifeq ($(build-shared),yes) 35@@ -694,6 +694,9 @@ ifeq ($(build-shared),yes)
36 $(common-objpfx)libc.so: $(common-objpfx)libc.map 36 $(common-objpfx)libc.so: $(common-objpfx)libc.map
37 endif 37 endif
38 common-generated += libc.so libc_pic.os 38 common-generated += libc.so libc_pic.os
@@ -42,7 +42,7 @@ index 1dd41aa..41778e1 100644
42 ifdef libc.so-version 42 ifdef libc.so-version
43 $(common-objpfx)libc.so$(libc.so-version): $(common-objpfx)libc.so 43 $(common-objpfx)libc.so$(libc.so-version): $(common-objpfx)libc.so
44 $(make-link) 44 $(make-link)
45@@ -955,6 +958,7 @@ endif 45@@ -936,6 +939,7 @@ endif
46 46
47 install: check-install-supported 47 install: check-install-supported
48 48
@@ -50,7 +50,7 @@ index 1dd41aa..41778e1 100644
50 install: $(installed-libcs) 50 install: $(installed-libcs)
51 $(installed-libcs): $(inst_libdir)/lib$(libprefix)%: lib $(+force) 51 $(installed-libcs): $(inst_libdir)/lib$(libprefix)%: lib $(+force)
52 $(make-target-directory) 52 $(make-target-directory)
53@@ -983,6 +987,22 @@ versioned := $(strip $(foreach so,$(install-lib.so),\ 53@@ -964,6 +968,22 @@ versioned := $(strip $(foreach so,$(install-lib.so),\
54 install-lib.so-versioned := $(filter $(versioned), $(install-lib.so)) 54 install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
55 install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so)) 55 install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
56 56
@@ -73,7 +73,7 @@ index 1dd41aa..41778e1 100644
73 # For versioned libraries, we install three files: 73 # For versioned libraries, we install three files:
74 # $(inst_libdir)/libfoo.so -- for linking, symlink or ld script 74 # $(inst_libdir)/libfoo.so -- for linking, symlink or ld script
75 # $(inst_slibdir)/libfoo.so.NN -- for loading by SONAME, symlink 75 # $(inst_slibdir)/libfoo.so.NN -- for loading by SONAME, symlink
76@@ -1225,9 +1245,22 @@ $(addprefix $(inst_includedir)/,$(headers-nonh)): $(inst_includedir)/%: \ 76@@ -1206,9 +1226,22 @@ $(addprefix $(inst_includedir)/,$(headers-nonh)): $(inst_includedir)/%: \
77 endif # headers-nonh 77 endif # headers-nonh
78 endif # headers 78 endif # headers
79 79
@@ -97,7 +97,7 @@ index 1dd41aa..41778e1 100644
97 install-bin-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin)) 97 install-bin-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin))
98 install-bin-script-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin-script)) 98 install-bin-script-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin-script))
99 install-rootsbin-nosubdir: \ 99 install-rootsbin-nosubdir: \
100@@ -1240,6 +1273,10 @@ install-data-nosubdir: $(addprefix $(inst_datadir)/,$(install-data)) 100@@ -1221,6 +1254,10 @@ install-data-nosubdir: $(addprefix $(inst_datadir)/,$(install-data))
101 install-headers-nosubdir: $(addprefix $(inst_includedir)/,$(headers)) 101 install-headers-nosubdir: $(addprefix $(inst_includedir)/,$(headers))
102 install-others-nosubdir: $(install-others) 102 install-others-nosubdir: $(install-others)
103 install-others-programs-nosubdir: $(install-others-programs) 103 install-others-programs-nosubdir: $(install-others-programs)
@@ -108,7 +108,7 @@ index 1dd41aa..41778e1 100644
108 108
109 # We need all the `-nosubdir' targets so that `install' in the parent 109 # We need all the `-nosubdir' targets so that `install' in the parent
110 # doesn't depend on several things which each iterate over the subdirs. 110 # doesn't depend on several things which each iterate over the subdirs.
111@@ -1249,7 +1286,8 @@ install-%:: install-%-nosubdir ; 111@@ -1230,7 +1267,8 @@ install-%:: install-%-nosubdir ;
112 112
113 .PHONY: install install-no-libc.a-nosubdir 113 .PHONY: install install-no-libc.a-nosubdir
114 install-no-libc.a-nosubdir: install-headers-nosubdir install-data-nosubdir \ 114 install-no-libc.a-nosubdir: install-headers-nosubdir install-data-nosubdir \
@@ -119,5 +119,5 @@ index 1dd41aa..41778e1 100644
119 install-no-libc.a-nosubdir: install-bin-nosubdir install-bin-script-nosubdir \ 119 install-no-libc.a-nosubdir: install-bin-nosubdir install-bin-script-nosubdir \
120 install-rootsbin-nosubdir install-sbin-nosubdir \ 120 install-rootsbin-nosubdir install-sbin-nosubdir \
121-- 121--
1222.1.4 1222.6.4
123 123
diff --git a/meta/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch b/meta/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch
deleted file mode 100644
index 0514e282e6..0000000000
--- a/meta/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch
+++ /dev/null
@@ -1,16842 +0,0 @@
1From 2a5d7bcf0ff791c95ee1388772408a1bf4454694 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 01:33:49 +0000
4Subject: [PATCH 24/27] eglibc: Forward port eglibc options groups support
5
6Upstream-Status: Pending
7
8Signed-off-by: Khem Raj <raj.khem@gmail.com>
9---
10 Makeconfig | 20 +-
11 Makerules | 19 +
12 argp/Makefile | 2 +
13 argp/argp-fmtstream.c | 25 +-
14 argp/argp-help.c | 13 +-
15 argp/argp-namefrob.h | 2 +
16 catgets/Makefile | 17 +-
17 crypt/Makefile | 20 +-
18 crypt/crypt-entry.c | 13 +
19 crypt/crypt_common.c | 42 +
20 crypt/crypt_util.c | 18 -
21 csu/Makefile | 2 +
22 debug/Makefile | 41 +-
23 debug/segfault.c | 11 +-
24 debug/tst-chk1.c | 7 +
25 dlfcn/Makefile | 7 +-
26 elf/dl-support.c | 3 +
27 elf/rtld.c | 17 +-
28 extra-lib.mk | 6 +-
29 grp/Makefile | 5 +
30 hesiod/Makefile | 6 +-
31 iconv/Makefile | 7 +
32 iconv/gconv_db.c | 3 +
33 iconv/gconv_trans.c | 7 +
34 iconv/iconv_prog.c | 8 +
35 iconvdata/Makefile | 27 +-
36 include/netdb.h | 4 +
37 inet/Makefile | 22 +-
38 intl/Makefile | 3 +-
39 intl/dcigettext.c | 39 +-
40 io/Makefile | 18 +-
41 libidn/Makefile | 5 +-
42 libidn/toutf8.c | 11 +-
43 libio/Makefile | 66 +-
44 libio/__fpurge.c | 2 +-
45 libio/fileops.c | 10 +-
46 libio/iofwide.c | 26 +
47 libio/ioseekoff.c | 2 +-
48 libio/ioseekpos.c | 2 +-
49 libio/iosetbuffer.c | 4 +
50 libio/libioP.h | 18 +-
51 libio/wdummyfileops.c | 161 +
52 locale/C-ctype.c | 20 +
53 locale/Makefile | 41 +-
54 locale/catnames.c | 48 +
55 locale/dummy-setlocale.c | 33 +
56 locale/localeinfo.h | 2 +-
57 locale/programs/charmap-dir.c | 6 +
58 locale/programs/ld-collate.c | 17 +-
59 locale/programs/ld-ctype.c | 27 +-
60 locale/programs/ld-messages.c | 5 +
61 locale/programs/ld-time.c | 31 +-
62 locale/programs/linereader.c | 2 +-
63 locale/programs/localedef.c | 8 +
64 locale/programs/locfile.c | 5 +-
65 locale/programs/locfile.h | 59 +-
66 locale/setlocale.c | 30 -
67 locale/xlocale.c | 37 +
68 localedata/Makefile | 35 +-
69 login/Makefile | 17 +-
70 malloc/Makefile | 10 +-
71 malloc/memusage.c | 7 +-
72 malloc/memusage.sh | 2 +-
73 math/Makefile | 6 +-
74 misc/Makefile | 25 +-
75 misc/err.c | 11 +
76 misc/error.c | 5 +
77 misc/tst-efgcvt.c | 2 +-
78 nis/Makefile | 31 +-
79 nptl/Makefile | 28 +-
80 nptl/pthread_create.c | 5 +
81 nscd/Makefile | 33 +-
82 nscd/nis_hash.c | 3 +
83 nss/Makefile | 67 +-
84 nss/fixed-nsswitch.conf | 22 +
85 nss/fixed-nsswitch.functions | 121 +
86 nss/gen-fixed-nsswitch.c | 803 +++
87 nss/getent.c | 46 +-
88 nss/getnssent_r.c | 9 +-
89 nss/nsswitch.c | 109 +-
90 nss/nsswitch.h | 18 +-
91 posix/Makefile | 94 +-
92 posix/bug-regex1.c | 3 +
93 posix/bug-regex6.c | 8 +-
94 posix/fnmatch.c | 6 +-
95 posix/fnmatch_loop.c | 23 +-
96 posix/glob.c | 15 +-
97 posix/regcomp.c | 98 +-
98 posix/regex.h | 11 +
99 posix/regex_internal.c | 45 +-
100 posix/regex_internal.h | 23 +-
101 posix/regexec-compat.c | 39 +
102 posix/regexec.c | 71 +-
103 posix/xregex.c | 8215 +++++++++++++++++++++++++++++++
104 pwd/Makefile | 2 +
105 resolv/Makefile | 21 +-
106 stdio-common/Makefile | 35 +-
107 stdio-common/_i18n_number.h | 13 +
108 stdio-common/fxprintf.c | 5 +
109 stdio-common/printf_fp.c | 22 +
110 stdio-common/printf_fphex.c | 13 +
111 stdio-common/printf_size.c | 8 +
112 stdio-common/scanf14.c | 3 +
113 stdio-common/tst-popen.c | 3 +
114 stdio-common/tst-sprintf.c | 4 +-
115 stdio-common/tstdiomisc.c | 5 +
116 stdio-common/vfprintf.c | 31 +-
117 stdio-common/vfscanf.c | 53 +-
118 stdlib/Makefile | 34 +-
119 stdlib/strtod_l.c | 13 +
120 stdlib/tst-strtod.c | 5 +
121 streams/Makefile | 5 +-
122 string/Makefile | 14 +-
123 string/strcoll_l.c | 5 +
124 string/strerror_l.c | 5 +
125 string/strxfrm_l.c | 5 +
126 string/test-strcmp.c | 28 -
127 string/tst-strxfrm.c | 3 +
128 string/tst-strxfrm2.c | 3 +
129 sunrpc/Makefile | 44 +-
130 sysdeps/arm/Makefile | 5 +-
131 sysdeps/generic/ldsodefs.h | 8 +
132 sysdeps/gnu/Makefile | 3 +-
133 sysdeps/ieee754/ldbl-opt/Makefile | 27 +-
134 sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 40 +-
135 sysdeps/ieee754/ldbl-opt/nldbl-compat.h | 24 +-
136 sysdeps/nptl/Makefile | 3 +
137 sysdeps/nptl/bits/libc-lock.h | 45 +
138 sysdeps/nptl/bits/libc-lockP.h | 50 +-
139 sysdeps/nptl/small-macros-fns.c | 72 +
140 sysdeps/unix/sysv/linux/gethostid.c | 6 +
141 sysdeps/unix/sysv/linux/libc_fatal.c | 3 +
142 time/Makefile | 18 +-
143 time/strftime_l.c | 12 +-
144 time/strptime_l.c | 14 +-
145 timezone/Makefile | 2 +-
146 wcsmbs/Makefile | 27 +-
147 wcsmbs/wcsmbsload.c | 13 +
148 wctype/Makefile | 14 +-
149 139 files changed, 11363 insertions(+), 583 deletions(-)
150 create mode 100644 crypt/crypt_common.c
151 create mode 100644 libio/wdummyfileops.c
152 create mode 100644 locale/catnames.c
153 create mode 100644 locale/dummy-setlocale.c
154 create mode 100644 nscd/nis_hash.c
155 create mode 100644 nss/fixed-nsswitch.conf
156 create mode 100644 nss/fixed-nsswitch.functions
157 create mode 100644 nss/gen-fixed-nsswitch.c
158 create mode 100644 posix/regexec-compat.c
159 create mode 100644 posix/xregex.c
160 create mode 100644 sysdeps/nptl/small-macros-fns.c
161
162diff --git a/Makeconfig b/Makeconfig
163index f136b88..52dae8f 100644
164--- a/Makeconfig
165+++ b/Makeconfig
166@@ -609,7 +609,7 @@ elf-objpfx = $(common-objpfx)elf/
167 # and run on the build system, causes that program with those
168 # arguments to be run on the host for which the library is built.
169 ifndef test-wrapper
170-test-wrapper =
171+test-wrapper = $(cross-test-wrapper)
172 endif
173 # Likewise, but the name of the program is preceded by
174 # <variable>=<value> assignments for environment variables.
175@@ -1089,6 +1089,24 @@ libm = $(common-objpfx)math/libm.a
176 libmvec = $(common-objpfx)mathvec/libmvec.a
177 endif
178
179+# Generate a header file that #defines preprocessor symbols indicating
180+# which option groups are enabled. Note that the option-groups.config file
181+# may not exist at all.
182+before-compile += $(common-objpfx)gnu/option-groups.h
183+common-generated += gnu/option-groups.h gnu/option-groups.stmp
184+headers += gnu/option-groups.h
185+$(common-objpfx)gnu/option-groups.h: $(common-objpfx)gnu/option-groups.stmp; @:
186+$(common-objpfx)gnu/option-groups.stmp: \
187+ $(..)scripts/option-groups.awk \
188+ $(..)option-groups.defaults \
189+ $(wildcard $(common-objpfx)option-groups.config)
190+ $(make-target-directory)
191+ @rm -f ${@:stmp=T} $@
192+ LC_ALL=C $(AWK) -f $^ > ${@:stmp=T}
193+ $(move-if-change) ${@:stmp=T} ${@:stmp=h}
194+ touch $@
195+
196+
197 # These are the subdirectories containing the library source. The order
198 # is more or less arbitrary. The sorting step will take care of the
199 # dependencies.
200diff --git a/Makerules b/Makerules
201index f9ca3f5..1dd41aa 100644
202--- a/Makerules
203+++ b/Makerules
204@@ -456,6 +456,25 @@ define sed-remove-objpfx
205 endef
206 endif
207
208+# Include targets in the selected option groups.
209+aux += $(aux-y)
210+extra-libs += $(extra-libs-y)
211+extra-libs-others += $(extra-libs-others-y)
212+extra-objs += $(extra-objs-y)
213+install-bin += $(install-bin-y)
214+install-others += $(install-others-y)
215+install-sbin += $(install-sbin-y)
216+modules += $(modules-y)
217+others += $(others-y)
218+others-pie += $(others-pie-y)
219+routines += $(routines-y)
220+static-only-routines += $(static-only-routines-y)
221+sysdep_routines += $(sysdep_routines-y)
222+test-srcs += $(test-srcs-y)
223+tests += $(tests-y)
224+xtests += $(xtests-y)
225+
226+
227 # Modify the list of routines we build for different targets
228
229 ifeq (yes,$(build-shared))
230diff --git a/argp/Makefile b/argp/Makefile
231index 1a87629..f7c1e40 100644
232--- a/argp/Makefile
233+++ b/argp/Makefile
234@@ -18,6 +18,8 @@
235 #
236 # Makefile for argp.
237 #
238+include ../option-groups.mak
239+
240 subdir := argp
241
242 include ../Makeconfig
243diff --git a/argp/argp-fmtstream.c b/argp/argp-fmtstream.c
244index 2b845e0..c344e7b 100644
245--- a/argp/argp-fmtstream.c
246+++ b/argp/argp-fmtstream.c
247@@ -42,6 +42,7 @@
248 #ifdef _LIBC
249 # include <wchar.h>
250 # include <libio/libioP.h>
251+# include <gnu/option-groups.h>
252 # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
253 #endif
254
255@@ -100,7 +101,11 @@ __argp_fmtstream_free (argp_fmtstream_t fs)
256 __argp_fmtstream_update (fs);
257 if (fs->p > fs->buf)
258 {
259+#ifdef _LIBC
260 __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
261+#else
262+ fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
263+#endif
264 }
265 free (fs->buf);
266 free (fs);
267@@ -145,9 +150,17 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
268 size_t i;
269 for (i = 0; i < pad; i++)
270 {
271+#ifdef _LIBC
272 if (_IO_fwide (fs->stream, 0) > 0)
273- putwc_unlocked (L' ', fs->stream);
274+ {
275+#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
276+ putwc_unlocked (L' ', fs->stream);
277+#else
278+ abort ();
279+#endif
280+ }
281 else
282+#endif
283 putc_unlocked (' ', fs->stream);
284 }
285 }
286@@ -308,9 +321,17 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
287 *nl++ = ' ';
288 else
289 for (i = 0; i < fs->wmargin; ++i)
290+#ifdef _LIBC
291 if (_IO_fwide (fs->stream, 0) > 0)
292- putwc_unlocked (L' ', fs->stream);
293+ {
294+#ifdef OPTION_POSIX_WIDE_CHAR_DEVICE_IO
295+ putwc_unlocked (L' ', fs->stream);
296+#else
297+ abort ();
298+#endif
299+ }
300 else
301+#endif
302 putc_unlocked (' ', fs->stream);
303
304 /* Copy the tail of the original buffer into the current buffer
305diff --git a/argp/argp-help.c b/argp/argp-help.c
306index b055e45..6b3c4c1 100644
307--- a/argp/argp-help.c
308+++ b/argp/argp-help.c
309@@ -51,6 +51,7 @@ char *alloca ();
310 #ifdef _LIBC
311 # include <../libio/libioP.h>
312 # include <wchar.h>
313+# include <gnu/option-groups.h>
314 #endif
315
316 #ifndef _
317@@ -1702,7 +1703,7 @@ char *__argp_basename (char *name)
318 }
319
320 char *
321-__argp_short_program_name (void)
322+(__argp_short_program_name) (void)
323 {
324 # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
325 return program_invocation_short_name;
326@@ -1873,9 +1874,17 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
327 #endif
328 }
329
330+#ifdef _LIBC
331 if (_IO_fwide (stream, 0) > 0)
332- putwc_unlocked (L'\n', stream);
333+ {
334+#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
335+ putwc_unlocked (L'\n', stream);
336+#else
337+ abort ();
338+#endif
339+ }
340 else
341+#endif
342 putc_unlocked ('\n', stream);
343
344 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
345diff --git a/argp/argp-namefrob.h b/argp/argp-namefrob.h
346index f67c58f..e2002dc 100644
347--- a/argp/argp-namefrob.h
348+++ b/argp/argp-namefrob.h
349@@ -76,10 +76,12 @@
350 #undef __argp_fmtstream_wmargin
351 #define __argp_fmtstream_wmargin argp_fmtstream_wmargin
352
353+#if 0
354 #include "mempcpy.h"
355 #include "strcase.h"
356 #include "strchrnul.h"
357 #include "strndup.h"
358+#endif
359
360 /* normal libc functions we call */
361 #undef __flockfile
362diff --git a/catgets/Makefile b/catgets/Makefile
363index 4624a88..05714fd 100644
364--- a/catgets/Makefile
365+++ b/catgets/Makefile
366@@ -22,20 +22,23 @@ subdir := catgets
367
368 include ../Makeconfig
369
370+include ../option-groups.mak
371+
372 headers = nl_types.h
373-routines = catgets open_catalog
374-others = gencat
375-install-bin = gencat
376-extra-objs = $(gencat-modules:=.o)
377+routines-$(OPTION_EGLIBC_CATGETS) := catgets open_catalog
378+others-$(OPTION_EGLIBC_CATGETS) := gencat
379+install-bin-$(OPTION_EGLIBC_CATGETS) := gencat
380+extra-objs-$(OPTION_EGLIBC_CATGETS) := $(gencat-modules:=.o)
381
382-tests = tst-catgets
383-test-srcs = test-gencat
384+tests-$(OPTION_EGLIBC_CATGETS) := tst-catgets
385+test-srcs-$(OPTION_EGLIBC_CATGETS) := test-gencat
386
387+ifeq (y,$(OPTION_EGLIBC_CATGETS))
388 ifeq ($(run-built-tests),yes)
389 tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
390 $(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out
391 endif
392-
393+endif
394 gencat-modules = xmalloc
395
396 # To find xmalloc.c
397diff --git a/crypt/Makefile b/crypt/Makefile
398index 34c4dd7..7c18c88 100644
399--- a/crypt/Makefile
400+++ b/crypt/Makefile
401@@ -18,21 +18,25 @@
402 #
403 # Sub-makefile for crypt() portion of the library.
404 #
405+include ../option-groups.mak
406+
407 subdir := crypt
408
409 include ../Makeconfig
410
411 headers := crypt.h
412
413-extra-libs := libcrypt
414-extra-libs-others := $(extra-libs)
415+extra-libs-$(OPTION_EGLIBC_CRYPT) := libcrypt
416+extra-libs-others-y := $(extra-libs-y)
417
418-libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
419- crypt_util
420+libcrypt-routines :=crypt-entry md5-crypt sha256-crypt sha512-crypt crypt_common
421+libcrypt-routines-$(OPTION_EGLIBC_CRYPT_UFC) := crypt crypt_util
422+libcrypt-routines += $(libcrypt-routines-y)
423
424-tests := cert md5c-test sha256c-test sha512c-test badsalttest
425+tests-$(OPTION_EGLIBC_CRYPT) := md5c-test sha256c-test sha512c-test badsalttest
426+tests-$(OPTION_EGLIBC_CRYPT_UFC) += cert
427
428-ifeq ($(crypt-in-libc),yes)
429+ifeq ($(crypt-in-libc)$(OPTION_EGLIBC_CRYPT),yesy)
430 routines += $(libcrypt-routines)
431 endif
432
433@@ -44,7 +48,7 @@ LDLIBS-crypt.so = -lfreebl3
434 else
435 libcrypt-routines += md5 sha256 sha512
436
437-tests += md5test sha256test sha512test
438+tests-$(OPTION_EGLIBC_CRYPT) += md5test sha256test sha512test
439
440 # The test md5test-giant uses up to 400 MB of RSS and runs on a fast
441 # machine over a minute.
442@@ -64,8 +68,10 @@ $(objpfx)sha256test: $(patsubst %, $(objpfx)%.o,$(sha256-routines))
443 $(objpfx)sha512test: $(patsubst %, $(objpfx)%.o,$(sha512-routines))
444 endif
445
446+ifeq ($(OPTION_EGLIBC_CRYPT),y)
447 ifeq (yes,$(build-shared))
448 $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.so
449 else
450 $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.a
451 endif
452+endif # eglibc: OPTION_EGLIBC_CRYPT
453diff --git a/crypt/crypt-entry.c b/crypt/crypt-entry.c
454index 7e655ba..6ae5c2b 100644
455--- a/crypt/crypt-entry.c
456+++ b/crypt/crypt-entry.c
457@@ -27,6 +27,7 @@
458 #include <stdio.h>
459 #endif
460 #include <string.h>
461+#include <gnu/option-groups.h>
462 #include <errno.h>
463 #include <fips-private.h>
464
465@@ -76,9 +77,11 @@ __crypt_r (key, salt, data)
466 const char *salt;
467 struct crypt_data * __restrict data;
468 {
469+#if __OPTION_EGLIBC_CRYPT_UFC
470 ufc_long res[4];
471 char ktab[9];
472 ufc_long xx = 25; /* to cope with GCC long long compiler bugs */
473+#endif /*__OPTION_EGLIBC_CRYPT_UFC*/
474
475 #ifdef _LIBC
476 /* Try to find out whether we have to use MD5 encryption replacement. */
477@@ -105,6 +108,7 @@ __crypt_r (key, salt, data)
478 sizeof (struct crypt_data));
479 #endif
480
481+#if __OPTION_EGLIBC_CRYPT_UFC
482 /*
483 * Hack DES tables according to salt
484 */
485@@ -144,6 +148,10 @@ __crypt_r (key, salt, data)
486 */
487 _ufc_output_conversion_r (res[0], res[1], salt, data);
488 return data->crypt_3_buf;
489+#else /* __OPTION_EGLIBC_CRYPT_UFC */
490+ __set_errno (ENOSYS);
491+ return NULL;
492+#endif /* __OPTION_EGLIBC_CRYPT_UFC */
493 }
494 weak_alias (__crypt_r, crypt_r)
495
496@@ -168,7 +176,12 @@ crypt (key, salt)
497 return __sha512_crypt (key, salt);
498 #endif
499
500+#if __OPTION_EGLIBC_CRYPT_UFC
501 return __crypt_r (key, salt, &_ufc_foobar);
502+#else /* __OPTION_EGLIBC_CRYPT_UFC */
503+ __set_errno (ENOSYS);
504+ return NULL;
505+#endif /* __OPTION_EGLIBC_CRYPT_UFC */
506 }
507
508
509diff --git a/crypt/crypt_common.c b/crypt/crypt_common.c
510new file mode 100644
511index 0000000..cce6a31
512--- /dev/null
513+++ b/crypt/crypt_common.c
514@@ -0,0 +1,42 @@
515+/*
516+ * crypt: crypt(3) implementation
517+ *
518+ * Copyright (C) 1991-2014 Free Software Foundation, Inc.
519+ *
520+ * This library is free software; you can redistribute it and/or
521+ * modify it under the terms of the GNU Lesser General Public
522+ * License as published by the Free Software Foundation; either
523+ * version 2.1 of the License, or (at your option) any later version.
524+ *
525+ * This library is distributed in the hope that it will be useful,
526+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
527+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
528+ * Lesser General Public License for more details.
529+ *
530+ * You should have received a copy of the GNU Lesser General Public
531+ * License along with this library; see the file COPYING.LIB. If not,
532+ * see <http://www.gnu.org/licenses/>.
533+ *
534+ * General Support routines
535+ *
536+ */
537+
538+#include "crypt-private.h"
539+
540+/* Table with characters for base64 transformation. */
541+static const char b64t[64] =
542+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
543+
544+void
545+__b64_from_24bit (char **cp, int *buflen,
546+ unsigned int b2, unsigned int b1, unsigned int b0,
547+ int n)
548+{
549+ unsigned int w = (b2 << 16) | (b1 << 8) | b0;
550+ while (n-- > 0 && (*buflen) > 0)
551+ {
552+ *(*cp)++ = b64t[w & 0x3f];
553+ --(*buflen);
554+ w >>= 6;
555+ }
556+}
557diff --git a/crypt/crypt_util.c b/crypt/crypt_util.c
558index 1597885..9297974 100644
559--- a/crypt/crypt_util.c
560+++ b/crypt/crypt_util.c
561@@ -242,10 +242,6 @@ static ufc_long eperm32tab[4][256][2];
562 */
563 static ufc_long efp[16][64][2];
564
565-/* Table with characters for base64 transformation. */
566-static const char b64t[64] =
567-"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
568-
569 /*
570 * For use by the old, non-reentrant routines
571 * (crypt/encrypt/setkey)
572@@ -949,17 +945,3 @@ setkey(__key)
573 {
574 __setkey_r(__key, &_ufc_foobar);
575 }
576-
577-void
578-__b64_from_24bit (char **cp, int *buflen,
579- unsigned int b2, unsigned int b1, unsigned int b0,
580- int n)
581-{
582- unsigned int w = (b2 << 16) | (b1 << 8) | b0;
583- while (n-- > 0 && (*buflen) > 0)
584- {
585- *(*cp)++ = b64t[w & 0x3f];
586- --(*buflen);
587- w >>= 6;
588- }
589-}
590diff --git a/csu/Makefile b/csu/Makefile
591index 9f0855a..b1c3363 100644
592--- a/csu/Makefile
593+++ b/csu/Makefile
594@@ -22,6 +22,8 @@
595 # crtn.o, special "initializer" and "finalizer" files used in the link
596 # to make the .init and .fini sections work right.
597
598+include ../option-groups.mak
599+
600 subdir := csu
601
602 include ../Makeconfig
603diff --git a/debug/Makefile b/debug/Makefile
604index 9ff357b..d23d97d 100644
605--- a/debug/Makefile
606+++ b/debug/Makefile
607@@ -18,6 +18,8 @@
608 #
609 # Sub-makefile for debug portion of the library.
610 #
611+include ../option-groups.mak
612+
613 subdir := debug
614
615 include ../Makeconfig
616@@ -27,7 +29,7 @@ headers := execinfo.h
617 # Note that ptsname_r_chk and getlogin_r are not here, but in
618 # login/Makefile instead. If that subdir is omitted from the
619 # build, its _FORTIFY_SOURCE support will be too.
620-routines = backtrace backtracesyms backtracesymsfd noophooks \
621+routines = noophooks \
622 memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \
623 strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \
624 sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
625@@ -36,20 +38,27 @@ routines = backtrace backtracesyms backtracesymsfd noophooks \
626 read_chk pread_chk pread64_chk recv_chk recvfrom_chk \
627 readlink_chk readlinkat_chk getwd_chk getcwd_chk \
628 realpath_chk fread_chk fread_u_chk \
629- wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
630- wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
631- wcpncpy_chk \
632- swprintf_chk vswprintf_chk wprintf_chk fwprintf_chk \
633- vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk \
634 confstr_chk getgroups_chk ttyname_r_chk \
635- gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \
636- wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \
637- wcstombs_chk asprintf_chk vasprintf_chk dprintf_chk \
638+ gethostname_chk getdomainname_chk \
639+ asprintf_chk vasprintf_chk dprintf_chk \
640 vdprintf_chk obprintf_chk \
641 longjmp_chk ____longjmp_chk \
642 fdelt_chk poll_chk ppoll_chk \
643 stack_chk_fail fortify_fail \
644 $(static-only-routines)
645+routines-$(OPTION_EGLIBC_BACKTRACE) += backtrace backtracesyms backtracesymsfd
646+routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
647+ += wprintf_chk fwprintf_chk \
648+ vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk
649+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
650+ += wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
651+ wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
652+ wcpncpy_chk \
653+ swprintf_chk vswprintf_chk \
654+ wcrtomb_chk mbsnrtowcs_chk \
655+ wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \
656+ wcstombs_chk
657+
658 static-only-routines := warning-nop stack_chk_fail_local
659
660 CFLAGS-backtrace.c = -fno-omit-frame-pointer
661@@ -131,11 +140,15 @@ LDFLAGS-tst-backtrace4 = -rdynamic
662 LDFLAGS-tst-backtrace5 = -rdynamic
663 LDFLAGS-tst-backtrace6 = -rdynamic
664
665-tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
666- tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
667- tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \
668- tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \
669- tst-backtrace5 tst-backtrace6
670+tests = tst-longjmp_chk test-strcpy_chk test-stpcpy_chk tst-longjmp_chk2
671+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
672+ += tst-chk1 tst-chk2 tst-chk3 tst-lfschk1 tst-lfschk2 tst-lfschk3
673+tests-$(OPTION_EGLIBC_BACKTRACE) \
674+ += backtrace-tst tst-backtrace2 tst-backtrace3 tst-backtrace4 \
675+ tst-backtrace5 tst-backtrace6
676+ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_EGLIBC_CXX_TESTS))
677+tests += tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6
678+endif
679
680 ifeq (,$(CXX))
681 tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \
682diff --git a/debug/segfault.c b/debug/segfault.c
683index 3459a2a..ee9a146 100644
684--- a/debug/segfault.c
685+++ b/debug/segfault.c
686@@ -30,6 +30,7 @@
687 #include <unistd.h>
688 #include <_itoa.h>
689 #include <ldsodefs.h>
690+#include <gnu/option-groups.h>
691
692 /* This file defines macros to access the content of the sigcontext element
693 passed up by the signal handler. */
694@@ -68,11 +69,13 @@ write_strsignal (int fd, int signal)
695 static void
696 catch_segfault (int signal, SIGCONTEXT ctx)
697 {
698- int fd, cnt, i;
699- void **arr;
700+ int fd;
701 struct sigaction sa;
702+#if __OPTION_EGLIBC_BACKTRACE
703+ int cnt, i;
704+ void **arr;
705 uintptr_t pc;
706-
707+#endif
708 /* This is the name of the file we are writing to. If none is given
709 or we cannot write to this file write to stderr. */
710 fd = 2;
711@@ -91,6 +94,7 @@ catch_segfault (int signal, SIGCONTEXT ctx)
712 REGISTER_DUMP;
713 #endif
714
715+#if __OPTION_EGLIBC_BACKTRACE
716 WRITE_STRING ("\nBacktrace:\n");
717
718 /* Get the backtrace. */
719@@ -113,6 +117,7 @@ catch_segfault (int signal, SIGCONTEXT ctx)
720
721 /* Now generate nicely formatted output. */
722 __backtrace_symbols_fd (arr + i, cnt - i, fd);
723+#endif
724
725 #ifdef HAVE_PROC_SELF
726 /* Now the link map. */
727diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
728index 53559e6..362d92a 100644
729--- a/debug/tst-chk1.c
730+++ b/debug/tst-chk1.c
731@@ -31,6 +31,7 @@
732 #include <sys/select.h>
733 #include <sys/socket.h>
734 #include <sys/un.h>
735+#include <gnu/option-groups.h>
736
737
738 #define obstack_chunk_alloc malloc
739@@ -307,6 +308,7 @@ do_test (void)
740 snprintf (buf + 8, l0 + 3, "%d", num2);
741 CHK_FAIL_END
742
743+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
744 CHK_FAIL_START
745 swprintf (wbuf + 8, 3, L"%d", num1);
746 CHK_FAIL_END
747@@ -314,6 +316,7 @@ do_test (void)
748 CHK_FAIL_START
749 swprintf (wbuf + 8, l0 + 3, L"%d", num1);
750 CHK_FAIL_END
751+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
752 # endif
753
754 memcpy (buf, str1 + 2, l0 + 9);
755@@ -381,6 +384,7 @@ do_test (void)
756 CHK_FAIL_END
757 #endif
758
759+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
760
761 /* These ops can be done without runtime checking of object size. */
762 wmemcpy (wbuf, L"abcdefghij", 10);
763@@ -605,6 +609,7 @@ do_test (void)
764 CHK_FAIL_END
765 #endif
766
767+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
768
769 /* Now checks for %n protection. */
770
771@@ -1192,6 +1197,7 @@ do_test (void)
772 # endif
773 #endif
774
775+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
776 if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL)
777 {
778 assert (MB_CUR_MAX <= 10);
779@@ -1348,6 +1354,7 @@ do_test (void)
780 puts ("cannot set locale");
781 ret = 1;
782 }
783+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
784
785 int fd = posix_openpt (O_RDWR);
786 if (fd != -1)
787diff --git a/dlfcn/Makefile b/dlfcn/Makefile
788index 759780d..3827607 100644
789--- a/dlfcn/Makefile
790+++ b/dlfcn/Makefile
791@@ -15,6 +15,8 @@
792 # License along with the GNU C Library; if not, see
793 # <http://www.gnu.org/licenses/>.
794
795+include ../option-groups.mak
796+
797 subdir := dlfcn
798
799 include ../Makeconfig
800@@ -36,8 +38,11 @@ endif
801 ifeq (yes,$(build-shared))
802 tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
803 bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
804- bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen
805+ tstatexit bug-dl-leaf tst-rec-dlopen
806 endif
807+
808+tests-$(OPTION_EGLIBC_CXX_TESTS) += bug-atexit3
809+
810 modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
811 defaultmod2 errmsg1mod modatexit modcxaatexit \
812 bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \
813diff --git a/elf/dl-support.c b/elf/dl-support.c
814index 4d036f1..c15f405 100644
815--- a/elf/dl-support.c
816+++ b/elf/dl-support.c
817@@ -19,6 +19,7 @@
818 /* This file defines some things that for the dynamic linker are defined in
819 rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */
820
821+#include <gnu/option-groups.h>
822 #include <errno.h>
823 #include <libintl.h>
824 #include <stdlib.h>
825@@ -42,7 +43,9 @@ char **_dl_argv = &__progname; /* This is checked for some error messages. */
826 const char *_dl_platform;
827 size_t _dl_platformlen;
828
829+#if __OPTION_EGLIBC_RTLD_DEBUG
830 int _dl_debug_mask;
831+#endif
832 int _dl_lazy;
833 ElfW(Addr) _dl_use_load_bias = -2;
834 int _dl_dynamic_weak;
835diff --git a/elf/rtld.c b/elf/rtld.c
836index 6d3add7..fc3a2db 100644
837--- a/elf/rtld.c
838+++ b/elf/rtld.c
839@@ -16,6 +16,7 @@
840 License along with the GNU C Library; if not, see
841 <http://www.gnu.org/licenses/>. */
842
843+#include <gnu/option-groups.h>
844 #include <errno.h>
845 #include <dlfcn.h>
846 #include <fcntl.h>
847@@ -2201,6 +2202,7 @@ print_missing_version (int errcode __attribute__ ((unused)),
848 objname, errstring);
849 }
850
851+#if __OPTION_EGLIBC_RTLD_DEBUG
852 /* Nonzero if any of the debugging options is enabled. */
853 static int any_debug attribute_relro;
854
855@@ -2310,6 +2312,7 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
856 _exit (0);
857 }
858 }
859+#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
860
861 static void
862 process_dl_audit (char *str)
863@@ -2349,8 +2352,9 @@ process_envvars (enum mode *modep)
864 char **runp = _environ;
865 char *envline;
866 enum mode mode = normal;
867+#if __OPTION_EGLIBC_RTLD_DEBUG
868 char *debug_output = NULL;
869-
870+#endif
871 /* This is the default place for profiling data file. */
872 GLRO(dl_profile_output)
873 = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
874@@ -2377,12 +2381,14 @@ process_envvars (enum mode *modep)
875 break;
876
877 case 5:
878+#if __OPTION_EGLIBC_RTLD_DEBUG
879 /* Debugging of the dynamic linker? */
880 if (memcmp (envline, "DEBUG", 5) == 0)
881 {
882 process_dl_debug (&envline[6]);
883 break;
884 }
885+#endif
886 if (memcmp (envline, "AUDIT", 5) == 0)
887 process_dl_audit (&envline[6]);
888 break;
889@@ -2448,13 +2454,14 @@ process_envvars (enum mode *modep)
890 break;
891 }
892
893+#if __OPTION_EGLIBC_RTLD_DEBUG
894 /* Where to place the profiling data file. */
895 if (memcmp (envline, "DEBUG_OUTPUT", 12) == 0)
896 {
897 debug_output = &envline[13];
898 break;
899 }
900-
901+#endif
902 if (!__libc_enable_secure
903 && memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
904 GLRO(dl_dynamic_weak) = 1;
905@@ -2491,7 +2498,9 @@ process_envvars (enum mode *modep)
906 {
907 mode = trace;
908 GLRO(dl_verbose) = 1;
909+#if __OPTION_EGLIBC_RTLD_DEBUG
910 GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
911+#endif
912 GLRO(dl_trace_prelink) = &envline[17];
913 }
914 break;
915@@ -2538,12 +2547,15 @@ process_envvars (enum mode *modep)
916 if (__access ("/etc/suid-debug", F_OK) != 0)
917 {
918 unsetenv ("MALLOC_CHECK_");
919+#if __OPTION_EGLIBC_RTLD_DEBUG
920 GLRO(dl_debug_mask) = 0;
921+#endif
922 }
923
924 if (mode != normal)
925 _exit (5);
926 }
927+#if __OPTION_EGLIBC_RTLD_DEBUG
928 /* If we have to run the dynamic linker in debugging mode and the
929 LD_DEBUG_OUTPUT environment variable is given, we write the debug
930 messages to this file. */
931@@ -2568,6 +2580,7 @@ process_envvars (enum mode *modep)
932 /* We use standard output if opening the file failed. */
933 GLRO(dl_debug_fd) = STDOUT_FILENO;
934 }
935+#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
936 }
937
938
939diff --git a/extra-lib.mk b/extra-lib.mk
940index b10748d..d71a06f 100644
941--- a/extra-lib.mk
942+++ b/extra-lib.mk
943@@ -25,7 +25,9 @@ install-lib := $(install-lib)
944 extra-objs := $(extra-objs)
945
946 # The modules that go in $(lib).
947-all-$(lib)-routines := $($(lib)-routines) $($(lib)-sysdep_routines)
948+all-$(lib)-routines := $($(lib)-routines) \
949+ $($(lib)-routines-y) \
950+ $($(lib)-sysdep_routines)
951
952 # Add each flavor of library to the lists of things to build and install.
953 install-lib += $(foreach o,$(object-suffixes-$(lib)),$(lib:lib%=$(libtype$o)))
954@@ -101,7 +103,7 @@ endif
955 endif
956
957 # This will define `libof-ROUTINE := LIB' for each of the routines.
958-cpp-srcs-left := $($(lib)-routines) $($(lib)-sysdep_routines)
959+cpp-srcs-left := $(all-$(lib)-routines)
960 ifneq (,$(cpp-srcs-left))
961 include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
962 endif
963diff --git a/grp/Makefile b/grp/Makefile
964index c63b552..7486f32 100644
965--- a/grp/Makefile
966+++ b/grp/Makefile
967@@ -18,6 +18,8 @@
968 #
969 # Sub-makefile for grp portion of the library.
970 #
971+include ../option-groups.mak
972+
973 subdir := grp
974
975 include ../Makeconfig
976@@ -29,6 +31,9 @@ routines := fgetgrent initgroups setgroups \
977 getgrent_r getgrgid_r getgrnam_r fgetgrent_r
978
979 tests := testgrp
980+ifneq (y,$(OPTION_EGLIBC_NSSWITCH))
981+LDLIBS-testgrp += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
982+endif
983
984 ifeq (yes,$(build-shared))
985 test-srcs := tst_fgetgrent
986diff --git a/hesiod/Makefile b/hesiod/Makefile
987index ac0bc01..38263b4 100644
988--- a/hesiod/Makefile
989+++ b/hesiod/Makefile
990@@ -18,12 +18,14 @@
991 #
992 # Sub-makefile for hesiod portion of the library.
993 #
994+include ../option-groups.mak
995+
996 subdir := hesiod
997
998 include ../Makeconfig
999
1000-extra-libs := libnss_hesiod
1001-extra-libs-others = $(extra-libs)
1002+extra-libs-$(OPTION_EGLIBC_INET) += libnss_hesiod
1003+extra-libs-others-y += $(extra-libs-y)
1004
1005 subdir-dirs = nss_hesiod
1006 vpath %.c nss_hesiod
1007diff --git a/iconv/Makefile b/iconv/Makefile
1008index 0d55eda..a1847c6 100644
1009--- a/iconv/Makefile
1010+++ b/iconv/Makefile
1011@@ -18,6 +18,8 @@
1012 #
1013 # Makefile for iconv.
1014 #
1015+include ../option-groups.mak
1016+
1017 subdir := iconv
1018
1019 include ../Makeconfig
1020@@ -39,6 +41,11 @@ CFLAGS-iconv_charmap.c = -I../locale/programs
1021 CFLAGS-dummy-repertoire.c = -I../locale/programs
1022 CFLAGS-charmap.c = -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \
1023 -DDEFAULT_CHARMAP=null_pointer -DNEED_NULL_POINTER
1024+
1025+ifneq (y,$(OPTION_EGLIBC_SPAWN))
1026+CFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
1027+endif
1028+
1029 CFLAGS-linereader.c = -DNO_TRANSLITERATION
1030 CFLAGS-simple-hash.c = -I../locale
1031
1032diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c
1033index ce46216..ea18964 100644
1034--- a/iconv/gconv_db.c
1035+++ b/iconv/gconv_db.c
1036@@ -25,6 +25,7 @@
1037 #include <sys/param.h>
1038 #include <bits/libc-lock.h>
1039 #include <locale/localeinfo.h>
1040+#include <gnu/option-groups.h>
1041
1042 #include <dlfcn.h>
1043 #include <gconv_int.h>
1044@@ -828,9 +829,11 @@ free_modules_db (struct gconv_module *node)
1045 /* Free all resources if necessary. */
1046 libc_freeres_fn (free_mem)
1047 {
1048+#if __OPTION_EGLIBC_LOCALE_CODE
1049 /* First free locale memory. This needs to be done before freeing derivations,
1050 as ctype cleanup functions dereference steps arrays which we free below. */
1051 _nl_locale_subfreeres ();
1052+#endif
1053
1054 /* finddomain.c has similar problem. */
1055 extern void _nl_finddomain_subfreeres (void) attribute_hidden;
1056diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
1057index 5d5d4d7..a7d3072 100644
1058--- a/iconv/gconv_trans.c
1059+++ b/iconv/gconv_trans.c
1060@@ -23,6 +23,7 @@
1061 #include <stdint.h>
1062 #include <string.h>
1063 #include <stdlib.h>
1064+#include <gnu/option-groups.h>
1065
1066 #include <bits/libc-lock.h>
1067 #include "gconv_int.h"
1068@@ -38,15 +39,19 @@ __gconv_transliterate (struct __gconv_step *step,
1069 unsigned char **outbufstart, size_t *irreversible)
1070 {
1071 /* Find out about the locale's transliteration. */
1072+#if __OPTION_EGLIBC_LOCALE_CODE
1073 uint_fast32_t size;
1074 const uint32_t *from_idx;
1075 const uint32_t *from_tbl;
1076 const uint32_t *to_idx;
1077 const uint32_t *to_tbl;
1078+#endif
1079 const uint32_t *winbuf;
1080 const uint32_t *winbufend;
1081+#if __OPTION_EGLIBC_LOCALE_CODE
1082 uint_fast32_t low;
1083 uint_fast32_t high;
1084+#endif
1085
1086 /* The input buffer. There are actually 4-byte values. */
1087 winbuf = (const uint32_t *) *inbufp;
1088@@ -58,6 +63,7 @@ __gconv_transliterate (struct __gconv_step *step,
1089 PTR_DEMANGLE (fct);
1090 #endif
1091
1092+#if __OPTION_EGLIBC_LOCALE_CODE
1093 /* If there is no transliteration information in the locale don't do
1094 anything and return the error. */
1095 size = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_TAB_SIZE);
1096@@ -193,6 +199,7 @@ __gconv_transliterate (struct __gconv_step *step,
1097 sorted. */
1098 break;
1099 }
1100+#endif
1101
1102 /* One last chance: use the default replacement. */
1103 if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN) != 0)
1104diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
1105index e249bce..403ece5 100644
1106--- a/iconv/iconv_prog.c
1107+++ b/iconv/iconv_prog.c
1108@@ -35,6 +35,7 @@
1109 #ifdef _POSIX_MAPPED_FILES
1110 # include <sys/mman.h>
1111 #endif
1112+#include <gnu/option-groups.h>
1113 #include <charmap.h>
1114 #include <gconv_int.h>
1115 #include "iconv_prog.h"
1116@@ -221,10 +222,17 @@ main (int argc, char *argv[])
1117 bool to_wrong =
1118 (iconv_open (to_code, "UTF-8") == (iconv_t) -1
1119 && errno == EINVAL);
1120+#if __OPTION_EGLIBC_LOCALE_CODE
1121 const char *from_pretty =
1122 (from_code[0] ? from_code : nl_langinfo (CODESET));
1123 const char *to_pretty =
1124 (orig_to_code[0] ? orig_to_code : nl_langinfo (CODESET));
1125+#else
1126+ const char *from_pretty =
1127+ (from_code[0] ? from_code : "ANSI_X3.4-1968");
1128+ const char *to_pretty =
1129+ (orig_to_code[0] ? orig_to_code : "ANSI_X3.4-1968");
1130+#endif
1131
1132 if (from_wrong)
1133 {
1134diff --git a/iconvdata/Makefile b/iconvdata/Makefile
1135index a3d1d09..0832708 100644
1136--- a/iconvdata/Makefile
1137+++ b/iconvdata/Makefile
1138@@ -18,12 +18,15 @@
1139 #
1140 # Makefile for iconv data and code.
1141 #
1142+include ../option-groups.mak
1143+
1144 subdir := iconvdata
1145
1146 include ../Makeconfig
1147
1148 # Names of all the shared objects which implement the transformations.
1149-modules := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
1150+modules-$(OPTION_EGLIBC_CHARSETS) \
1151+ := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
1152 ISO8859-6 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-10 \
1153 ISO8859-11 ISO8859-13 ISO8859-14 ISO8859-15 ISO8859-16 \
1154 T.61 ISO_6937 SJIS KOI-8 HP-ROMAN8 HP-ROMAN9 EBCDIC-AT-DE \
1155@@ -63,11 +66,13 @@ modules := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
1156 MAC-CENTRALEUROPE KOI8-RU ISO8859-9E \
1157 CP770 CP771 CP772 CP773 CP774
1158
1159-modules.so := $(addsuffix .so, $(modules))
1160+modules.so := $(addsuffix .so, $(modules-y))
1161
1162 ifeq (yes,$(build-shared))
1163 tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
1164- tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9
1165+ tst-iconv6 bug-iconv5 bug-iconv8 bug-iconv9
1166+tests-$(OPTION_EGLIBC_LOCALE_CODE) += bug-iconv6 tst-iconv7
1167+
1168 ifeq ($(have-thread-library),yes)
1169 tests += bug-iconv3
1170 endif
1171@@ -127,13 +132,13 @@ ifeq (yes,$(build-shared))
1172 # Rule to generate the shared objects.
1173 charmaps = ../localedata/charmaps
1174 -include $(objpfx)iconv-rules
1175-extra-modules-left := $(modules)
1176+extra-modules-left := $(modules-y)
1177 include extra-module.mk
1178
1179
1180 extra-objs += $(modules.so)
1181-install-others = $(addprefix $(inst_gconvdir)/, $(modules.so)) \
1182- $(inst_gconvdir)/gconv-modules
1183+install-others-y += $(addprefix $(inst_gconvdir)/, $(modules.so))
1184+install-others-$(OPTION_EGLIBC_CHARSETS) += $(inst_gconvdir)/gconv-modules
1185
1186 # We can build the conversion tables for numerous charsets automatically.
1187
1188@@ -201,7 +206,7 @@ before-compile += $(addprefix $(objpfx),$(generated-modules:=.h))
1189 ifndef avoid-generated
1190 $(objpfx)iconv-rules: Makefile
1191 $(make-target-directory)
1192- { echo $(filter-out lib%, $(modules)); \
1193+ { echo $(filter-out lib%, $(modules-y)); \
1194 echo 8bit $(gen-8bit-modules); \
1195 echo 8bit-gap $(gen-8bit-gap-modules); } | \
1196 LC_ALL=C \
1197@@ -245,7 +250,7 @@ $(addprefix $(inst_gconvdir)/, $(modules.so)): \
1198 $(do-install-program)
1199 $(inst_gconvdir)/gconv-modules: gconv-modules $(+force)
1200 $(do-install)
1201-ifeq (no,$(cross-compiling))
1202+# eglibc: ifeq (no,$(cross-compiling))
1203 # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary
1204 # if this libc has more gconv modules than the previously installed one.
1205 if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \
1206@@ -254,9 +259,9 @@ ifeq (no,$(cross-compiling))
1207 $(common-objpfx)iconv/iconvconfig \
1208 $(addprefix --prefix=,$(install_root)); \
1209 fi
1210-else
1211- @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
1212-endif
1213+# eglibc: else
1214+# eglibc: @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
1215+# eglibc: endif
1216
1217 endif # build-shared = yes
1218
1219diff --git a/include/netdb.h b/include/netdb.h
1220index e1f051d..f6d15aa 100644
1221--- a/include/netdb.h
1222+++ b/include/netdb.h
1223@@ -232,6 +232,10 @@ extern enum nss_status _nss_ ## service ## _gethostbyname2_r \
1224 (const char *name, int af, struct hostent *host, \
1225 char *buffer, size_t buflen, int *errnop, \
1226 int *h_errnop); \
1227+extern enum nss_status _nss_ ## service ## _gethostbyname3_r \
1228+ (const char *name, int af, struct hostent *result, \
1229+ char *buffer, size_t buflen, int *errnop, \
1230+ int *h_errnop, int32_t *ttlp, char **canonp); \
1231 extern enum nss_status _nss_ ## service ## _gethostbyname_r \
1232 (const char *name, struct hostent *host, char *buffer, \
1233 size_t buflen, int *errnop, int *h_errnop); \
1234diff --git a/inet/Makefile b/inet/Makefile
1235index f1d871f..7cb1709 100644
1236--- a/inet/Makefile
1237+++ b/inet/Makefile
1238@@ -18,6 +18,8 @@
1239 #
1240 # Sub-makefile for inet portion of the library.
1241 #
1242+include ../option-groups.mak
1243+
1244 subdir := inet
1245
1246 include ../Makeconfig
1247@@ -27,7 +29,8 @@ headers := netinet/ether.h netinet/in.h netinet/in_systm.h \
1248 netinet/tcp.h netinet/ip.h $(wildcard arpa/*.h protocols/*.h) \
1249 aliases.h ifaddrs.h netinet/ip6.h netinet/icmp6.h bits/in.h
1250
1251-routines := htonl htons \
1252+routines-$(OPTION_EGLIBC_INET) \
1253+ += htonl htons \
1254 inet_lnaof inet_mkadr \
1255 inet_netof inet_ntoa inet_net herrno herrno-loc \
1256 gethstbyad gethstbyad_r gethstbynm gethstbynm2 gethstbynm2_r \
1257@@ -39,18 +42,23 @@ routines := htonl htons \
1258 getservent_r \
1259 ether_aton ether_aton_r ether_hton ether_line \
1260 ether_ntoa ether_ntoa_r ether_ntoh \
1261- rcmd rexec ruserpass \
1262 getnetgrent_r getnetgrent \
1263- getaliasent_r getaliasent getaliasname getaliasname_r \
1264- in6_addr getnameinfo if_index ifaddrs inet6_option \
1265+ in6_addr getnameinfo if_index ifaddrs \
1266 getipv4sourcefilter setipv4sourcefilter \
1267- getsourcefilter setsourcefilter inet6_opt inet6_rth
1268+ getsourcefilter setsourcefilter
1269+routines-$(OPTION_EGLIBC_RCMD) \
1270+ += rcmd rexec ruserpass
1271+routines-$(OPTION_EGLIBC_DB_ALIASES) \
1272+ += getaliasent_r getaliasent getaliasname getaliasname_r
1273+routines-$(OPTION_EGLIBC_ADVANCED_INET6) \
1274+ += inet6_option inet6_opt inet6_rth
1275
1276-aux := check_pf check_native ifreq
1277+aux-$(OPTION_EGLIBC_INET) += check_pf check_native ifreq
1278
1279 tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
1280- tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
1281+ tst-gethnm test-ifaddrs bug-if1 tst-ether_line \
1282 tst-getni1 tst-getni2 tst-inet6_rth tst-checks
1283+tests-$(OPTION_EGLIBC_ADVANCED_INET6) += test-inet6_opt
1284
1285 include ../Rules
1286
1287diff --git a/intl/Makefile b/intl/Makefile
1288index 9ecf8fe..587bc0d 100644
1289--- a/intl/Makefile
1290+++ b/intl/Makefile
1291@@ -16,6 +16,7 @@
1292 # <http://www.gnu.org/licenses/>.
1293
1294 # Makefile for intl subdirectory: message handling code from GNU gettext.
1295+include ../option-groups.mak
1296
1297 subdir = intl
1298
1299@@ -48,7 +49,7 @@ endif
1300 $(objpfx)plural.o: plural.c
1301
1302 ifeq ($(run-built-tests),yes)
1303-ifeq (yes,$(build-shared))
1304+ifeq (yyyes,$(OPTION_EGLIBC_LOCALES)$(OPTION_EGLIBC_LOCALE_CODE)$(build-shared))
1305 ifneq ($(strip $(MSGFMT)),:)
1306 tests-special += $(objpfx)tst-translit.out $(objpfx)tst-gettext.out \
1307 $(objpfx)tst-gettext2.out $(objpfx)tst-codeset.out \
1308diff --git a/intl/dcigettext.c b/intl/dcigettext.c
1309index 8a3f091..e271648 100644
1310--- a/intl/dcigettext.c
1311+++ b/intl/dcigettext.c
1312@@ -100,11 +100,15 @@ extern int errno;
1313 # include "libgnuintl.h"
1314 #endif
1315 #include "hash-string.h"
1316+#ifdef _LIBC
1317+# include <gnu/option-groups.h>
1318+#endif
1319
1320 /* Handle multi-threaded applications. */
1321 #ifdef _LIBC
1322 # include <bits/libc-lock.h>
1323 # define gl_rwlock_define_initialized __libc_rwlock_define_initialized
1324+# define gl_rwlock_define __libc_rwlock_define
1325 # define gl_rwlock_rdlock __libc_rwlock_rdlock
1326 # define gl_rwlock_wrlock __libc_rwlock_wrlock
1327 # define gl_rwlock_unlock __libc_rwlock_unlock
1328@@ -523,8 +527,10 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
1329 saved_errno = errno;
1330
1331 #ifdef _LIBC
1332- __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
1333- __libc_rwlock_rdlock (__libc_setlocale_lock);
1334+# if __OPTION_EGLIBC_LOCALE_CODE
1335+ gl_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
1336+ gl_rwlock_rdlock (__libc_setlocale_lock);
1337+# endif
1338 #endif
1339
1340 gl_rwlock_rdlock (_nl_state_lock);
1341@@ -550,7 +556,11 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
1342 #ifdef HAVE_PER_THREAD_LOCALE
1343 # ifndef IN_LIBGLOCALE
1344 # ifdef _LIBC
1345- localename = strdupa (__current_locale_name (category));
1346+# if __OPTION_EGLIBC_LOCALE_CODE
1347+ localename = strdupa (__current_locale_name (category));
1348+# else
1349+ localename = "C";
1350+# endif
1351 # else
1352 categoryname = category_to_name (category);
1353 # define CATEGORYNAME_INITIALIZED
1354@@ -581,10 +591,12 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
1355 else
1356 retval = (char *) (*foundp)->translation;
1357
1358- gl_rwlock_unlock (_nl_state_lock);
1359 # ifdef _LIBC
1360- __libc_rwlock_unlock (__libc_setlocale_lock);
1361+# if __OPTION_EGLIBC_LOCALE_CODE
1362+ gl_rwlock_unlock (__libc_setlocale_lock);
1363+# endif
1364 # endif
1365+ gl_rwlock_unlock (_nl_state_lock);
1366 __set_errno (saved_errno);
1367 return retval;
1368 }
1369@@ -838,10 +850,13 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
1370 if (plural)
1371 retval = plural_lookup (domain, n, retval, retlen);
1372
1373- gl_rwlock_unlock (_nl_state_lock);
1374 #ifdef _LIBC
1375- __libc_rwlock_unlock (__libc_setlocale_lock);
1376+# if __OPTION_EGLIBC_LOCALE_CODE
1377+
1378+ gl_rwlock_unlock (__libc_setlocale_lock);
1379+# endif
1380 #endif
1381+ gl_rwlock_unlock (_nl_state_lock);
1382 return retval;
1383 }
1384 }
1385@@ -850,10 +865,12 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
1386 return_untranslated:
1387 /* Return the untranslated MSGID. */
1388 FREE_BLOCKS (block_list);
1389- gl_rwlock_unlock (_nl_state_lock);
1390 #ifdef _LIBC
1391- __libc_rwlock_unlock (__libc_setlocale_lock);
1392+# if __OPTION_EGLIBC_LOCALE_CODE
1393+ gl_rwlock_unlock (__libc_setlocale_lock);
1394+# endif
1395 #endif
1396+ gl_rwlock_unlock (_nl_state_lock);
1397 #ifndef _LIBC
1398 if (!ENABLE_SECURE)
1399 {
1400@@ -1550,7 +1567,11 @@ guess_category_value (int category, const char *categoryname)
1401 `LC_xxx', and `LANG'. On some systems this can be done by the
1402 `setlocale' function itself. */
1403 # ifdef _LIBC
1404+# if __OPTION_EGLIBC_LOCALE_CODE
1405 locale = __current_locale_name (category);
1406+# else
1407+ locale = "C";
1408+# endif
1409 # else
1410 locale_defaulted = 0;
1411 # if HAVE_USELOCALE
1412diff --git a/io/Makefile b/io/Makefile
1413index 613dce0..697439e 100644
1414--- a/io/Makefile
1415+++ b/io/Makefile
1416@@ -18,6 +18,8 @@
1417 #
1418 # Sub-makefile for I/O portion of the library.
1419 #
1420+include ../option-groups.mak
1421+
1422 subdir := io
1423
1424 include ../Makeconfig
1425@@ -36,7 +38,7 @@ routines := \
1426 fxstatat fxstatat64 \
1427 statfs fstatfs statfs64 fstatfs64 \
1428 statvfs fstatvfs statvfs64 fstatvfs64 \
1429- umask chmod fchmod lchmod fchmodat \
1430+ umask chmod fchmod fchmodat \
1431 mkdir mkdirat \
1432 open open_2 open64 open64_2 openat openat_2 openat64 openat64_2 \
1433 read write lseek lseek64 access euidaccess faccessat \
1434@@ -49,11 +51,13 @@ routines := \
1435 ttyname ttyname_r isatty \
1436 link linkat symlink symlinkat readlink readlinkat \
1437 unlink unlinkat rmdir \
1438- ftw ftw64 fts poll ppoll \
1439+ poll ppoll \
1440 posix_fadvise posix_fadvise64 \
1441 posix_fallocate posix_fallocate64 \
1442 sendfile sendfile64 \
1443 utimensat futimens
1444+routines-$(OPTION_EGLIBC_BSD) += lchmod
1445+routines-$(OPTION_EGLIBC_FTRAVERSE) += ftw ftw64 fts
1446
1447 aux := have_o_cloexec
1448
1449@@ -64,18 +68,22 @@ static-only-routines = stat fstat lstat stat64 fstat64 lstat64 \
1450 fstatat fstatat64 mknod mknodat
1451
1452 others := pwd
1453-test-srcs := ftwtest
1454+test-srcs-$(OPTION_EGLIBC_FTRAVERSE) := ftwtest
1455 tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
1456- tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 tst-statvfs \
1457+ tst-fcntl tst-statvfs \
1458 tst-openat tst-unlinkat tst-fstatat tst-futimesat \
1459 tst-renameat tst-fchownat tst-fchmodat tst-faccessat \
1460 tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
1461- tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \
1462+ tst-mknodat tst-mkfifoat tst-ttyname_r \
1463 tst-posix_fallocate
1464+tests-$(OPTION_EGLIBC_FTRAVERSE) += bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 \
1465+ bug-ftw5
1466
1467 ifeq ($(run-built-tests),yes)
1468+ifeq (y,$(OPTION_EGLIBC_FTRAVERSE))
1469 tests-special += $(objpfx)ftwtest.out
1470 endif
1471+endif
1472
1473 include ../Rules
1474
1475diff --git a/libidn/Makefile b/libidn/Makefile
1476index 940fa52..43aad0c 100644
1477--- a/libidn/Makefile
1478+++ b/libidn/Makefile
1479@@ -16,6 +16,7 @@
1480 # <http://www.gnu.org/licenses/>.
1481
1482 # Makefile for libidn subdirectory of GNU C Library.
1483+include ../option-groups.mak
1484
1485 subdir := libidn
1486
1487@@ -23,8 +24,8 @@ include ../Makeconfig
1488
1489 routines = idn-stub
1490
1491-extra-libs = libcidn
1492-extra-libs-others = $(extra-libs)
1493+extra-libs-$(OPTION_EGLIBC_IDN) = libcidn
1494+extra-libs-others-y = $(extra-libs-y)
1495
1496 libcidn-routines := punycode toutf8 nfkc stringprep rfc3454 profiles idna \
1497 iconvme
1498diff --git a/libidn/toutf8.c b/libidn/toutf8.c
1499index c7e67ca..62df478 100644
1500--- a/libidn/toutf8.c
1501+++ b/libidn/toutf8.c
1502@@ -33,6 +33,11 @@
1503 /* Get strlen. */
1504 #include <string.h>
1505
1506+/* Get __OPTION_EGLIBC_LOCALE_CODE. */
1507+#ifdef _LIBC
1508+# include <gnu/option-groups.h>
1509+#endif
1510+
1511 /* Get iconv_string. */
1512 #include "iconvme.h"
1513
1514@@ -47,7 +52,11 @@
1515 #endif
1516
1517 #ifdef _LIBC
1518-# define stringprep_locale_charset() nl_langinfo (CODESET)
1519+# if __OPTION_EGLIBC_LOCALE_CODE
1520+# define stringprep_locale_charset() nl_langinfo (CODESET)
1521+# else
1522+# define stringprep_locale_charset() "ANSI_X3.4-1968"
1523+# endif
1524 #else
1525 /**
1526 * stringprep_locale_charset - return charset used in current locale
1527diff --git a/libio/Makefile b/libio/Makefile
1528index 7b3bcf9..27c9186 100644
1529--- a/libio/Makefile
1530+++ b/libio/Makefile
1531@@ -18,6 +18,8 @@
1532 #
1533 # Specific makefile for libio.
1534 #
1535+include ../option-groups.mak
1536+
1537 subdir := libio
1538
1539 include ../Makeconfig
1540@@ -27,16 +29,13 @@ headers := stdio.h libio.h _G_config.h bits/stdio.h bits/stdio-lock.h \
1541
1542 routines := \
1543 filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen \
1544- iofopncook iofputs iofread iofsetpos ioftell wfiledoalloc \
1545+ iofopncook iofputs iofread iofsetpos ioftell \
1546 iofwrite iogetdelim iogetline iogets iopadn iopopen ioputs \
1547 ioseekoff ioseekpos iosetbuffer iosetvbuf ioungetc \
1548 iovsprintf iovsscanf \
1549 iofgetpos64 iofopen64 iofsetpos64 \
1550- fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
1551- iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u \
1552- putwchar putwchar_u putchar putchar_u fwprintf swprintf vwprintf \
1553- wprintf wscanf fwscanf vwscanf vswprintf iovswscanf swscanf wgenops \
1554- wstrops wfileops iofwide fwide wmemstream \
1555+ putchar putchar_u \
1556+ iofwide \
1557 \
1558 clearerr feof ferror fileno fputc freopen fseek getc getchar \
1559 memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \
1560@@ -48,24 +47,49 @@ routines := \
1561 \
1562 libc_fatal fmemopen oldfmemopen
1563
1564-tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
1565- tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \
1566- tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf \
1567- tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof \
1568- tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \
1569+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += \
1570+ wfiledoalloc \
1571+ iowpadn \
1572+ swprintf \
1573+ vswprintf iovswscanf swscanf wgenops \
1574+ wstrops wfileops wmemstream
1575+routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) += \
1576+ wdummyfileops
1577+routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += \
1578+ fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
1579+ iofputws iofputws_u iogetwline ioungetwc putwc putwc_u \
1580+ putwchar putwchar_u fwprintf vwprintf \
1581+ wprintf wscanf fwscanf vwscanf \
1582+ fwide
1583+
1584+tests = test-fmemopen tst-ext tst-ext2 \
1585+ tst-mmap-setvbuf tst-atime tst-eof \
1586+ tst-freopen bug-ungetc bug-fseek \
1587 tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \
1588- tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \
1589- bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4 tst-fopenloc2 \
1590+ tst-mmap2-eofsync tst-mmap-offend bug-fopena+ \
1591+ bug-ungetc2 bug-ungetc3 bug-ungetc4 \
1592 tst-memstream1 tst-memstream2 \
1593- tst-wmemstream1 tst-wmemstream2 \
1594- bug-memstream1 bug-wmemstream1 \
1595- tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
1596- tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
1597- tst-ftell-append tst-fputws
1598+ bug-memstream1 tst-popen1 tst-fwrite-error \
1599+ tst-ftell-active-handler tst-ftell-append
1600+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
1601+ += tst-swscanf tst-fgetws tst-setvbuf1 \
1602+ tst-ungetwc1 tst-ungetwc2 bug-ftell bug-ungetwc2 \
1603+ tst-widetext tst-fputws
1604+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
1605+ += bug-rewind bug-rewind2 bug-ungetwc1 \
1606+ bug-wfflush bug-wmemstream1 tst-fopenloc2 \
1607+ tst_getwc \
1608+ tst_putwc tst_wprintf tst_wprintf2 tst_wscanf \
1609+ tst-fgetwc bug-wsetpos tst-fseek tst-ftell-partial-wide
1610+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
1611+ += tst_swprintf tst_swscanf \
1612+ tst-sscanf \
1613+ tst-wmemstream1 tst-wmemstream2
1614+
1615 ifeq (yes,$(build-shared))
1616 # Add test-fopenloc only if shared library is enabled since it depends on
1617 # shared localedata objects.
1618-tests += tst-fopenloc
1619+tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-fopenloc
1620 endif
1621 test-srcs = test-freopen
1622
1623@@ -164,13 +188,17 @@ shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \
1624 oldiofsetpos64
1625
1626 ifeq ($(run-built-tests),yes)
1627+ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
1628 tests-special += $(objpfx)test-freopen.out
1629+endif
1630+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
1631 ifeq (yes,$(build-shared))
1632 # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
1633 # library is enabled since they depend on tst-fopenloc.out.
1634 tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out
1635 endif
1636 endif
1637+endif
1638
1639 include ../Rules
1640
1641diff --git a/libio/__fpurge.c b/libio/__fpurge.c
1642index 065cf61..e32a3e9 100644
1643--- a/libio/__fpurge.c
1644+++ b/libio/__fpurge.c
1645@@ -21,7 +21,7 @@
1646 void
1647 __fpurge (FILE *fp)
1648 {
1649- if (fp->_mode > 0)
1650+ if (_IO_is_wide (fp))
1651 {
1652 /* Wide-char stream. */
1653 if (_IO_in_backup (fp))
1654diff --git a/libio/fileops.c b/libio/fileops.c
1655index cbcd6f5..19e43c2 100644
1656--- a/libio/fileops.c
1657+++ b/libio/fileops.c
1658@@ -39,6 +39,7 @@
1659 #include <string.h>
1660 #include <errno.h>
1661 #include <unistd.h>
1662+#include <gnu/option-groups.h>
1663 #include <stdlib.h>
1664 #if _LIBC
1665 # include "../wcsmbs/wcsmbsload.h"
1666@@ -173,7 +174,7 @@ _IO_new_file_close_it (_IO_FILE *fp)
1667
1668 /* Free buffer. */
1669 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
1670- if (fp->_mode > 0)
1671+ if (_IO_is_wide (fp))
1672 {
1673 if (_IO_have_wbackup (fp))
1674 _IO_free_wbackup_area (fp);
1675@@ -348,6 +349,7 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
1676 cs = strstr (last_recognized + 1, ",ccs=");
1677 if (cs != NULL)
1678 {
1679+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
1680 /* Yep. Load the appropriate conversions and set the orientation
1681 to wide. */
1682 struct gconv_fcts fcts;
1683@@ -418,6 +420,12 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
1684
1685 /* Set the mode now. */
1686 result->_mode = 1;
1687+#else
1688+ /* Treat this as if we couldn't find the given character set. */
1689+ (void) _IO_file_close_it (fp);
1690+ __set_errno (EINVAL);
1691+ return NULL;
1692+#endif
1693 }
1694 }
1695
1696diff --git a/libio/iofwide.c b/libio/iofwide.c
1697index 0c175d1..3e9f52b 100644
1698--- a/libio/iofwide.c
1699+++ b/libio/iofwide.c
1700@@ -26,6 +26,7 @@
1701
1702 #include <libioP.h>
1703 #ifdef _LIBC
1704+# include <gnu/option-groups.h>
1705 # include <dlfcn.h>
1706 # include <wchar.h>
1707 #endif
1708@@ -43,6 +44,8 @@
1709 #endif
1710
1711
1712+#if ! defined _LIBC || __OPTION_POSIX_C_LANG_WIDE_CHAR
1713+
1714 /* Prototypes of libio's codecvt functions. */
1715 static enum __codecvt_result do_out (struct _IO_codecvt *codecvt,
1716 __mbstate_t *statep,
1717@@ -499,3 +502,26 @@ do_max_length (struct _IO_codecvt *codecvt)
1718 return MB_CUR_MAX;
1719 #endif
1720 }
1721+
1722+#else
1723+/* OPTION_POSIX_C_LANG_WIDE_CHAR is disabled. */
1724+
1725+#undef _IO_fwide
1726+int
1727+_IO_fwide (fp, mode)
1728+ _IO_FILE *fp;
1729+ int mode;
1730+{
1731+ /* Die helpfully if the user tries to create a wide stream; I
1732+ disbelieve that most users check the return value from
1733+ 'fwide (fp, 1)'. */
1734+ assert (mode <= 0);
1735+
1736+ /* We can only make streams byte-oriented, which is trivial. */
1737+ if (mode < 0)
1738+ fp->_mode = -1;
1739+
1740+ return fp->_mode;
1741+}
1742+
1743+#endif
1744diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c
1745index 11765cf..15d6230 100644
1746--- a/libio/ioseekoff.c
1747+++ b/libio/ioseekoff.c
1748@@ -60,7 +60,7 @@ _IO_seekoff_unlocked (fp, offset, dir, mode)
1749 else
1750 abort ();
1751 }
1752- if (_IO_fwide (fp, 0) < 0)
1753+ if (! _IO_is_wide (fp))
1754 _IO_free_backup_area (fp);
1755 else
1756 _IO_free_wbackup_area (fp);
1757diff --git a/libio/ioseekpos.c b/libio/ioseekpos.c
1758index a7652a1..6938b68 100644
1759--- a/libio/ioseekpos.c
1760+++ b/libio/ioseekpos.c
1761@@ -35,7 +35,7 @@ _IO_seekpos_unlocked (fp, pos, mode)
1762 /* If we have a backup buffer, get rid of it, since the __seekoff
1763 callback may not know to do the right thing about it.
1764 This may be over-kill, but it'll do for now. TODO */
1765- if (_IO_fwide (fp, 0) <= 0)
1766+ if (! _IO_is_wide (fp))
1767 {
1768 if (_IO_have_backup (fp))
1769 _IO_free_backup_area (fp);
1770diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c
1771index 0a41c10..3d99fa0 100644
1772--- a/libio/iosetbuffer.c
1773+++ b/libio/iosetbuffer.c
1774@@ -24,6 +24,8 @@
1775 This exception applies to code released by its copyright holders
1776 in files containing the exception. */
1777
1778+#include <gnu/option-groups.h>
1779+
1780 #include "libioP.h"
1781
1782 void
1783@@ -38,9 +40,11 @@ _IO_setbuffer (fp, buf, size)
1784 if (!buf)
1785 size = 0;
1786 (void) _IO_SETBUF (fp, buf, size);
1787+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
1788 if (_IO_vtable_offset (fp) == 0 && fp->_mode == 0 && _IO_CHECK_WIDE (fp))
1789 /* We also have to set the buffer using the wide char function. */
1790 (void) _IO_WSETBUF (fp, buf, size);
1791+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
1792 _IO_release_lock (fp);
1793 }
1794 libc_hidden_def (_IO_setbuffer)
1795diff --git a/libio/libioP.h b/libio/libioP.h
1796index 0f16e2d..d2626d6 100644
1797--- a/libio/libioP.h
1798+++ b/libio/libioP.h
1799@@ -44,6 +44,10 @@
1800 /*# include <comthread.h>*/
1801 #endif
1802
1803+#if defined _LIBC
1804+# include <gnu/option-groups.h>
1805+#endif
1806+
1807 #include <math_ldbl_opt.h>
1808
1809 #include "iolibio.h"
1810@@ -523,8 +527,20 @@ extern void _IO_old_init (_IO_FILE *fp, int flags) __THROW;
1811
1812
1813 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
1814+
1815+/* _IO_is_wide (fp) is roughly equivalent to '_IO_fwide (fp, 0) > 0',
1816+ except that when OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, it
1817+ expands to a constant, allowing the compiler to realize that it can
1818+ eliminate code that references wide stream handling functions.
1819+ This, in turn, allows us to omit them. */
1820+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
1821+# define _IO_is_wide(_f) ((_f)->_mode > 0)
1822+#else
1823+# define _IO_is_wide(_f) (0)
1824+#endif
1825+
1826 # define _IO_do_flush(_f) \
1827- ((_f)->_mode <= 0 \
1828+ (! _IO_is_wide (_f) \
1829 ? _IO_do_write(_f, (_f)->_IO_write_base, \
1830 (_f)->_IO_write_ptr-(_f)->_IO_write_base) \
1831 : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base, \
1832diff --git a/libio/wdummyfileops.c b/libio/wdummyfileops.c
1833new file mode 100644
1834index 0000000..c0150b8
1835--- /dev/null
1836+++ b/libio/wdummyfileops.c
1837@@ -0,0 +1,161 @@
1838+/* Copyright (C) 2007 Free Software Foundation, Inc.
1839+ This file is part of the GNU C Library.
1840+
1841+ The GNU C Library is free software; you can redistribute it and/or
1842+ modify it under the terms of the GNU Lesser General Public
1843+ License as published by the Free Software Foundation; either
1844+ version 2.1 of the License, or (at your option) any later version.
1845+
1846+ The GNU C Library is distributed in the hope that it will be useful,
1847+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1848+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1849+ Lesser General Public License for more details.
1850+
1851+ You should have received a copy of the GNU Lesser General Public
1852+ License along with the GNU C Library; if not, write to the Free
1853+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1854+ 02111-1307 USA.
1855+
1856+ As a special exception, if you link the code in this file with
1857+ files compiled with a GNU compiler to produce an executable,
1858+ that does not cause the resulting executable to be covered by
1859+ the GNU Lesser General Public License. This exception does not
1860+ however invalidate any other reasons why the executable file
1861+ might be covered by the GNU Lesser General Public License.
1862+ This exception applies to code released by its copyright holders
1863+ in files containing the exception. */
1864+
1865+#include <assert.h>
1866+#include <stdio.h>
1867+#include <stdlib.h>
1868+#include <libioP.h>
1869+
1870+static void __THROW __attribute__ ((__noreturn__))
1871+_IO_wfile_wide_char_support_disabled (void)
1872+{
1873+ static const char errstr[]
1874+ = ("The application tried to use wide character I/O, but libc.so"
1875+ " was compiled\n"
1876+ "with the OPTION_POSIX_C_LANG_WIDE_CHAR option group disabled.\n");
1877+ __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
1878+ abort ();
1879+}
1880+
1881+static void
1882+_IO_wfile_disabled_void_int (_IO_FILE *fp, int x)
1883+{
1884+ _IO_wfile_wide_char_support_disabled ();
1885+}
1886+
1887+static int
1888+_IO_wfile_disabled_int_int (_IO_FILE *fp, int x)
1889+{
1890+ _IO_wfile_wide_char_support_disabled ();
1891+}
1892+
1893+static int
1894+_IO_wfile_disabled_int_none (_IO_FILE *fp)
1895+{
1896+ _IO_wfile_wide_char_support_disabled ();
1897+}
1898+
1899+static _IO_size_t
1900+_IO_wfile_disabled_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n)
1901+{
1902+ _IO_wfile_wide_char_support_disabled ();
1903+}
1904+
1905+static _IO_size_t
1906+_IO_wfile_disabled_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
1907+{
1908+ _IO_wfile_wide_char_support_disabled ();
1909+}
1910+
1911+static _IO_off64_t
1912+_IO_wfile_disabled_seekoff (_IO_FILE *fp, _IO_off64_t off, int dir, int mode)
1913+{
1914+ _IO_wfile_wide_char_support_disabled ();
1915+}
1916+
1917+static _IO_off64_t
1918+_IO_wfile_disabled_seekpos (_IO_FILE *fp, _IO_off64_t pos, int flags)
1919+{
1920+ _IO_wfile_wide_char_support_disabled ();
1921+}
1922+
1923+static _IO_FILE *
1924+_IO_wfile_disabled_setbuf (_IO_FILE *fp, char *buffer, _IO_ssize_t length)
1925+{
1926+ _IO_wfile_wide_char_support_disabled ();
1927+}
1928+
1929+static _IO_ssize_t
1930+_IO_wfile_disabled_read (_IO_FILE *fp, void *buffer, _IO_ssize_t length)
1931+{
1932+ _IO_wfile_wide_char_support_disabled ();
1933+}
1934+
1935+static _IO_ssize_t
1936+_IO_wfile_disabled_write (_IO_FILE *fp, const void *buffer, _IO_ssize_t length)
1937+{
1938+ _IO_wfile_wide_char_support_disabled ();
1939+}
1940+
1941+static _IO_off64_t
1942+_IO_wfile_disabled_seek (_IO_FILE *fp, _IO_off64_t offset, int mode)
1943+{
1944+ _IO_wfile_wide_char_support_disabled ();
1945+}
1946+
1947+static int
1948+_IO_wfile_disabled_close (_IO_FILE *fp)
1949+{
1950+ _IO_wfile_wide_char_support_disabled ();
1951+}
1952+
1953+static int
1954+_IO_wfile_disabled_stat (_IO_FILE *fp, void *buf)
1955+{
1956+ _IO_wfile_wide_char_support_disabled ();
1957+}
1958+
1959+static int
1960+_IO_wfile_disabled_showmanyc (_IO_FILE *fp)
1961+{
1962+ _IO_wfile_wide_char_support_disabled ();
1963+}
1964+
1965+static void
1966+_IO_wfile_disabled_imbue (_IO_FILE *fp, void *locale)
1967+{
1968+ _IO_wfile_wide_char_support_disabled ();
1969+}
1970+
1971+static const struct _IO_jump_t _IO_wfile_jumps_disabled =
1972+{
1973+ JUMP_INIT_DUMMY,
1974+ JUMP_INIT(finish, _IO_wfile_disabled_void_int),
1975+ JUMP_INIT(overflow, _IO_wfile_disabled_int_int),
1976+ JUMP_INIT(underflow, _IO_wfile_disabled_int_none),
1977+ JUMP_INIT(uflow, _IO_wfile_disabled_int_none),
1978+ JUMP_INIT(pbackfail, _IO_wfile_disabled_int_int),
1979+ JUMP_INIT(xsputn, _IO_wfile_disabled_xsputn),
1980+ JUMP_INIT(xsgetn, _IO_wfile_disabled_xsgetn),
1981+ JUMP_INIT(seekoff, _IO_wfile_disabled_seekoff),
1982+ JUMP_INIT(seekpos, _IO_wfile_disabled_seekpos),
1983+ JUMP_INIT(setbuf, _IO_wfile_disabled_setbuf),
1984+ JUMP_INIT(sync, _IO_wfile_disabled_int_none),
1985+ JUMP_INIT(doallocate, _IO_wfile_disabled_int_none),
1986+ JUMP_INIT(read, _IO_wfile_disabled_read),
1987+ JUMP_INIT(write, _IO_wfile_disabled_write),
1988+ JUMP_INIT(seek, _IO_wfile_disabled_seek),
1989+ JUMP_INIT(close, _IO_wfile_disabled_close),
1990+ JUMP_INIT(stat, _IO_wfile_disabled_stat),
1991+ JUMP_INIT(showmanyc, _IO_wfile_disabled_showmanyc),
1992+ JUMP_INIT(imbue, _IO_wfile_disabled_imbue)
1993+};
1994+
1995+strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps)
1996+libc_hidden_data_def (_IO_wfile_jumps)
1997+strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_mmap)
1998+strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_maybe_mmap)
1999diff --git a/locale/C-ctype.c b/locale/C-ctype.c
2000index aa5f19f..06be081 100644
2001--- a/locale/C-ctype.c
2002+++ b/locale/C-ctype.c
2003@@ -19,8 +19,11 @@
2004 #include "localeinfo.h"
2005 #include <endian.h>
2006 #include <stdint.h>
2007+#include <gnu/option-groups.h>
2008
2009+#if __OPTION_EGLIBC_LOCALE_CODE
2010 #include "C-translit.h"
2011+#endif
2012
2013 /* This table's entries are taken from POSIX.2 Table 2-6
2014 ``LC_CTYPE Category Definition in the POSIX Locale''.
2015@@ -634,6 +637,7 @@ const struct __locale_data _nl_C_LC_CTYPE attribute_hidden =
2016 { .word = L'7' },
2017 { .word = L'8' },
2018 { .word = L'9' },
2019+#if __OPTION_EGLIBC_LOCALE_CODE
2020 /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
2021 { .word = NTRANSLIT },
2022 /* _NL_CTYPE_TRANSLIT_FROM_IDX */
2023@@ -644,6 +648,22 @@ const struct __locale_data _nl_C_LC_CTYPE attribute_hidden =
2024 { .wstr = translit_to_idx },
2025 /* _NL_CTYPE_TRANSLIT_TO_TBL */
2026 { .wstr = (uint32_t *) translit_to_tbl },
2027+#else
2028+ /* If the locale code isn't enabled, we don't have the
2029+ transliteration code in iconv/gconv_trans.c anyway, so there's
2030+ no need for the transliteration tables here. We'll fall back
2031+ on the default missing replacement, '?'. */
2032+ /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
2033+ { .word = 0 },
2034+ /* _NL_CTYPE_TRANSLIT_FROM_IDX */
2035+ { .wstr = NULL },
2036+ /* _NL_CTYPE_TRANSLIT_FROM_TBL */
2037+ { .wstr = NULL },
2038+ /* _NL_CTYPE_TRANSLIT_TO_IDX */
2039+ { .wstr = NULL },
2040+ /* _NL_CTYPE_TRANSLIT_TO_TBL */
2041+ { .wstr = NULL },
2042+#endif
2043 /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN */
2044 { .word = 1 },
2045 /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING */
2046diff --git a/locale/Makefile b/locale/Makefile
2047index f1b4343..599a1a9 100644
2048--- a/locale/Makefile
2049+++ b/locale/Makefile
2050@@ -18,27 +18,43 @@
2051 #
2052 # Makefile for locales.
2053 #
2054+include ../option-groups.mak
2055+
2056 subdir := locale
2057
2058 include ../Makeconfig
2059
2060 headers = locale.h bits/locale.h langinfo.h xlocale.h
2061-routines = setlocale findlocale loadlocale loadarchive \
2062- localeconv nl_langinfo nl_langinfo_l mb_cur_max \
2063- newlocale duplocale freelocale uselocale
2064-tests = tst-C-locale tst-locname tst-duplocale
2065+# catnames is needed by OPTION_EGLIBC_LOCALE_CODE and by the 'intl' code.
2066+# If we put the latter in an option group, too, we can omit catnames
2067+# when both option groups are disabled. libstdc++-v3 needs mb_cur_max.
2068+routines-y := catnames mb_cur_max
2069+routines-$(OPTION_EGLIBC_LOCALE_CODE) \
2070+ += setlocale findlocale loadlocale loadarchive \
2071+ localeconv nl_langinfo nl_langinfo_l \
2072+ newlocale duplocale freelocale uselocale
2073+ifneq (y,$(OPTION_EGLIBC_LOCALE_CODE))
2074+routines-y += dummy-setlocale
2075+endif
2076+tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-C-locale tst-locname tst-duplocale
2077 categories = ctype messages monetary numeric time paper name \
2078 address telephone measurement identification collate
2079-aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \
2080- xlocale localename global-locale coll-lookup
2081-others = localedef locale
2082+# C-messages belongs in an intl option group.
2083+aux-y := C-ctype C-time \
2084+ SYS_libc C_name xlocale global-locale coll-lookup
2085+aux-$(OPTION_EGLIBC_LOCALE_CODE) \
2086+ += $(filter-out $(aux-y), \
2087+ $(categories:%=lc-%) $(categories:%=C-%)) \
2088+ localename
2089+others-$(OPTION_EGLIBC_LOCALE_CODE) = localedef locale
2090 #others-static = localedef locale
2091-install-bin = localedef locale
2092-extra-objs = $(localedef-modules:=.o) $(localedef-aux:=.o) \
2093+install-bin = $(others-y)
2094+extra-objs-$(OPTION_EGLIBC_LOCALE_CODE) \
2095+ = $(localedef-modules:=.o) $(localedef-aux:=.o) \
2096 $(locale-modules:=.o) $(lib-modules:=.o)
2097
2098-extra-libs = libBrokenLocale
2099-extra-libs-others = $(extra-libs)
2100+extra-libs-$(OPTION_EGLIBC_LOCALE_CODE) = libBrokenLocale
2101+extra-libs-others = $(extra-libs-y)
2102
2103 libBrokenLocale-routines = broken_cur_max
2104
2105@@ -93,6 +109,9 @@ CPPFLAGS-locale-programs = -DLOCALE_PATH='$(localepath)' \
2106 CFLAGS-charmap.c = -Wno-write-strings -Wno-char-subscripts
2107 CFLAGS-locfile.c = -Wno-write-strings -Wno-char-subscripts
2108 CFLAGS-charmap-dir.c = -Wno-write-strings
2109+ifneq (y,$(OPTION_EGLIBC_SPAWN))
2110+CFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
2111+endif
2112
2113 # Set libof-* for each routine.
2114 cpp-srcs-left := $(localedef-modules) $(localedef-aux) $(locale-modules) \
2115diff --git a/locale/catnames.c b/locale/catnames.c
2116new file mode 100644
2117index 0000000..9fad357
2118--- /dev/null
2119+++ b/locale/catnames.c
2120@@ -0,0 +1,48 @@
2121+/* Copyright (C) 2006 Free Software Foundation, Inc.
2122+ This file is part of the GNU C Library.
2123+
2124+ The GNU C Library is free software; you can redistribute it and/or
2125+ modify it under the terms of the GNU Lesser General Public
2126+ License as published by the Free Software Foundation; either
2127+ version 2.1 of the License, or (at your option) any later version.
2128+
2129+ The GNU C Library is distributed in the hope that it will be useful,
2130+ but WITHOUT ANY WARRANTY; without even the implied warranty of
2131+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2132+ Lesser General Public License for more details.
2133+
2134+ You should have received a copy of the GNU Lesser General Public
2135+ License along with the GNU C Library; if not, write to the Free
2136+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
2137+ 02111-1307 USA. */
2138+
2139+#include "localeinfo.h"
2140+
2141+/* Define an array of category names (also the environment variable names). */
2142+const union catnamestr_t _nl_category_names attribute_hidden =
2143+ {
2144+ {
2145+#define DEFINE_CATEGORY(category, category_name, items, a) \
2146+ category_name,
2147+#include "categories.def"
2148+#undef DEFINE_CATEGORY
2149+ }
2150+ };
2151+
2152+const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
2153+ {
2154+#define DEFINE_CATEGORY(category, category_name, items, a) \
2155+ [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
2156+#include "categories.def"
2157+#undef DEFINE_CATEGORY
2158+ };
2159+
2160+/* An array of their lengths, for convenience. */
2161+const uint8_t _nl_category_name_sizes[] attribute_hidden =
2162+ {
2163+#define DEFINE_CATEGORY(category, category_name, items, a) \
2164+ [category] = sizeof (category_name) - 1,
2165+#include "categories.def"
2166+#undef DEFINE_CATEGORY
2167+ [LC_ALL] = sizeof ("LC_ALL") - 1
2168+ };
2169diff --git a/locale/dummy-setlocale.c b/locale/dummy-setlocale.c
2170new file mode 100644
2171index 0000000..219964a
2172--- /dev/null
2173+++ b/locale/dummy-setlocale.c
2174@@ -0,0 +1,33 @@
2175+/* Copyright (C) 2006 Free Software Foundation, Inc.
2176+ This file is part of the GNU C Library.
2177+
2178+ The GNU C Library is free software; you can redistribute it and/or
2179+ modify it under the terms of the GNU Lesser General Public
2180+ License as published by the Free Software Foundation; either
2181+ version 2.1 of the License, or (at your option) any later version.
2182+
2183+ The GNU C Library is distributed in the hope that it will be useful,
2184+ but WITHOUT ANY WARRANTY; without even the implied warranty of
2185+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2186+ Lesser General Public License for more details.
2187+
2188+ You should have received a copy of the GNU Lesser General Public
2189+ License along with the GNU C Library; if not, write to the Free
2190+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
2191+ 02111-1307 USA. */
2192+
2193+#include <string.h>
2194+#include <locale.h>
2195+
2196+char *
2197+setlocale (int category, const char *locale)
2198+{
2199+ if (! locale
2200+ || locale[0] == '\0'
2201+ || strcmp (locale, "C") == 0
2202+ || strcmp (locale, "POSIX") == 0)
2203+ return (char *) "C";
2204+ else
2205+ return NULL;
2206+}
2207+libc_hidden_def (setlocale)
2208diff --git a/locale/localeinfo.h b/locale/localeinfo.h
2209index bdab9fe..a7516c0 100644
2210--- a/locale/localeinfo.h
2211+++ b/locale/localeinfo.h
2212@@ -232,7 +232,7 @@ __libc_tsd_define (extern, __locale_t, LOCALE)
2213 unused. We can manage this playing some tricks with weak references.
2214 But with thread-local locale settings, it becomes quite ungainly unless
2215 we can use __thread variables. So only in that case do we attempt this. */
2216-#ifndef SHARED
2217+#if !defined SHARED && !defined IN_GLIBC_LOCALEDEF
2218 # include <tls.h>
2219 # define NL_CURRENT_INDIRECT 1
2220 #endif
2221diff --git a/locale/programs/charmap-dir.c b/locale/programs/charmap-dir.c
2222index cf7adea..ef3b811 100644
2223--- a/locale/programs/charmap-dir.c
2224+++ b/locale/programs/charmap-dir.c
2225@@ -19,7 +19,9 @@
2226 #include <error.h>
2227 #include <fcntl.h>
2228 #include <libintl.h>
2229+#ifndef NO_UNCOMPRESS
2230 #include <spawn.h>
2231+#endif
2232 #include <stdio.h>
2233 #include <stdlib.h>
2234 #include <string.h>
2235@@ -156,6 +158,7 @@ charmap_closedir (CHARMAP_DIR *cdir)
2236 return closedir (dir);
2237 }
2238
2239+#ifndef NO_UNCOMPRESS
2240 /* Creates a subprocess decompressing the given pathname, and returns
2241 a stream reading its output (the decompressed data). */
2242 static
2243@@ -204,6 +207,7 @@ fopen_uncompressed (const char *pathname, const char *compressor)
2244 }
2245 return NULL;
2246 }
2247+#endif
2248
2249 /* Opens a charmap for reading, given its name (not an alias name). */
2250 FILE *
2251@@ -226,6 +230,7 @@ charmap_open (const char *directory, const char *name)
2252 if (stream != NULL)
2253 return stream;
2254
2255+#ifndef NO_UNCOMPRESS
2256 memcpy (p, ".gz", 4);
2257 stream = fopen_uncompressed (pathname, "gzip");
2258 if (stream != NULL)
2259@@ -235,6 +240,7 @@ charmap_open (const char *directory, const char *name)
2260 stream = fopen_uncompressed (pathname, "bzip2");
2261 if (stream != NULL)
2262 return stream;
2263+#endif
2264
2265 return NULL;
2266 }
2267diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
2268index a39a94f..16e9039 100644
2269--- a/locale/programs/ld-collate.c
2270+++ b/locale/programs/ld-collate.c
2271@@ -351,7 +351,7 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
2272 }
2273 if (wcs != NULL)
2274 {
2275- size_t nwcs = wcslen ((wchar_t *) wcs);
2276+ size_t nwcs = wcslen_uint32 (wcs);
2277 uint32_t zero = 0;
2278 /* Handle <U0000> as a single character. */
2279 if (nwcs == 0)
2280@@ -1777,8 +1777,7 @@ symbol `%s' has the same encoding as"), (*eptr)->name);
2281
2282 if ((*eptr)->nwcs == runp->nwcs)
2283 {
2284- int c = wmemcmp ((wchar_t *) (*eptr)->wcs,
2285- (wchar_t *) runp->wcs, runp->nwcs);
2286+ int c = wmemcmp_uint32 ((*eptr)->wcs, runp->wcs, runp->nwcs);
2287
2288 if (c == 0)
2289 {
2290@@ -2011,9 +2010,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
2291 one consecutive entry. */
2292 if (runp->wcnext != NULL
2293 && runp->nwcs == runp->wcnext->nwcs
2294- && wmemcmp ((wchar_t *) runp->wcs,
2295- (wchar_t *)runp->wcnext->wcs,
2296- runp->nwcs - 1) == 0
2297+ && wmemcmp_uint32 (runp->wcs,
2298+ runp->wcnext->wcs,
2299+ runp->nwcs - 1) == 0
2300 && (runp->wcs[runp->nwcs - 1]
2301 == runp->wcnext->wcs[runp->nwcs - 1] + 1))
2302 {
2303@@ -2037,9 +2036,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
2304 runp = runp->wcnext;
2305 while (runp->wcnext != NULL
2306 && runp->nwcs == runp->wcnext->nwcs
2307- && wmemcmp ((wchar_t *) runp->wcs,
2308- (wchar_t *)runp->wcnext->wcs,
2309- runp->nwcs - 1) == 0
2310+ && wmemcmp_uint32 (runp->wcs,
2311+ runp->wcnext->wcs,
2312+ runp->nwcs - 1) == 0
2313 && (runp->wcs[runp->nwcs - 1]
2314 == runp->wcnext->wcs[runp->nwcs - 1] + 1));
2315
2316diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
2317index 3f464ef..b7b6b51 100644
2318--- a/locale/programs/ld-ctype.c
2319+++ b/locale/programs/ld-ctype.c
2320@@ -926,7 +926,7 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
2321 allocate_arrays (ctype, charmap, ctype->repertoire);
2322
2323 default_missing_len = (ctype->default_missing
2324- ? wcslen ((wchar_t *) ctype->default_missing)
2325+ ? wcslen_uint32 (ctype->default_missing)
2326 : 0);
2327
2328 init_locale_data (&file, nelems);
2329@@ -1937,7 +1937,7 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype,
2330 ignore = 1;
2331 else
2332 /* This value is usable. */
2333- obstack_grow (ob, to_wstr, wcslen ((wchar_t *) to_wstr) * 4);
2334+ obstack_grow (ob, to_wstr, wcslen_uint32 (to_wstr) * 4);
2335
2336 first = 0;
2337 }
2338@@ -2471,8 +2471,8 @@ with character code range values one must use the absolute ellipsis `...'"));
2339 }
2340
2341 handle_tok_digit:
2342- class_bit = _ISwdigit;
2343- class256_bit = _ISdigit;
2344+ class_bit = BITw (tok_digit);
2345+ class256_bit = BIT (tok_digit);
2346 handle_digits = 1;
2347 goto read_charclass;
2348
2349@@ -3929,8 +3929,7 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
2350
2351 while (idx < number)
2352 {
2353- int res = wcscmp ((const wchar_t *) sorted[idx]->from,
2354- (const wchar_t *) runp->from);
2355+ int res = wcscmp_uint32 (sorted[idx]->from, runp->from);
2356 if (res == 0)
2357 {
2358 replace = 1;
2359@@ -3967,11 +3966,11 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
2360 for (size_t cnt = 0; cnt < number; ++cnt)
2361 {
2362 struct translit_to_t *srunp;
2363- from_len += wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
2364+ from_len += wcslen_uint32 (sorted[cnt]->from) + 1;
2365 srunp = sorted[cnt]->to;
2366 while (srunp != NULL)
2367 {
2368- to_len += wcslen ((const wchar_t *) srunp->str) + 1;
2369+ to_len += wcslen_uint32 (srunp->str) + 1;
2370 srunp = srunp->next;
2371 }
2372 /* Plus one for the extra NUL character marking the end of
2373@@ -3995,18 +3994,18 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
2374 ctype->translit_from_idx[cnt] = from_len;
2375 ctype->translit_to_idx[cnt] = to_len;
2376
2377- len = wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
2378- wmemcpy ((wchar_t *) &ctype->translit_from_tbl[from_len],
2379- (const wchar_t *) sorted[cnt]->from, len);
2380+ len = wcslen_uint32 (sorted[cnt]->from) + 1;
2381+ wmemcpy_uint32 (&ctype->translit_from_tbl[from_len],
2382+ sorted[cnt]->from, len);
2383 from_len += len;
2384
2385 ctype->translit_to_idx[cnt] = to_len;
2386 srunp = sorted[cnt]->to;
2387 while (srunp != NULL)
2388 {
2389- len = wcslen ((const wchar_t *) srunp->str) + 1;
2390- wmemcpy ((wchar_t *) &ctype->translit_to_tbl[to_len],
2391- (const wchar_t *) srunp->str, len);
2392+ len = wcslen_uint32 (srunp->str) + 1;
2393+ wmemcpy_uint32 (&ctype->translit_to_tbl[to_len],
2394+ srunp->str, len);
2395 to_len += len;
2396 srunp = srunp->next;
2397 }
2398diff --git a/locale/programs/ld-messages.c b/locale/programs/ld-messages.c
2399index ec1a80b..736eed8 100644
2400--- a/locale/programs/ld-messages.c
2401+++ b/locale/programs/ld-messages.c
2402@@ -25,6 +25,7 @@
2403 #include <string.h>
2404 #include <stdint.h>
2405 #include <sys/uio.h>
2406+#include <gnu/option-groups.h>
2407
2408 #include <assert.h>
2409
2410@@ -124,6 +125,7 @@ No definition for %s category found"), "LC_MESSAGES"));
2411 }
2412 else
2413 {
2414+#if __OPTION_POSIX_REGEXP
2415 int result;
2416 regex_t re;
2417
2418@@ -140,6 +142,7 @@ No definition for %s category found"), "LC_MESSAGES"));
2419 }
2420 else if (result != 0)
2421 regfree (&re);
2422+#endif
2423 }
2424
2425 if (messages->noexpr == NULL)
2426@@ -158,6 +161,7 @@ No definition for %s category found"), "LC_MESSAGES"));
2427 }
2428 else
2429 {
2430+#if __OPTION_POSIX_REGEXP
2431 int result;
2432 regex_t re;
2433
2434@@ -174,6 +178,7 @@ No definition for %s category found"), "LC_MESSAGES"));
2435 }
2436 else if (result != 0)
2437 regfree (&re);
2438+#endif
2439 }
2440 }
2441
2442diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
2443index db490c6..75dc505 100644
2444--- a/locale/programs/ld-time.c
2445+++ b/locale/programs/ld-time.c
2446@@ -215,8 +215,10 @@ No definition for %s category found"), "LC_TIME"));
2447 }
2448 else
2449 {
2450+ static const uint32_t wt_fmt_ampm[]
2451+ = { '%','I',':','%','M',':','%','S',' ','%','p',0 };
2452 time->t_fmt_ampm = "%I:%M:%S %p";
2453- time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p";
2454+ time->wt_fmt_ampm = wt_fmt_ampm;
2455 }
2456 }
2457
2458@@ -226,7 +228,7 @@ No definition for %s category found"), "LC_TIME"));
2459 const int days_per_month[12] = { 31, 29, 31, 30, 31, 30,
2460 31, 31, 30, 31 ,30, 31 };
2461 size_t idx;
2462- wchar_t *wstr;
2463+ uint32_t *wstr;
2464
2465 time->era_entries =
2466 (struct era_data *) xmalloc (time->num_era
2467@@ -464,18 +466,18 @@ No definition for %s category found"), "LC_TIME"));
2468 }
2469
2470 /* Now generate the wide character name and format. */
2471- wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */
2472- wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end offset */
2473- wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end start */
2474- wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end end */
2475+ wstr = wcschr_uint32 (time->wera[idx], L':'); /* end direction */
2476+ wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end offset */
2477+ wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end start */
2478+ wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end end */
2479 if (wstr != NULL)
2480 {
2481- time->era_entries[idx].wname = (uint32_t *) wstr + 1;
2482- wstr = wcschr (wstr + 1, L':'); /* end name */
2483+ time->era_entries[idx].wname = wstr + 1;
2484+ wstr = wcschr_uint32 (wstr + 1, L':'); /* end name */
2485 if (wstr != NULL)
2486 {
2487 *wstr = L'\0';
2488- time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
2489+ time->era_entries[idx].wformat = wstr + 1;
2490 }
2491 else
2492 time->era_entries[idx].wname =
2493@@ -530,7 +532,16 @@ No definition for %s category found"), "LC_TIME"));
2494 if (time->date_fmt == NULL)
2495 time->date_fmt = "%a %b %e %H:%M:%S %Z %Y";
2496 if (time->wdate_fmt == NULL)
2497- time->wdate_fmt = (const uint32_t *) L"%a %b %e %H:%M:%S %Z %Y";
2498+ {
2499+ static const uint32_t wdate_fmt[] =
2500+ { '%','a',' ',
2501+ '%','b',' ',
2502+ '%','e',' ',
2503+ '%','H',':','%','M',':','%','S',' ',
2504+ '%','Z',' ',
2505+ '%','Y',0 };
2506+ time->wdate_fmt = wdate_fmt;
2507+ }
2508 }
2509
2510
2511diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c
2512index 2e05130..653b68c 100644
2513--- a/locale/programs/linereader.c
2514+++ b/locale/programs/linereader.c
2515@@ -595,7 +595,7 @@ get_string (struct linereader *lr, const struct charmap_t *charmap,
2516 {
2517 int return_widestr = lr->return_widestr;
2518 char *buf;
2519- wchar_t *buf2 = NULL;
2520+ uint32_t *buf2 = NULL;
2521 size_t bufact;
2522 size_t bufmax = 56;
2523
2524diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
2525index 2a0f2aa..583d233 100644
2526--- a/locale/programs/localedef.c
2527+++ b/locale/programs/localedef.c
2528@@ -114,6 +114,7 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
2529 #define OPT_LIST_ARCHIVE 309
2530 #define OPT_LITTLE_ENDIAN 400
2531 #define OPT_BIG_ENDIAN 401
2532+#define OPT_UINT32_ALIGN 402
2533
2534 /* Definitions of arguments for argp functions. */
2535 static const struct argp_option options[] =
2536@@ -150,6 +151,8 @@ static const struct argp_option options[] =
2537 N_("Generate little-endian output") },
2538 { "big-endian", OPT_BIG_ENDIAN, NULL, 0,
2539 N_("Generate big-endian output") },
2540+ { "uint32-align", OPT_UINT32_ALIGN, "ALIGNMENT", 0,
2541+ N_("Set the target's uint32_t alignment in bytes (default 4)") },
2542 { NULL, 0, NULL, 0, NULL }
2543 };
2544
2545@@ -239,12 +242,14 @@ main (int argc, char *argv[])
2546 ctype locale. (P1003.2 4.35.5.2) */
2547 setlocale (LC_CTYPE, "POSIX");
2548
2549+#ifndef NO_SYSCONF
2550 /* Look whether the system really allows locale definitions. POSIX
2551 defines error code 3 for this situation so I think it must be
2552 a fatal error (see P1003.2 4.35.8). */
2553 if (sysconf (_SC_2_LOCALEDEF) < 0)
2554 WITH_CUR_LOCALE (error (3, 0, _("\
2555 FATAL: system does not define `_POSIX2_LOCALEDEF'")));
2556+#endif
2557
2558 /* Process charmap file. */
2559 charmap = charmap_read (charmap_file, verbose, 1, be_quiet, 1);
2560@@ -338,6 +343,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
2561 case OPT_BIG_ENDIAN:
2562 set_big_endian (true);
2563 break;
2564+ case OPT_UINT32_ALIGN:
2565+ uint32_align_mask = strtol (arg, NULL, 0) - 1;
2566+ break;
2567 case 'c':
2568 force_output = 1;
2569 break;
2570diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c
2571index 33da52e..f790c4c 100644
2572--- a/locale/programs/locfile.c
2573+++ b/locale/programs/locfile.c
2574@@ -544,6 +544,9 @@ compare_files (const char *filename1, const char *filename2, size_t size,
2575 machine running localedef. */
2576 bool swap_endianness_p;
2577
2578+/* The target's value of __align__(uint32_t) - 1. */
2579+unsigned int uint32_align_mask = 3;
2580+
2581 /* When called outside a start_locale_structure/end_locale_structure
2582 or start_locale_prelude/end_locale_prelude block, record that the
2583 next byte in FILE's obstack will be the first byte of a new element.
2584@@ -621,7 +624,7 @@ add_locale_string (struct locale_file *file, const char *string)
2585 void
2586 add_locale_wstring (struct locale_file *file, const uint32_t *string)
2587 {
2588- add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1);
2589+ add_locale_uint32_array (file, string, wcslen_uint32 (string) + 1);
2590 }
2591
2592 /* Record that FILE's next element is the 32-bit integer VALUE. */
2593diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h
2594index 6fc441b..118b171 100644
2595--- a/locale/programs/locfile.h
2596+++ b/locale/programs/locfile.h
2597@@ -71,6 +71,8 @@ extern void write_all_categories (struct localedef_t *definitions,
2598
2599 extern bool swap_endianness_p;
2600
2601+extern unsigned int uint32_align_mask;
2602+
2603 /* Change the output to be big-endian if BIG_ENDIAN is true and
2604 little-endian otherwise. */
2605 static inline void
2606@@ -89,7 +91,8 @@ maybe_swap_uint32 (uint32_t value)
2607 }
2608
2609 /* Likewise, but munge an array of N uint32_ts starting at ARRAY. */
2610-static inline void
2611+static void
2612+__attribute__ ((unused))
2613 maybe_swap_uint32_array (uint32_t *array, size_t n)
2614 {
2615 if (swap_endianness_p)
2616@@ -99,7 +102,8 @@ maybe_swap_uint32_array (uint32_t *array, size_t n)
2617
2618 /* Like maybe_swap_uint32_array, but the array of N elements is at
2619 the end of OBSTACK's current object. */
2620-static inline void
2621+static void
2622+__attribute__ ((unused))
2623 maybe_swap_uint32_obstack (struct obstack *obstack, size_t n)
2624 {
2625 maybe_swap_uint32_array ((uint32_t *) obstack_next_free (obstack) - n, n);
2626@@ -276,4 +280,55 @@ extern void identification_output (struct localedef_t *locale,
2627 const struct charmap_t *charmap,
2628 const char *output_path);
2629
2630+static size_t wcslen_uint32 (const uint32_t *str) __attribute__ ((unused));
2631+static uint32_t * wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
2632+static uint32_t * wcschr_uint32 (const uint32_t *s, uint32_t ch) __attribute__ ((unused));
2633+static int wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2) __attribute__ ((unused));
2634+static int wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
2635+
2636+static size_t
2637+wcslen_uint32 (const uint32_t *str)
2638+{
2639+ size_t len = 0;
2640+ while (str[len] != 0)
2641+ len++;
2642+ return len;
2643+}
2644+
2645+static int
2646+wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n)
2647+{
2648+ while (n-- != 0)
2649+ {
2650+ int diff = *s1++ - *s2++;
2651+ if (diff != 0)
2652+ return diff;
2653+ }
2654+ return 0;
2655+}
2656+
2657+static int
2658+wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2)
2659+{
2660+ while (*s1 != 0 && *s1 == *s2)
2661+ s1++, s2++;
2662+ return *s1 - *s2;
2663+}
2664+
2665+static uint32_t *
2666+wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n)
2667+{
2668+ return memcpy (s1, s2, n * sizeof (uint32_t));
2669+}
2670+
2671+static uint32_t *
2672+wcschr_uint32 (const uint32_t *s, uint32_t ch)
2673+{
2674+ do
2675+ if (*s == ch)
2676+ return (uint32_t *) s;
2677+ while (*s++ != 0);
2678+ return 0;
2679+}
2680+
2681 #endif /* locfile.h */
2682diff --git a/locale/setlocale.c b/locale/setlocale.c
2683index fa9cb3a..8eee284 100644
2684--- a/locale/setlocale.c
2685+++ b/locale/setlocale.c
2686@@ -64,36 +64,6 @@ static char *const _nl_current_used[] =
2687 #endif
2688
2689
2690-/* Define an array of category names (also the environment variable names). */
2691-const union catnamestr_t _nl_category_names attribute_hidden =
2692- {
2693- {
2694-#define DEFINE_CATEGORY(category, category_name, items, a) \
2695- category_name,
2696-#include "categories.def"
2697-#undef DEFINE_CATEGORY
2698- }
2699- };
2700-
2701-const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
2702- {
2703-#define DEFINE_CATEGORY(category, category_name, items, a) \
2704- [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
2705-#include "categories.def"
2706-#undef DEFINE_CATEGORY
2707- };
2708-
2709-/* An array of their lengths, for convenience. */
2710-const uint8_t _nl_category_name_sizes[] attribute_hidden =
2711- {
2712-#define DEFINE_CATEGORY(category, category_name, items, a) \
2713- [category] = sizeof (category_name) - 1,
2714-#include "categories.def"
2715-#undef DEFINE_CATEGORY
2716- [LC_ALL] = sizeof ("LC_ALL") - 1
2717- };
2718-
2719-
2720 #ifdef NL_CURRENT_INDIRECT
2721 # define WEAK_POSTLOAD(postload) weak_extern (postload)
2722 #else
2723diff --git a/locale/xlocale.c b/locale/xlocale.c
2724index fec4564..f00269c 100644
2725--- a/locale/xlocale.c
2726+++ b/locale/xlocale.c
2727@@ -18,6 +18,7 @@
2728 <http://www.gnu.org/licenses/>. */
2729
2730 #include <locale.h>
2731+#include <gnu/option-groups.h>
2732 #include "localeinfo.h"
2733
2734 #define DEFINE_CATEGORY(category, category_name, items, a) \
2735@@ -25,6 +26,19 @@ extern struct __locale_data _nl_C_##category;
2736 #include "categories.def"
2737 #undef DEFINE_CATEGORY
2738
2739+/* If the locale support code isn't enabled, don't generate strong
2740+ reference to the C locale_data structures here; let the Makefile
2741+ decide which ones to include. (In the static linking case, the
2742+ strong reference to the 'class', 'toupper', and 'tolower' tables
2743+ will cause C-ctype.o to be brought in, as it should be, even when
2744+ the reference to _nl_C_LC_CTYPE will be weak.) */
2745+#if ! __OPTION_EGLIBC_LOCALE_CODE
2746+# define DEFINE_CATEGORY(category, category_name, items, a) \
2747+ weak_extern (_nl_C_##category)
2748+# include "categories.def"
2749+# undef DEFINE_CATEGORY
2750+#endif
2751+
2752 /* Defined in locale/C-ctype.c. */
2753 extern const char _nl_C_LC_CTYPE_class[] attribute_hidden;
2754 extern const char _nl_C_LC_CTYPE_toupper[] attribute_hidden;
2755@@ -52,3 +66,26 @@ const struct __locale_struct _nl_C_locobj attribute_hidden =
2756 .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
2757 .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
2758 };
2759+
2760+
2761+#if ! __OPTION_EGLIBC_LOCALE_CODE
2762+/* When locale code is enabled, these are each defined in the
2763+ appropriate lc-CATEGORY.c file, so that static links (when __thread
2764+ is supported) bring in only those lc-CATEGORY.o files for
2765+ categories the program actually uses; look for NL_CURRENT_INDIRECT
2766+ in localeinfo.h.
2767+
2768+ When locale code is disabled, the _nl_C_CATEGORY objects are the
2769+ only possible referents. At the moment, there isn't a way to get
2770+ __OPTION_EGLIBC_LOCALE_CODE defined in every compilation unit that
2771+ #includes localeinfo.h, so we can't just turn off
2772+ NL_CURRENT_INDIRECT. So we'll define the _nl_current_CATEGORY
2773+ pointers here. */
2774+#if defined (NL_CURRENT_INDIRECT)
2775+#define DEFINE_CATEGORY(category, category_name, items, a) \
2776+ __thread struct __locale_data * const *_nl_current_##category \
2777+ attribute_hidden = &_nl_C_locobj.__locales[category];
2778+#include "categories.def"
2779+#undef DEFINE_CATEGORY
2780+#endif
2781+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
2782diff --git a/localedata/Makefile b/localedata/Makefile
2783index ebf6ac9..1870753 100644
2784--- a/localedata/Makefile
2785+++ b/localedata/Makefile
2786@@ -21,12 +21,22 @@ subdir := localedata
2787
2788 include ../Makeconfig
2789
2790-# List with all available character set descriptions.
2791-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
2792+include ../option-groups.mak
2793
2794 # List with all available character set descriptions.
2795-locales := $(wildcard locales/*)
2796-
2797+all-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
2798+
2799+all-locales := $(wildcard locales/*)
2800+
2801+# If the EGLIBC_LOCALES option group is not enabled, trim the
2802+# list of charmap and locale source files.
2803+ifeq ($(OPTION_EGLIBC_LOCALES),y)
2804+charmaps := $(all-charmaps)
2805+locales := $(all-locales)
2806+else
2807+charmaps :=
2808+locales := locales/POSIX
2809+endif
2810
2811 subdir-dirs = tests-mbwc
2812 vpath %.c tests-mbwc
2813@@ -71,14 +81,20 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl \
2814 tst_wcsxfrm tst_wctob tst_wctomb tst_wctrans \
2815 tst_wctype tst_wcwidth
2816
2817-tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
2818+# Since these tests build their own locale files, they're not
2819+# dependent on the OPTION_EGLIBC_LOCALES option group. But they do
2820+# need the locale functions to be present.
2821+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
2822+ += $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
2823 tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \
2824 tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
2825 tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \
2826 tst-wctype
2827+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
2828 tests-static = bug-setlocale1-static
2829 tests += $(tests-static)
2830-ifeq (yes,$(build-shared))
2831+endif
2832+ifeq (yesy,$(build-shared)$(OPTION_EGLIBC_LOCALE_CODE))
2833 ifneq (no,$(PERL))
2834 tests-special += $(objpfx)mtrace-tst-leaks.out
2835 endif
2836@@ -95,6 +111,7 @@ tests: $(objdir)/iconvdata/gconv-modules
2837 tests-static += tst-langinfo-static
2838
2839 ifeq ($(run-built-tests),yes)
2840+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
2841 tests-special += $(objpfx)sort-test.out $(objpfx)tst-fmon.out \
2842 $(objpfx)tst-locale.out $(objpfx)tst-rpmatch.out \
2843 $(objpfx)tst-trans.out $(objpfx)tst-ctype.out \
2844@@ -109,6 +126,7 @@ LOCALES := de_DE.ISO-8859-1 de_DE.UTF-8 en_US.ANSI_X3.4-1968 \
2845 tr_TR.ISO-8859-9 en_GB.UTF-8 uk_UA.UTF-8
2846 include ../gen-locales.mk
2847 endif
2848+endif
2849
2850 include ../Rules
2851
2852@@ -191,6 +209,11 @@ endif
2853
2854 include SUPPORTED
2855
2856+# Only install locale data if OPTION_EGLIBC_LOCALES is selected.
2857+ifneq ($(OPTION_EGLIBC_LOCALES),y)
2858+SUPPORTED-LOCALES :=
2859+endif
2860+
2861 INSTALL-SUPPORTED-LOCALES=$(addprefix install-, $(SUPPORTED-LOCALES))
2862
2863 # Sometimes the whole collection of locale files should be installed.
2864diff --git a/login/Makefile b/login/Makefile
2865index 0f4bb22..4036ddb 100644
2866--- a/login/Makefile
2867+++ b/login/Makefile
2868@@ -18,6 +18,7 @@
2869 #
2870 # Sub-makefile for login portion of the library.
2871 #
2872+include ../option-groups.mak
2873
2874 subdir := login
2875
2876@@ -25,14 +26,16 @@ include ../Makeconfig
2877
2878 headers := utmp.h bits/utmp.h lastlog.h pty.h
2879
2880-routines := getlogin getlogin_r setlogin getlogin_r_chk \
2881- getutent getutent_r getutid getutline getutid_r getutline_r \
2882- utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
2883- ptsname_r_chk
2884+routines := getpt grantpt unlockpt ptsname ptsname_r_chk
2885+routines-$(OPTION_EGLIBC_UTMP) \
2886+ += getutent getutent_r getutid getutline getutid_r getutline_r \
2887+ utmp_file utmpname updwtmp
2888+routines-$(OPTION_EGLIBC_GETLOGIN) += getlogin getlogin_r getlogin_r_chk
2889+routines-$(OPTION_EGLIBC_BSD) += setlogin
2890
2891 CFLAGS-grantpt.c = -DLIBEXECDIR='"$(libexecdir)"'
2892
2893-others = utmpdump
2894+others-$(OPTION_EGLIBC_UTMP) += utmpdump
2895
2896 ifeq (yes,$(build-pt-chown))
2897 others += pt_chown
2898@@ -46,8 +49,8 @@ vpath %.c programs
2899 tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin
2900
2901 # Build the -lutil library with these extra functions.
2902-extra-libs := libutil
2903-extra-libs-others := $(extra-libs)
2904+extra-libs-$(OPTION_EGLIBC_UTMP) := libutil
2905+extra-libs-others := $(extra-libs-y)
2906
2907 libutil-routines:= login login_tty logout logwtmp openpty forkpty
2908
2909diff --git a/malloc/Makefile b/malloc/Makefile
2910index 67ed293..272ca4d 100644
2911--- a/malloc/Makefile
2912+++ b/malloc/Makefile
2913@@ -18,6 +18,8 @@
2914 #
2915 # Makefile for malloc routines
2916 #
2917+include ../option-groups.mak
2918+
2919 subdir := malloc
2920
2921 include ../Makeconfig
2922@@ -39,9 +41,15 @@ install-lib := libmcheck.a
2923 non-lib.a := libmcheck.a
2924
2925 # Additional library.
2926+ifeq ($(OPTION_EGLIBC_MEMUSAGE),y)
2927 extra-libs = libmemusage
2928 extra-libs-others = $(extra-libs)
2929
2930+ifdef OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
2931+CPPFLAGS-memusage += -D__OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE=$(OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE)
2932+endif
2933+endif
2934+
2935 libmemusage-routines = memusage
2936 libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
2937
2938@@ -71,7 +79,7 @@ endif
2939 # Unless we get a test for the availability of libgd which also works
2940 # for cross-compiling we disable the memusagestat generation in this
2941 # situation.
2942-ifneq ($(cross-compiling),yes)
2943+ifeq ($(cross-compiling)$(OPTION_EGLIBC_MEMUSAGE),noy)
2944 # If the gd library is available we build the `memusagestat' program.
2945 ifneq ($(LIBGD),no)
2946 others: $(objpfx)memusage
2947diff --git a/malloc/memusage.c b/malloc/memusage.c
2948index a57ba8e..732ba9d 100644
2949--- a/malloc/memusage.c
2950+++ b/malloc/memusage.c
2951@@ -33,6 +33,7 @@
2952 #include <stdint.h>
2953 #include <sys/mman.h>
2954 #include <sys/time.h>
2955+#include <gnu/option-groups.h>
2956
2957 #include <memusage.h>
2958
2959@@ -93,7 +94,11 @@ static __thread uintptr_t start_sp;
2960 #define peak_stack peak_use[1]
2961 #define peak_total peak_use[2]
2962
2963-#define DEFAULT_BUFFER_SIZE 32768
2964+#ifndef __OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
2965+# define DEFAULT_BUFFER_SIZE 32768
2966+#else
2967+# define DEFAULT_BUFFER_SIZE __OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
2968+#endif
2969 static size_t buffer_size;
2970
2971 static int fd = -1;
2972diff --git a/malloc/memusage.sh b/malloc/memusage.sh
2973index 8ab8cc2..d18f446 100755
2974--- a/malloc/memusage.sh
2975+++ b/malloc/memusage.sh
2976@@ -35,7 +35,7 @@ do_missing_arg() {
2977
2978 # Print help message
2979 do_help() {
2980- echo $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
2981+ printf $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
2982 Profile memory usage of PROGRAM.
2983
2984 -n,--progname=NAME Name of the program file to profile
2985diff --git a/math/Makefile b/math/Makefile
2986index 6388bae..ed1c511 100644
2987--- a/math/Makefile
2988+++ b/math/Makefile
2989@@ -21,6 +21,8 @@ subdir := math
2990
2991 include ../Makeconfig
2992
2993+include ../option-groups.mak
2994+
2995 # Installed header files.
2996 headers := math.h bits/mathcalls.h bits/mathinline.h bits/huge_val.h \
2997 bits/huge_valf.h bits/huge_vall.h bits/inf.h bits/nan.h \
2998@@ -34,8 +36,8 @@ aux := setfpucw fpu_control
2999
3000 # Build the -lm library.
3001
3002-extra-libs := libm
3003-extra-libs-others = $(extra-libs)
3004+extra-libs-$(OPTION_EGLIBC_LIBM) := libm
3005+extra-libs-others-$(OPTION_EGLIBC_LIBM) = $(extra-libs-$(OPTION_EGLIBC_LIBM))
3006
3007 libm-support = s_lib_version s_matherr s_signgam \
3008 fclrexcpt fgetexcptflg fraiseexcpt fsetexcptflg \
3009diff --git a/misc/Makefile b/misc/Makefile
3010index aecb0da..e6b7c23 100644
3011--- a/misc/Makefile
3012+++ b/misc/Makefile
3013@@ -19,6 +19,10 @@
3014 # Sub-makefile for misc portion of the library.
3015 #
3016
3017+# Some system-dependent implementations of these functions use option
3018+# groups (see sysdeps/unix/sysv/linux/Makefile, for example).
3019+include ../option-groups.mak
3020+
3021 subdir := misc
3022
3023 include ../Makeconfig
3024@@ -46,40 +50,47 @@ routines := brk sbrk sstk ioctl \
3025 select pselect \
3026 acct chroot fsync sync fdatasync syncfs reboot \
3027 gethostid sethostid \
3028- revoke vhangup \
3029+ vhangup \
3030 swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \
3031 mkostemp mkostemp64 mkstemps mkstemps64 mkostemps mkostemps64 \
3032 ualarm usleep \
3033 gtty stty \
3034 ptrace \
3035- fstab mntent mntent_r \
3036+ mntent mntent_r \
3037 utimes lutimes futimes futimesat \
3038 truncate ftruncate truncate64 ftruncate64 \
3039- chflags fchflags \
3040 insremque getttyent getusershell getpass ttyslot \
3041 syslog syscall daemon \
3042 mmap mmap64 munmap mprotect msync madvise mincore remap_file_pages\
3043 mlock munlock mlockall munlockall \
3044- efgcvt efgcvt_r qefgcvt qefgcvt_r \
3045 hsearch hsearch_r tsearch lsearch \
3046 err error ustat \
3047- getsysstats dirname regexp \
3048+ getsysstats dirname \
3049 getloadavg getclktck \
3050 fgetxattr flistxattr fremovexattr fsetxattr getxattr \
3051 listxattr lgetxattr llistxattr lremovexattr lsetxattr \
3052 removexattr setxattr getauxval ifunc-impl-list
3053
3054+routines-$(OPTION_POSIX_REGEXP) += regexp
3055+routines-$(OPTION_EGLIBC_FSTAB) += fstab
3056+routines-$(OPTION_EGLIBC_BSD) += chflags fchflags revoke
3057+routines-$(OPTION_EGLIBC_FCVT) += efgcvt efgcvt_r qefgcvt qefgcvt_r
3058+
3059 generated += tst-error1.mtrace tst-error1-mem.out
3060
3061 aux := init-misc
3062 install-lib := libg.a
3063 gpl2lgpl := error.c error.h
3064
3065-tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
3066- tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
3067+tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
3068+ tst-pselect tst-insremque tst-mntent2 bug-hsearch1
3069+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += tst-error1
3070+tests-$(OPTION_EGLIBC_FCVT) += tst-efgcvt
3071 ifeq ($(run-built-tests),yes)
3072+ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
3073 tests-special += $(objpfx)tst-error1-mem.out
3074 endif
3075+endif
3076
3077 CFLAGS-select.c = -fexceptions -fasynchronous-unwind-tables
3078 CFLAGS-tsearch.c = $(uses-callbacks)
3079diff --git a/misc/err.c b/misc/err.c
3080index 7b98157..efce8d5 100644
3081--- a/misc/err.c
3082+++ b/misc/err.c
3083@@ -22,6 +22,7 @@
3084 #include <errno.h>
3085 #include <string.h>
3086 #include <stdio.h>
3087+#include <gnu/option-groups.h>
3088
3089 #include <wchar.h>
3090 #define flockfile(s) _IO_flockfile (s)
3091@@ -37,6 +38,7 @@ extern char *__progname;
3092 va_end (ap); \
3093 }
3094
3095+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
3096 static void
3097 convert_and_print (const char *format, __gnuc_va_list ap)
3098 {
3099@@ -81,6 +83,7 @@ convert_and_print (const char *format, __gnuc_va_list ap)
3100
3101 __vfwprintf (stderr, wformat, ap);
3102 }
3103+#endif
3104
3105 void
3106 vwarnx (const char *format, __gnuc_va_list ap)
3107@@ -88,9 +91,13 @@ vwarnx (const char *format, __gnuc_va_list ap)
3108 flockfile (stderr);
3109 if (_IO_fwide (stderr, 0) > 0)
3110 {
3111+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
3112 __fwprintf (stderr, L"%s: ", __progname);
3113 convert_and_print (format, ap);
3114 putwc_unlocked (L'\n', stderr);
3115+#else
3116+ abort ();
3117+#endif
3118 }
3119 else
3120 {
3121@@ -111,6 +118,7 @@ vwarn (const char *format, __gnuc_va_list ap)
3122 flockfile (stderr);
3123 if (_IO_fwide (stderr, 0) > 0)
3124 {
3125+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
3126 __fwprintf (stderr, L"%s: ", __progname);
3127 if (format)
3128 {
3129@@ -119,6 +127,9 @@ vwarn (const char *format, __gnuc_va_list ap)
3130 }
3131 __set_errno (error);
3132 __fwprintf (stderr, L"%m\n");
3133+#else
3134+ abort ();
3135+#endif
3136 }
3137 else
3138 {
3139diff --git a/misc/error.c b/misc/error.c
3140index aaa120d..d6cbc82 100644
3141--- a/misc/error.c
3142+++ b/misc/error.c
3143@@ -35,6 +35,7 @@
3144 #endif
3145
3146 #ifdef _LIBC
3147+# include <gnu/option-groups.h>
3148 # include <libintl.h>
3149 # include <stdbool.h>
3150 # include <stdint.h>
3151@@ -205,6 +206,7 @@ error_tail (int status, int errnum, const char *message, va_list args)
3152 #if _LIBC
3153 if (_IO_fwide (stderr, 0) > 0)
3154 {
3155+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
3156 size_t len = strlen (message) + 1;
3157 wchar_t *wmessage = NULL;
3158 mbstate_t st;
3159@@ -265,6 +267,9 @@ error_tail (int status, int errnum, const char *message, va_list args)
3160
3161 if (use_malloc)
3162 free (wmessage);
3163+#else
3164+ abort ();
3165+#endif
3166 }
3167 else
3168 #endif
3169diff --git a/misc/tst-efgcvt.c b/misc/tst-efgcvt.c
3170index 5083fec..79ed36c 100644
3171--- a/misc/tst-efgcvt.c
3172+++ b/misc/tst-efgcvt.c
3173@@ -59,7 +59,7 @@ static testcase ecvt_tests[] =
3174 { 123.01, -4, 3, "" },
3175 { 126.71, -4, 3, "" },
3176 { 0.0, 4, 1, "0000" },
3177-#if DBL_MANT_DIG == 53
3178+#if DBL_MANT_DIG == 53 && !(defined __powerpc__ && defined __NO_FPRS__ && !defined _SOFT_FLOAT && !defined _SOFT_DOUBLE)
3179 { 0x1p-1074, 3, -323, "494" },
3180 { -0x1p-1074, 3, -323, "494" },
3181 #endif
3182diff --git a/nis/Makefile b/nis/Makefile
3183index 037e674..c967850 100644
3184--- a/nis/Makefile
3185+++ b/nis/Makefile
3186@@ -18,6 +18,8 @@
3187 #
3188 # Makefile for NIS/NIS+ part.
3189 #
3190+include ../option-groups.mak
3191+
3192 subdir := nis
3193
3194 include ../Makeconfig
3195@@ -30,19 +32,26 @@ endif
3196
3197 # These are the databases available for the nis (and perhaps later nisplus)
3198 # service. This must be a superset of the services in nss.
3199-databases = proto service hosts network grp pwd rpc ethers \
3200- spwd netgrp alias publickey
3201+databases-y := proto service hosts network grp pwd rpc ethers \
3202+ spwd netgrp publickey
3203+databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
3204
3205 # Specify rules for the nss_* modules.
3206-services := nis nisplus compat
3207+# The 'compat' module includes nis support, and the 'nss' directory
3208+# includes a bare-bones "files" library, so we'll include 'compat' in
3209+# OPTION_EGLIBC_NIS.
3210+services-y :=
3211+services-$(OPTION_EGLIBC_NIS) += nis nisplus compat
3212+
3213+extra-libs-$(OPTION_EGLIBC_NIS) += libnsl
3214+extra-libs-y += $(services-y:%=libnss_%)
3215
3216-extra-libs = libnsl $(services:%=libnss_%)
3217 # These libraries will be built in the `others' pass rather than
3218 # the `lib' pass, because they depend on libc.so being built already.
3219-extra-libs-others = $(extra-libs)
3220+extra-libs-others-y += $(extra-libs-y)
3221
3222 # The sources are found in the appropriate subdir.
3223-subdir-dirs = $(services:%=nss_%)
3224+subdir-dirs = $(services-y:%=nss_%)
3225 vpath %.c $(subdir-dirs)
3226
3227 libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
3228@@ -60,11 +69,11 @@ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
3229 libnss_compat-routines := $(addprefix compat-,grp pwd spwd initgroups)
3230 libnss_compat-inhibit-o = $(filter-out .os,$(object-suffixes))
3231
3232-libnss_nis-routines := $(addprefix nis-,$(databases)) nis-initgroups \
3233+libnss_nis-routines := $(addprefix nis-,$(databases-y)) nis-initgroups \
3234 nss-nis
3235 libnss_nis-inhibit-o = $(filter-out .os,$(object-suffixes))
3236
3237-libnss_nisplus-routines := $(addprefix nisplus-,$(databases)) nisplus-parser \
3238+libnss_nisplus-routines := $(addprefix nisplus-,$(databases-y)) nisplus-parser \
3239 nss-nisplus nisplus-initgroups
3240 libnss_nisplus-inhibit-o = $(filter-out .os,$(object-suffixes))
3241
3242@@ -80,12 +89,12 @@ libnsl-libc = $(common-objpfx)linkobj/libc.so
3243 # Target-specific variable setting to link objects using deprecated
3244 # RPC interfaces with the version of libc.so that makes them available
3245 # for new links:
3246-$(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
3247+$(services-y:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
3248 libc-for-link = $(libnsl-libc)
3249
3250
3251 ifeq ($(build-shared),yes)
3252-$(others:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
3253+$(others-y:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
3254 else
3255-$(others:%=$(objpfx)%): $(objpfx)libnsl.a
3256+$(others-y:%=$(objpfx)%): $(objpfx)libnsl.a
3257 endif
3258diff --git a/nptl/Makefile b/nptl/Makefile
3259index aaca0a4..596ca3c 100644
3260--- a/nptl/Makefile
3261+++ b/nptl/Makefile
3262@@ -18,6 +18,8 @@
3263 #
3264 # Sub-makefile for NPTL portion of the library.
3265 #
3266+include ../option-groups.mak
3267+
3268 subdir := nptl
3269
3270 include ../Makeconfig
3271@@ -118,7 +120,7 @@ libpthread-routines = nptl-init vars events version pt-interp \
3272 pt-raise pt-system \
3273 flockfile ftrylockfile funlockfile \
3274 sigaction \
3275- herrno res pt-allocrtsig \
3276+ pt-allocrtsig \
3277 pthread_kill_other_threads \
3278 pthread_getaffinity pthread_setaffinity \
3279 pthread_attr_getaffinity pthread_attr_setaffinity \
3280@@ -138,8 +140,10 @@ libpthread-routines = nptl-init vars events version pt-interp \
3281 # pthread_setgid pthread_setegid pthread_setregid \
3282 # pthread_setresgid
3283
3284+libpthread-routines-$(OPTION_EGLIBC_INET) := herrno res
3285 libpthread-shared-only-routines = version pt-interp pt-allocrtsig \
3286 unwind-forcedunwind
3287+
3288 libpthread-static-only-routines = pthread_atfork
3289
3290 # Since cancellation handling is in large parts handled using exceptions
3291@@ -220,7 +224,7 @@ tests = tst-typesizes \
3292 tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
3293 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
3294 tst-mutexpi9 \
3295- tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
3296+ tst-spin1 tst-spin2 tst-spin3 \
3297 tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
3298 tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
3299 tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
3300@@ -256,14 +260,14 @@ tests = tst-typesizes \
3301 tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
3302 tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
3303 tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \
3304- tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 tst-cancel25 \
3305+ tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel25 \
3306 tst-cancel-self tst-cancel-self-cancelstate \
3307 tst-cancel-self-canceltype tst-cancel-self-testcancel \
3308 tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
3309 tst-flock1 tst-flock2 \
3310 tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
3311 tst-signal6 tst-signal7 \
3312- tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
3313+ tst-exec2 tst-exec3 tst-exec4 \
3314 tst-exit1 tst-exit2 tst-exit3 \
3315 tst-stdio1 tst-stdio2 \
3316 tst-stack1 tst-stack2 tst-stack3 tst-stack4 tst-pthread-getattr \
3317@@ -271,13 +275,12 @@ tests = tst-typesizes \
3318 tst-unload \
3319 tst-dlsym1 \
3320 tst-sysconf \
3321- tst-locale1 tst-locale2 \
3322+ tst-locale2 \
3323 tst-umask1 \
3324 tst-popen1 \
3325 tst-clock1 \
3326 tst-context1 \
3327 tst-sched1 \
3328- tst-backtrace1 \
3329 tst-abstime \
3330 tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
3331 tst-getpid3 \
3332@@ -288,9 +291,16 @@ xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
3333 tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
3334 test-srcs = tst-oddstacklimit
3335
3336-# Test expected to fail on most targets (except x86_64) due to bug
3337-# 18435 - pthread_once hangs when init routine throws an exception.
3338-test-xfail-tst-once5 = yes
3339+# This test uses the posix_spawn functions.
3340+tests-$(OPTION_EGLIBC_SPAWN) += tst-exec1
3341+
3342+# This test uses the 'backtrace' functions.
3343+tests-$(OPTION_EGLIBC_BACKTRACE) += tst-backtrace1
3344+
3345+# This test is written in C++.
3346+tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24
3347+
3348+tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-locale1
3349
3350 # Files which must not be linked with libpthread.
3351 tests-nolibpthread = tst-unload
3352diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
3353index d10f4ea..14257ce 100644
3354--- a/nptl/pthread_create.c
3355+++ b/nptl/pthread_create.c
3356@@ -33,6 +33,7 @@
3357 #include <default-sched.h>
3358 #include <futex-internal.h>
3359
3360+#include <gnu/option-groups.h>
3361 #include <shlib-compat.h>
3362
3363 #include <stap-probe.h>
3364@@ -262,8 +263,10 @@ START_THREAD_DEFN
3365 THREAD_SETMEM (pd, cpuclock_offset, now);
3366 #endif
3367
3368+#if __OPTION_EGLIBC_INET
3369 /* Initialize resolver state pointer. */
3370 __resp = &pd->res;
3371+#endif
3372
3373 /* Initialize pointers to locale data. */
3374 __ctype_init ();
3375@@ -346,8 +349,10 @@ START_THREAD_DEFN
3376 /* Run the destructor for the thread-local data. */
3377 __nptl_deallocate_tsd ();
3378
3379+#if __OPTION_EGLIBC_INET
3380 /* Clean up any state libc stored in thread-local variables. */
3381 __libc_thread_freeres ();
3382+#endif
3383
3384 /* If this is the last thread we terminate the process now. We
3385 do not notify the debugger, it might just irritate it if there
3386diff --git a/nscd/Makefile b/nscd/Makefile
3387index ede941d..f4f3f8d 100644
3388--- a/nscd/Makefile
3389+++ b/nscd/Makefile
3390@@ -18,14 +18,17 @@
3391 #
3392 # Sub-makefile for nscd portion of the library.
3393 #
3394+include ../option-groups.mak
3395+
3396 subdir := nscd
3397
3398 include ../Makeconfig
3399
3400 ifneq ($(use-nscd),no)
3401-routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
3402+routines-$(OPTION_EGLIBC_INET) += \
3403+ nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
3404 nscd_initgroups nscd_getserv_r nscd_netgroup
3405-aux := nscd_helper
3406+aux-$(OPTION_EGLIBC_INET) += nscd_helper
3407 endif
3408
3409 # To find xmalloc.c
3410@@ -37,14 +40,18 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
3411 dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
3412 xmalloc xstrdup aicache initgrcache gai res_hconf \
3413 netgroupcache
3414-
3415+ifneq (y,$(OPTION_EGLIBC_NIS))
3416+# If we haven't build libnsl.so, then we'll need to include our
3417+# own copy of nis_hash.
3418+nscd-modules += nis_hash
3419+endif
3420 ifeq ($(build-nscd)$(have-thread-library),yesyes)
3421
3422-others += nscd
3423-others-pie += nscd
3424-install-sbin := nscd
3425+others-$(OPTION_EGLIBC_INET) += nscd
3426+others-pie-$(OPTION_EGLIBC_INET) += nscd
3427+install-sbin-$(OPTION_EGLIBC_INET) += nscd
3428
3429-extra-objs = $(nscd-modules:=.o)
3430+extra-objs-$(OPTION_EGLIBC_INET) += $(nscd-modules:=.o)
3431
3432 endif
3433
3434@@ -100,7 +107,15 @@ include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
3435 $(objpfx)nscd: $(nscd-modules:%=$(objpfx)%.o)
3436
3437 ifeq ($(build-shared),yes)
3438-$(objpfx)nscd: $(shared-thread-library) $(common-objpfx)nis/libnsl.so
3439+$(objpfx)nscd: $(shared-thread-library)
3440+else
3441+$(objpfx)nscd: $(static-thread-library)
3442+endif
3443+
3444+ifeq (y,$(OPTION_EGLIBC_NIS))
3445+ifeq ($(build-shared),yes)
3446+$(objpfx)nscd: $(common-objpfx)nis/libnsl.so
3447 else
3448-$(objpfx)nscd: $(static-thread-library) $(common-objpfx)nis/libnsl.a
3449+$(objpfx)nscd: $(common-objpfx)nis/libnsl.a
3450+endif
3451 endif
3452diff --git a/nscd/nis_hash.c b/nscd/nis_hash.c
3453new file mode 100644
3454index 0000000..d244c41
3455--- /dev/null
3456+++ b/nscd/nis_hash.c
3457@@ -0,0 +1,3 @@
3458+/* If OPTION_EGLIBC_NIS is disabled, nscd can't get this from libnsl.so;
3459+ we need our own copy. */
3460+#include "../nis/nis_hash.c"
3461diff --git a/nss/Makefile b/nss/Makefile
3462index 65ab7b5..19f0aef 100644
3463--- a/nss/Makefile
3464+++ b/nss/Makefile
3465@@ -18,28 +18,35 @@
3466 #
3467 # Makefile for name service switch.
3468 #
3469+include ../option-groups.mak
3470+
3471 subdir := nss
3472
3473 include ../Makeconfig
3474
3475 headers := nss.h
3476
3477-# This is the trivial part which goes into libc itself.
3478-routines = nsswitch getnssent getnssent_r digits_dots \
3479- $(addsuffix -lookup,$(databases))
3480-
3481 # These are the databases that go through nss dispatch.
3482 # Caution: if you add a database here, you must add its real name
3483 # in databases.def, too.
3484-databases = proto service hosts network grp pwd ethers \
3485- spwd netgrp alias sgrp
3486+databases-y = grp pwd spwd sgrp
3487+databases-$(OPTION_EGLIBC_INET) \
3488+ += proto service hosts network ethers \
3489+ netgrp
3490+databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
3491+
3492+routines-$(OPTION_EGLIBC_INET) += digits_dots
3493
3494 ifneq (,$(filter sunrpc,$(subdirs)))
3495-databases += key rpc
3496+databases-$(OPTION_EGLIBC_INET) += key rpc
3497 have-sunrpc := 1
3498 else
3499 have-sunrpc := 0
3500 endif
3501+# This is the trivial part which goes into libc itself.
3502+routines-y += nsswitch getnssent getnssent_r \
3503+ $(addsuffix -lookup,$(databases-y))
3504+
3505 CPPFLAGS-getent.c = -DHAVE_SUNRPC=$(have-sunrpc)
3506
3507 others := getent makedb
3508@@ -47,8 +54,9 @@ install-bin := getent makedb
3509 makedb-modules = xmalloc hash-string
3510 extra-objs += $(makedb-modules:=.o)
3511
3512-tests = test-netdb tst-nss-test1 test-digits-dots tst-nss-getpwent
3513-xtests = bug-erange
3514+tests = tst-nss-test1 tst-nss-getpwent
3515+tests-$(OPTION_EGLIBC_INET) += test-netdb test-digits-dots
3516+xtests-$(OPTION_EGLIBC_INET) += bug-erange
3517
3518 # Specify rules for the nss_* modules. We have some services.
3519 services := files db
3520@@ -63,7 +71,7 @@ subdir-dirs = $(services:%=nss_%)
3521 vpath %.c $(subdir-dirs) ../locale/programs ../intl
3522
3523
3524-libnss_files-routines := $(addprefix files-,$(databases)) \
3525+libnss_files-routines := $(addprefix files-,$(databases-y)) \
3526 files-initgroups files-have_o_cloexec files-init
3527
3528 libnss_db-dbs := $(addprefix db-,\
3529@@ -86,6 +94,45 @@ tests-static = tst-nss-static
3530 tests += $(tests-static)
3531 endif
3532
3533+ifneq ($(OPTION_EGLIBC_NSSWITCH),y)
3534+
3535+ifndef OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG
3536+$(error OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG variable left unset)
3537+endif
3538+
3539+ifndef OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS
3540+$(error OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS variable left unset)
3541+endif
3542+
3543+ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)))
3544+$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed config file)
3545+$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG))
3546+endif
3547+
3548+ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)))
3549+$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed functions file)
3550+$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS))
3551+endif
3552+
3553+before-compile := $(objpfx)fixed-nsswitch.h
3554+generated := fixed-nsswitch.h
3555+$(objpfx)fixed-nsswitch.h $(objfpx)fixed-nsswitch-libs: \
3556+ $(objpfx)gen-fixed-nsswitch \
3557+ $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
3558+ $< $(objpfx)fixed-nsswitch.h \
3559+ $(objpfx)fixed-nsswitch-libs \
3560+ $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
3561+
3562+$(objpfx)gen-fixed-nsswitch: gen-fixed-nsswitch.c \
3563+ $(common-objpfx)option-groups.config \
3564+ $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)
3565+ $(native-compile)
3566+gen-fixed-nsswitch-CFLAGS = \
3567+ -g3 -O -Wall \
3568+ -I $(objpfx) \
3569+ -DFIXED_FUNCTIONS='"$(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)"'
3570+endif
3571+
3572 include ../Rules
3573
3574 ifeq (yes,$(have-selinux))
3575diff --git a/nss/fixed-nsswitch.conf b/nss/fixed-nsswitch.conf
3576new file mode 100644
3577index 0000000..91bb675
3578--- /dev/null
3579+++ b/nss/fixed-nsswitch.conf
3580@@ -0,0 +1,22 @@
3581+# /etc/nsswitch.conf
3582+#
3583+# Example configuration for fixed name service.
3584+# See the description of OPTION_EGLIBC_NSSWITCH in option-groups.def
3585+# for details.
3586+#
3587+
3588+aliases: files
3589+
3590+passwd: files
3591+group: files
3592+shadow: files
3593+
3594+hosts: files dns
3595+networks: files dns
3596+
3597+protocols: files
3598+services: files
3599+ethers: files
3600+rpc: files
3601+
3602+netgroup: files
3603diff --git a/nss/fixed-nsswitch.functions b/nss/fixed-nsswitch.functions
3604new file mode 100644
3605index 0000000..2f3fa83
3606--- /dev/null
3607+++ b/nss/fixed-nsswitch.functions
3608@@ -0,0 +1,121 @@
3609+/* List of functions defined for fixed NSS in GNU C Library.
3610+ Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
3611+ This file is part of the GNU C Library.
3612+
3613+ The GNU C Library is free software; you can redistribute it and/or
3614+ modify it under the terms of the GNU Lesser General Public
3615+ License as published by the Free Software Foundation; either
3616+ version 2.1 of the License, or (at your option) any later version.
3617+
3618+ The GNU C Library is distributed in the hope that it will be useful,
3619+ but WITHOUT ANY WARRANTY; without even the implied warranty of
3620+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3621+ Lesser General Public License for more details.
3622+
3623+ You should have received a copy of the GNU Lesser General Public
3624+ License along with the GNU C Library; if not, write to the Free
3625+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3626+ 02111-1307 USA. */
3627+
3628+/* When OPTION_EGLIBC_NSSWITCH is disabled (see option-groups.def),
3629+ EGLIBC does not use the 'dlopen' and 'dlsym' functions to look for
3630+ database query functions in the individual name service libraries.
3631+ Instead, it uses a set of functions chosen at compile time, as
3632+ directed by the OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS file. This
3633+ file is a sample of what you might use there.
3634+
3635+ This file is C source code; it should only contain invocations of
3636+ the following macros:
3637+
3638+ - DEFINE_ENT (DATABASE, SERVICE, X)
3639+
3640+ Declare the 'setXent', 'getXent_r', and 'endXent' functions that
3641+ query DATABASE using the service library 'libnss_SERVICE.so.2'.
3642+ DATABASE should be the full name of the database as it appears in
3643+ 'nsswitch.conf', like 'passwd' or 'aliases'.
3644+
3645+ (The non-reentrant 'getXent' functions are implemented in terms
3646+ of the reentrant 'getXent_r' functions, so there is no need to
3647+ refer to them explicitly here.)
3648+
3649+ - DEFINE_GETBY (DATABASE, SERVICE, X, KEY)
3650+
3651+ Declare the 'getXbyKEY_r' functions that query DATABASE using
3652+ SERVICE. DATABASE and SERVICE are as described above.
3653+
3654+ (The non-reentrant 'getXbyKEY' functions are implemented in terms
3655+ of the reentrant 'getXbyKEY_r' functions, so there is no need to
3656+ refer to them explicitly here.)
3657+
3658+ Use the special key 'name3' for the service library function that
3659+ implements the 'getaddrinfo' function.
3660+
3661+ - DEFINE_GET (DATABASE, SERVICE, QUERY)
3662+
3663+ Declare the 'getQUERY_r' functions that query DATABASE using
3664+ SERVICE. This is used for functions like 'getpwnam'.
3665+
3666+ (The non-reentrant 'getQUERY' functions are implemented in terms
3667+ of the reentrant 'getQUERY_r' functions, so there is no need to
3668+ refer to them explicitly here.)
3669+
3670+ This sample file only includes functions that consult the files in
3671+ '/etc', and the Domain Name System (DNS). */
3672+
3673+/* aliases */
3674+DEFINE_ENT (aliases, files, alias)
3675+DEFINE_GETBY (aliases, files, alias, name)
3676+
3677+/* ethers */
3678+DEFINE_ENT (ethers, files, ether)
3679+
3680+/* group */
3681+DEFINE_ENT (group, files, gr)
3682+DEFINE_GET (group, files, grgid)
3683+DEFINE_GET (group, files, grnam)
3684+
3685+/* hosts */
3686+DEFINE_ENT (hosts, files, host)
3687+DEFINE_GETBY (hosts, files, host, addr)
3688+DEFINE_GETBY (hosts, files, host, name)
3689+DEFINE_GETBY (hosts, files, host, name2)
3690+DEFINE_GET (hosts, files, hostton)
3691+DEFINE_GET (hosts, files, ntohost)
3692+DEFINE_GETBY (hosts, dns, host, addr)
3693+DEFINE_GETBY (hosts, dns, host, name)
3694+DEFINE_GETBY (hosts, dns, host, name2)
3695+DEFINE_GETBY (hosts, dns, host, name3)
3696+
3697+/* netgroup */
3698+DEFINE_ENT (netgroup, files, netgr)
3699+
3700+/* networks */
3701+DEFINE_ENT (networks, files, net)
3702+DEFINE_GETBY (networks, files, net, name)
3703+DEFINE_GETBY (networks, files, net, addr)
3704+DEFINE_GETBY (networks, dns, net, name)
3705+DEFINE_GETBY (networks, dns, net, addr)
3706+
3707+/* protocols */
3708+DEFINE_ENT (protocols, files, proto)
3709+DEFINE_GETBY (protocols, files, proto, name)
3710+DEFINE_GETBY (protocols, files, proto, number)
3711+
3712+/* passwd */
3713+DEFINE_ENT (passwd, files, pw)
3714+DEFINE_GET (passwd, files, pwnam)
3715+DEFINE_GET (passwd, files, pwuid)
3716+
3717+/* rpc */
3718+DEFINE_ENT (rpc, files, rpc)
3719+DEFINE_GETBY (rpc, files, rpc, name)
3720+DEFINE_GETBY (rpc, files, rpc, number)
3721+
3722+/* services */
3723+DEFINE_ENT (services, files, serv)
3724+DEFINE_GETBY (services, files, serv, name)
3725+DEFINE_GETBY (services, files, serv, port)
3726+
3727+/* shadow */
3728+DEFINE_ENT (shadow, files, sp)
3729+DEFINE_GET (shadow, files, spnam)
3730diff --git a/nss/gen-fixed-nsswitch.c b/nss/gen-fixed-nsswitch.c
3731new file mode 100644
3732index 0000000..6e1c98c
3733--- /dev/null
3734+++ b/nss/gen-fixed-nsswitch.c
3735@@ -0,0 +1,803 @@
3736+/* gen-fixed-nsswitch.c --- generate fixed name service data structures
3737+ Copyright (C) 1996-1999, 2001-2006, 2007 Free Software Foundation, Inc.
3738+ This file is part of the GNU C Library.
3739+
3740+ The GNU C Library is free software; you can redistribute it and/or
3741+ modify it under the terms of the GNU Lesser General Public
3742+ License as published by the Free Software Foundation; either
3743+ version 2.1 of the License, or (at your option) any later version.
3744+
3745+ The GNU C Library is distributed in the hope that it will be useful,
3746+ but WITHOUT ANY WARRANTY; without even the implied warranty of
3747+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3748+ Lesser General Public License for more details.
3749+
3750+ You should have received a copy of the GNU Lesser General Public
3751+ License along with the GNU C Library; if not, write to the Free
3752+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3753+ 02111-1307 USA. */
3754+
3755+#define _GNU_SOURCE
3756+
3757+#include <stdlib.h>
3758+#include <stdio.h>
3759+#include <errno.h>
3760+#include <string.h>
3761+#include <stdarg.h>
3762+#include <assert.h>
3763+#include <ctype.h>
3764+
3765+#include "gnu/lib-names.h"
3766+#include "nss.h"
3767+
3768+/* Provide a fallback definition to allow this file to be compiled outside
3769+ libc. */
3770+#ifndef internal_function
3771+# define internal_function
3772+#endif
3773+
3774+
3775+/* Simple utilities. */
3776+
3777+void __attribute__ ((noreturn))
3778+error (const char *message)
3779+{
3780+ fprintf (stderr, "%s\n", message);
3781+ exit (1);
3782+}
3783+
3784+
3785+void *
3786+check_alloc (void *p)
3787+{
3788+ if (p)
3789+ return p;
3790+ else
3791+ error ("out of memory");
3792+}
3793+
3794+void *
3795+xmalloc (size_t size)
3796+{
3797+ return check_alloc (malloc (size));
3798+}
3799+
3800+
3801+/* Format ARGS according to FORMAT, and return the result as a
3802+ malloc'ed string. */
3803+char *
3804+saprintf (const char *format, ...)
3805+{
3806+ va_list args;
3807+ size_t len;
3808+ char *buf;
3809+
3810+ va_start (args, format);
3811+ len = vsnprintf (NULL, 0, format, args);
3812+ va_end (args);
3813+
3814+ buf = xmalloc (len + 1);
3815+ va_start (args, format);
3816+ assert (len == vsnprintf (buf, len + 1, format, args));
3817+ va_end (args);
3818+
3819+ return buf;
3820+}
3821+
3822+
3823+
3824+/* Data structures representing the configuration file in memory. */
3825+
3826+/* These are copied from nsswitch.h.
3827+
3828+ We could simply #include that file, but this program runs on the
3829+ build machine and links against the build machine's libraries,
3830+ whereas that header is meant for use by target code; it uses
3831+ 'libc_hidden_proto', 'internal_function', and related hair. Since
3832+ we've copied the parsing code, we might as well copy the data
3833+ structure definitions as well. */
3834+
3835+/* Actions performed after lookup finished. */
3836+typedef enum
3837+{
3838+ NSS_ACTION_CONTINUE,
3839+ NSS_ACTION_RETURN
3840+} lookup_actions;
3841+
3842+
3843+typedef struct service_library
3844+{
3845+ /* Name of service (`files', `dns', `nis', ...). */
3846+ const char *name;
3847+ /* Pointer to the loaded shared library. */
3848+ void *lib_handle;
3849+ /* And the link to the next entry. */
3850+ struct service_library *next;
3851+} service_library;
3852+
3853+
3854+/* For mapping a function name to a function pointer. It is known in
3855+ nsswitch.c:nss_lookup_function that a string pointer for the lookup key
3856+ is the first member. */
3857+typedef struct
3858+{
3859+ const char *fct_name;
3860+ void *fct_ptr;
3861+} known_function;
3862+
3863+
3864+typedef struct service_user
3865+{
3866+ /* And the link to the next entry. */
3867+ struct service_user *next;
3868+ /* Action according to result. */
3869+ lookup_actions actions[5];
3870+ /* Link to the underlying library object. */
3871+ service_library *library;
3872+ /* Collection of known functions.
3873+
3874+ With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
3875+ 'tsearch'-style tree.
3876+
3877+ With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
3878+ pointers to known_function structures, NULL-terminated. */
3879+ union
3880+ {
3881+ void *tree;
3882+ const known_function **array;
3883+ } known;
3884+ /* Name of the service (`files', `dns', `nis', ...). */
3885+ const char *name;
3886+} service_user;
3887+
3888+/* To access the action based on the status value use this macro. */
3889+#define nss_next_action(ni, status) ((ni)->actions[2 + status])
3890+
3891+
3892+typedef struct name_database_entry
3893+{
3894+ /* And the link to the next entry. */
3895+ struct name_database_entry *next;
3896+ /* List of service to be used. */
3897+ service_user *service;
3898+ /* Name of the database. */
3899+ const char *name;
3900+} name_database_entry;
3901+
3902+
3903+typedef struct name_database
3904+{
3905+ /* List of all known databases. */
3906+ name_database_entry *entry;
3907+ /* List of libraries with service implementation. */
3908+ service_library *library;
3909+} name_database;
3910+
3911+
3912+
3913+/* Gathering the contents of the FIXED_FUNCTIONS file. */
3914+
3915+/* It should be possible to generate this list automatically by
3916+ looking at the services and databases used in the nsswitch.conf
3917+ file, and having a hard-coded set of queries supported on each
3918+ database. */
3919+
3920+/* We #include the FIXED_FUNCTIONS file several times to build an
3921+ array of function structures holding its data. */
3922+enum function_kind {
3923+ fk_end = 0, /* Last entry. */
3924+ fk_setent, /* Like setpwent. */
3925+ fk_getent, /* Like getpwent. */
3926+ fk_endent, /* Like endpwent. */
3927+ fk_getby, /* Like gethostbyname. */
3928+ fk_get /* Like getpwnam. */
3929+};
3930+
3931+
3932+struct function {
3933+ /* What kind of function this is. */
3934+ enum function_kind kind;
3935+
3936+ /* The database and service of the function being hardwired in. */
3937+ char *database, *service;
3938+
3939+ /* The kind of entry being queried, for 'fk_setent', 'fk_getent',
3940+ 'fk_endent', and 'fk_getby' functions. */
3941+ char *entry;
3942+
3943+ /* The key, for 'fk_getby' entries. */
3944+ char *key;
3945+
3946+ /* The value and key, for 'fk_get' entries. */
3947+ char *value_and_key;
3948+};
3949+
3950+
3951+const struct function functions[] =
3952+ {
3953+
3954+#define DEFINE_ENT(database, service, entry) \
3955+ { fk_setent, #database, #service, #entry }, \
3956+ { fk_getent, #database, #service, #entry }, \
3957+ { fk_endent, #database, #service, #entry },
3958+#define DEFINE_GETBY(database, service, entry, key) \
3959+ { fk_getby, #database, #service, #entry, #key },
3960+#define DEFINE_GET(database, service, value_and_key) \
3961+ { fk_get, #database, #service, NULL, NULL, #value_and_key },
3962+
3963+#include FIXED_FUNCTIONS
3964+
3965+#undef DEFINE_ENT
3966+#undef DEFINE_GETBY
3967+#undef DEFINE_GET
3968+
3969+ { fk_end }
3970+ };
3971+
3972+
3973+/* Parsing the config file. Functions copied from nsswitch.c. */
3974+
3975+#define __strchrnul strchrnul
3976+#define __getline getline
3977+#define __strncasecmp strncasecmp
3978+
3979+/* Prototypes for the local functions. */
3980+static name_database *nss_parse_file (const char *fname) internal_function;
3981+static name_database_entry *nss_getline (char *line) internal_function;
3982+static service_user *nss_parse_service_list (const char *line)
3983+ internal_function;
3984+
3985+static name_database *
3986+internal_function
3987+nss_parse_file (const char *fname)
3988+{
3989+ FILE *fp;
3990+ name_database *result;
3991+ name_database_entry *last;
3992+ char *line;
3993+ size_t len;
3994+
3995+ /* Open the configuration file. */
3996+ fp = fopen (fname, "rc");
3997+ if (fp == NULL)
3998+ return NULL;
3999+
4000+ // /* No threads use this stream. */
4001+ // __fsetlocking (fp, FSETLOCKING_BYCALLER);
4002+
4003+ result = (name_database *) xmalloc (sizeof (name_database));
4004+
4005+ result->entry = NULL;
4006+ result->library = NULL;
4007+ last = NULL;
4008+ line = NULL;
4009+ len = 0;
4010+ do
4011+ {
4012+ name_database_entry *this;
4013+ ssize_t n;
4014+
4015+ n = __getline (&line, &len, fp);
4016+ if (n < 0)
4017+ break;
4018+ if (line[n - 1] == '\n')
4019+ line[n - 1] = '\0';
4020+
4021+ /* Because the file format does not know any form of quoting we
4022+ can search forward for the next '#' character and if found
4023+ make it terminating the line. */
4024+ *__strchrnul (line, '#') = '\0';
4025+
4026+ /* If the line is blank it is ignored. */
4027+ if (line[0] == '\0')
4028+ continue;
4029+
4030+ /* Each line completely specifies the actions for a database. */
4031+ this = nss_getline (line);
4032+ if (this != NULL)
4033+ {
4034+ if (last != NULL)
4035+ last->next = this;
4036+ else
4037+ result->entry = this;
4038+
4039+ last = this;
4040+ }
4041+ }
4042+ while (!feof_unlocked (fp));
4043+
4044+ /* Free the buffer. */
4045+ free (line);
4046+ /* Close configuration file. */
4047+ fclose (fp);
4048+
4049+ return result;
4050+}
4051+
4052+
4053+/* Read the source names:
4054+ `( <source> ( "[" "!"? (<status> "=" <action> )+ "]" )? )*'
4055+ */
4056+static service_user *
4057+internal_function
4058+nss_parse_service_list (const char *line)
4059+{
4060+ service_user *result = NULL, **nextp = &result;
4061+
4062+ while (1)
4063+ {
4064+ service_user *new_service;
4065+ const char *name;
4066+
4067+ while (isspace (line[0]))
4068+ ++line;
4069+ if (line[0] == '\0')
4070+ /* No source specified. */
4071+ return result;
4072+
4073+ /* Read <source> identifier. */
4074+ name = line;
4075+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[')
4076+ ++line;
4077+ if (name == line)
4078+ return result;
4079+
4080+
4081+ new_service = (service_user *) xmalloc (sizeof (*new_service));
4082+ new_service->name = (char *) xmalloc (line - name + 1);
4083+
4084+ *((char *) __mempcpy ((char *) new_service->name, name, line - name))
4085+ = '\0';
4086+
4087+ /* Set default actions. */
4088+ new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
4089+ new_service->actions[2 + NSS_STATUS_UNAVAIL] = NSS_ACTION_CONTINUE;
4090+ new_service->actions[2 + NSS_STATUS_NOTFOUND] = NSS_ACTION_CONTINUE;
4091+ new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
4092+ new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
4093+ new_service->library = NULL;
4094+ new_service->known.tree = NULL;
4095+ new_service->next = NULL;
4096+
4097+ while (isspace (line[0]))
4098+ ++line;
4099+
4100+ if (line[0] == '[')
4101+ {
4102+ /* Read criterions. */
4103+ do
4104+ ++line;
4105+ while (line[0] != '\0' && isspace (line[0]));
4106+
4107+ do
4108+ {
4109+ int not;
4110+ enum nss_status status;
4111+ lookup_actions action;
4112+
4113+ /* Grok ! before name to mean all statii but that one. */
4114+ not = line[0] == '!';
4115+ if (not)
4116+ ++line;
4117+
4118+ /* Read status name. */
4119+ name = line;
4120+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
4121+ && line[0] != ']')
4122+ ++line;
4123+
4124+ /* Compare with known statii. */
4125+ if (line - name == 7)
4126+ {
4127+ if (__strncasecmp (name, "SUCCESS", 7) == 0)
4128+ status = NSS_STATUS_SUCCESS;
4129+ else if (__strncasecmp (name, "UNAVAIL", 7) == 0)
4130+ status = NSS_STATUS_UNAVAIL;
4131+ else
4132+ return result;
4133+ }
4134+ else if (line - name == 8)
4135+ {
4136+ if (__strncasecmp (name, "NOTFOUND", 8) == 0)
4137+ status = NSS_STATUS_NOTFOUND;
4138+ else if (__strncasecmp (name, "TRYAGAIN", 8) == 0)
4139+ status = NSS_STATUS_TRYAGAIN;
4140+ else
4141+ return result;
4142+ }
4143+ else
4144+ return result;
4145+
4146+ while (isspace (line[0]))
4147+ ++line;
4148+ if (line[0] != '=')
4149+ return result;
4150+ do
4151+ ++line;
4152+ while (isspace (line[0]));
4153+
4154+ name = line;
4155+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
4156+ && line[0] != ']')
4157+ ++line;
4158+
4159+ if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0)
4160+ action = NSS_ACTION_RETURN;
4161+ else if (line - name == 8
4162+ && __strncasecmp (name, "CONTINUE", 8) == 0)
4163+ action = NSS_ACTION_CONTINUE;
4164+ else
4165+ return result;
4166+
4167+ if (not)
4168+ {
4169+ /* Save the current action setting for this status,
4170+ set them all to the given action, and reset this one. */
4171+ const lookup_actions save = new_service->actions[2 + status];
4172+ new_service->actions[2 + NSS_STATUS_TRYAGAIN] = action;
4173+ new_service->actions[2 + NSS_STATUS_UNAVAIL] = action;
4174+ new_service->actions[2 + NSS_STATUS_NOTFOUND] = action;
4175+ new_service->actions[2 + NSS_STATUS_SUCCESS] = action;
4176+ new_service->actions[2 + status] = save;
4177+ }
4178+ else
4179+ new_service->actions[2 + status] = action;
4180+
4181+ /* Skip white spaces. */
4182+ while (isspace (line[0]))
4183+ ++line;
4184+ }
4185+ while (line[0] != ']');
4186+
4187+ /* Skip the ']'. */
4188+ ++line;
4189+ }
4190+
4191+ *nextp = new_service;
4192+ nextp = &new_service->next;
4193+ }
4194+}
4195+
4196+static name_database_entry *
4197+internal_function
4198+nss_getline (char *line)
4199+{
4200+ const char *name;
4201+ name_database_entry *result;
4202+ size_t len;
4203+
4204+ /* Ignore leading white spaces. ATTENTION: this is different from
4205+ what is implemented in Solaris. The Solaris man page says a line
4206+ beginning with a white space character is ignored. We regard
4207+ this as just another misfeature in Solaris. */
4208+ while (isspace (line[0]))
4209+ ++line;
4210+
4211+ /* Recognize `<database> ":"'. */
4212+ name = line;
4213+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != ':')
4214+ ++line;
4215+ if (line[0] == '\0' || name == line)
4216+ /* Syntax error. */
4217+ return NULL;
4218+ *line++ = '\0';
4219+
4220+ len = strlen (name) + 1;
4221+
4222+ result = (name_database_entry *) xmalloc (sizeof (*result));
4223+ result->name = (char *) xmalloc (len);
4224+
4225+ /* Save the database name. */
4226+ memcpy ((char *) result->name, name, len);
4227+
4228+ /* Parse the list of services. */
4229+ result->service = nss_parse_service_list (line);
4230+
4231+ result->next = NULL;
4232+ return result;
4233+}
4234+
4235+
4236+
4237+/* Generating code for statically initialized nsswitch structures. */
4238+
4239+
4240+/* Return the service-neutral suffix of the name of the service
4241+ library function referred to by the function F. The result is
4242+ allocated with malloc. */
4243+char *
4244+known_function_suffix (const struct function *f)
4245+{
4246+ switch (f->kind)
4247+ {
4248+ case fk_setent:
4249+ return saprintf ("set%sent", f->entry);
4250+
4251+ case fk_getent:
4252+ return saprintf ("get%sent_r", f->entry);
4253+
4254+ case fk_endent:
4255+ return saprintf ("end%sent", f->entry);
4256+
4257+ case fk_getby:
4258+ return saprintf ("get%sby%s_r", f->entry, f->key);
4259+
4260+ case fk_get:
4261+ return saprintf ("get%s_r", f->value_and_key);
4262+
4263+ default:
4264+ abort ();
4265+ }
4266+}
4267+
4268+
4269+/* Return the name of the service library function referred to by the
4270+ function F. The result is allocated with malloc. */
4271+char *
4272+known_function_name (const struct function *f)
4273+{
4274+ return saprintf ("_nss_%s_%s", f->service, known_function_suffix (f));
4275+}
4276+
4277+
4278+/* Write initialized known_function structures to OUT for
4279+ all the functions we'll use. */
4280+void
4281+generate_known_functions (FILE *out)
4282+{
4283+ int i;
4284+
4285+ /* First, generate weak references to the functions. The service
4286+ libraries depend on libc, and if these references weren't weak,
4287+ we'd be making libc depend circularly on the service
4288+ libraries. */
4289+ for (i = 0; functions[i].kind; i++)
4290+ {
4291+ char *name = known_function_name (&functions[i]);
4292+ fprintf (out, "typeof (%s) %s __attribute__ ((weak));\n",
4293+ name, name);
4294+ }
4295+ fputs ("\n", out);
4296+
4297+ /* Then, a table mapping names to functions. */
4298+ fputs ("static const known_function fixed_known_functions[] = {\n",
4299+ out);
4300+ for (i = 0; functions[i].kind; i++)
4301+ {
4302+ const struct function *f = &functions[i];
4303+ char *suffix = known_function_suffix (f);
4304+
4305+ fprintf (out, " /* %2d */ { \"%s\", _nss_%s_%s },\n",
4306+ i, suffix, f->service, suffix);
4307+ }
4308+ fputs ("};\n", out);
4309+ fputs ("\n", out);
4310+}
4311+
4312+
4313+/* Print code to OUT for an initialized array of pointers to the
4314+ 'known_function' structures needed for USER, which is for
4315+ DATABASE. Return its name, allocated with malloc. */
4316+char *
4317+generate_known_function_list (FILE *out,
4318+ const name_database_entry *database,
4319+ const service_user *user)
4320+{
4321+ char *list_name = saprintf ("fixed_%s_%s_known_funcs",
4322+ database->name, user->name);
4323+ fprintf (out, "static const known_function *%s[] = {\n",
4324+ list_name);
4325+ int i;
4326+ for (i = 0; functions[i].kind; i++)
4327+ if (strcmp (functions[i].database, database->name) == 0
4328+ && strcmp (functions[i].service, user->name) == 0)
4329+ fprintf (out, " &fixed_known_functions[%d], /* %s */\n",
4330+ i, known_function_name (&functions[i]));
4331+ fputs (" NULL\n", out);
4332+ fputs ("};\n", out);
4333+ fputs ("\n", out);
4334+
4335+ return list_name;
4336+}
4337+
4338+
4339+/* Return the name of the status value STATUS, as a statically
4340+ allocated string. */
4341+const char *
4342+lookup_status_name (enum nss_status status)
4343+{
4344+ switch (status)
4345+ {
4346+ case NSS_STATUS_TRYAGAIN: return "NSS_STATUS_TRYAGAIN";
4347+ case NSS_STATUS_UNAVAIL: return "NSS_STATUS_UNAVAIL";
4348+ case NSS_STATUS_NOTFOUND: return "NSS_STATUS_NOTFOUND";
4349+ case NSS_STATUS_SUCCESS: return "NSS_STATUS_SUCCESS";
4350+ case NSS_STATUS_RETURN: return "NSS_STATUS_RETURN";
4351+ default: abort ();
4352+ };
4353+}
4354+
4355+
4356+/* Return the name of ACTION as a statically allocated string. */
4357+const char *
4358+lookup_action_name (lookup_actions action)
4359+{
4360+ switch (action)
4361+ {
4362+ case NSS_ACTION_CONTINUE: return "NSS_ACTION_CONTINUE";
4363+ case NSS_ACTION_RETURN: return "NSS_ACTION_RETURN";
4364+ default: abort ();
4365+ }
4366+}
4367+
4368+
4369+/* Print code to OUT for the list of service_user structures starting
4370+ with USER, which are all for DATABASE. Return the name of the
4371+ first structure in that list, or zero if USER is NULL. */
4372+char *
4373+generate_service_user_list (FILE *out,
4374+ name_database_entry *database,
4375+ service_user *user)
4376+{
4377+ if (user)
4378+ {
4379+ /* Generate the tail of the list. */
4380+ char *next_name = generate_service_user_list (out, database, user->next);
4381+ /* Generate our known function list. */
4382+ char *known_function_list_name =
4383+ generate_known_function_list (out, database, user);
4384+
4385+ char *name = saprintf ("fixed_%s_%s_user", database->name, user->name);
4386+
4387+ fprintf (out, "static const service_user %s = {\n", name);
4388+ if (next_name)
4389+ fprintf (out, " (service_user *) &%s,\n", next_name);
4390+ else
4391+ fprintf (out, " NULL, /* no next entry */\n");
4392+ fputs (" {\n", out);
4393+ int i;
4394+ for (i = 0; i < sizeof (user->actions) / sizeof (user->actions[0]); i++)
4395+ fprintf (out, " %s, /* %s */\n",
4396+ lookup_action_name (user->actions[i]),
4397+ lookup_status_name (i - 2));
4398+ fputs (" },\n", out);
4399+ fprintf (out, " NULL, /* we never need the service library */\n");
4400+ fprintf (out, " { .array = %s },\n", known_function_list_name);
4401+ fprintf (out, " \"%s\"\n", user->name);
4402+ fputs ("};\n", out);
4403+ fputs ("\n", out);
4404+
4405+ return name;
4406+ }
4407+ else
4408+ return NULL;
4409+}
4410+
4411+
4412+/* Print code to OUT for the list of name_database_entry structures
4413+ starting with DATABASE. Return the name of the first structure
4414+ in that list, or zero if DATABASE is NULL. */
4415+char *
4416+generate_name_database_entries (FILE *out, name_database_entry *database)
4417+{
4418+ if (database)
4419+ {
4420+ char *next_name = generate_name_database_entries (out, database->next);
4421+ char *service_user_name
4422+ = generate_service_user_list (out, database, database->service);
4423+ char *name = saprintf ("fixed_%s_name_database", database->name);
4424+
4425+ fprintf (out, "static const name_database_entry %s = {\n", name);
4426+
4427+ if (next_name)
4428+ fprintf (out, " (name_database_entry *) &%s,\n", next_name);
4429+ else
4430+ fprintf (out, " NULL,\n");
4431+
4432+ if (service_user_name)
4433+ fprintf (out, " (service_user *) &%s,\n", service_user_name);
4434+ else
4435+ fprintf (out, " NULL,\n");
4436+
4437+ fprintf (out, " \"%s\"\n", database->name);
4438+ fprintf (out, "};\n");
4439+ fputs ("\n", out);
4440+
4441+ return name;
4442+ }
4443+ else
4444+ return NULL;
4445+}
4446+
4447+
4448+void
4449+generate_name_database (FILE *out, name_database *service_table)
4450+{
4451+ /* Produce a linked list of the known name_database_entry
4452+ structures. */
4453+ char *entries = generate_name_database_entries (out, service_table->entry);
4454+
4455+ /* Now produce the main structure that points to them all. */
4456+ fprintf (out, "static const name_database fixed_name_database = {\n");
4457+ if (entries)
4458+ fprintf (out, " (name_database_entry *) &%s,\n", entries);
4459+ else
4460+ fprintf (out, " NULL,\n");
4461+ fputs (" NULL /* we don't need the libraries */\n"
4462+ "};\n",
4463+ out);
4464+}
4465+
4466+
4467+
4468+/* Generating the list of service libraries we generate references to. */
4469+
4470+/* String with revision number of the shared object files. */
4471+static const char *const nss_shlib_revision = LIBNSS_FILES_SO + 15;
4472+
4473+void
4474+generate_service_lib_list (FILE *out, name_database *service_table)
4475+{
4476+ int i, j;
4477+ int printed_any = 0;
4478+
4479+ for (i = 0; functions[i].kind; i++)
4480+ {
4481+ /* Mention each service library only once. */
4482+ for (j = 0; j < i; j++)
4483+ if (strcmp (functions[i].service, functions[j].service) == 0)
4484+ break;
4485+
4486+ if (j >= i)
4487+ {
4488+ if (printed_any)
4489+ putc (' ', out);
4490+ fprintf (out, "-lnss_%s",
4491+ functions[i].service,
4492+ nss_shlib_revision);
4493+ printed_any = 1;
4494+ }
4495+ }
4496+}
4497+
4498+
4499+/* Main. */
4500+
4501+int
4502+main (int argc, char **argv)
4503+{
4504+ if (argc != 4)
4505+ {
4506+ fprintf (stderr, "usage: gen-fixed-nsswitch HEADER SERVLIBS CONFIG\n");
4507+ exit (1);
4508+ }
4509+
4510+ name_database *service_table = nss_parse_file (argv[3]);
4511+
4512+ FILE *header = fopen (argv[1], "w");
4513+ if (! header)
4514+ {
4515+ fprintf (stderr,
4516+ "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
4517+ argv[1], strerror (errno));
4518+ exit (1);
4519+ }
4520+ fputs ("/* Generated by nss/gen-fixed-nsswitch.c. */\n", header);
4521+ fputs ("\n", header);
4522+ generate_known_functions (header);
4523+ generate_name_database (header, service_table);
4524+ fclose (header);
4525+
4526+ FILE *service_lib_list = fopen (argv[2], "w");
4527+ if (! service_lib_list)
4528+ {
4529+ fprintf (stderr,
4530+ "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
4531+ argv[2], strerror (errno));
4532+ exit (1);
4533+ }
4534+ generate_service_lib_list (service_lib_list, service_table);
4535+ fclose (service_lib_list);
4536+
4537+ return 0;
4538+}
4539diff --git a/nss/getent.c b/nss/getent.c
4540index 34df848..674c8ee 100644
4541--- a/nss/getent.c
4542+++ b/nss/getent.c
4543@@ -39,6 +39,7 @@
4544 #include <netinet/ether.h>
4545 #include <netinet/in.h>
4546 #include <sys/socket.h>
4547+#include <gnu/option-groups.h>
4548
4549 /* Get libc version number. */
4550 #include <version.h>
4551@@ -91,6 +92,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
4552 fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
4553 }
4554
4555+#if __OPTION_EGLIBC_DB_ALIASES
4556 /* This is for aliases */
4557 static void
4558 print_aliases (struct aliasent *alias)
4559@@ -135,7 +137,9 @@ aliases_keys (int number, char *key[])
4560
4561 return result;
4562 }
4563+#endif /* __OPTION_EGLIBC_DB_ALIASES */
4564
4565+#if __OPTION_EGLIBC_INET
4566 /* This is for ethers */
4567 static int
4568 ethers_keys (int number, char *key[])
4569@@ -179,6 +183,7 @@ ethers_keys (int number, char *key[])
4570
4571 return result;
4572 }
4573+#endif /* __OPTION_EGLIBC_INET */
4574
4575 /* This is for group */
4576 static void
4577@@ -301,6 +306,7 @@ gshadow_keys (int number, char *key[])
4578 return result;
4579 }
4580
4581+#if __OPTION_EGLIBC_INET
4582 /* This is for hosts */
4583 static void
4584 print_hosts (struct hostent *host)
4585@@ -598,6 +604,7 @@ networks_keys (int number, char *key[])
4586
4587 return result;
4588 }
4589+#endif /* __OPTION_EGLIBC_INET */
4590
4591 /* Now is all for passwd */
4592 static void
4593@@ -650,6 +657,7 @@ passwd_keys (int number, char *key[])
4594 return result;
4595 }
4596
4597+#if __OPTION_EGLIBC_INET
4598 /* This is for protocols */
4599 static void
4600 print_protocols (struct protoent *proto)
4601@@ -807,6 +815,7 @@ services_keys (int number, char *key[])
4602
4603 return result;
4604 }
4605+#endif /* __OPTION_EGLIBC_INET */
4606
4607 /* This is for shadow */
4608 static void
4609@@ -873,23 +882,36 @@ struct
4610 } databases[] =
4611 {
4612 #define D(name) { #name, name ## _keys },
4613-D(ahosts)
4614-D(ahostsv4)
4615-D(ahostsv6)
4616-D(aliases)
4617-D(ethers)
4618+
4619+#if __OPTION_EGLIBC_INET
4620+# define DN(name) D(name)
4621+#else
4622+# define DN(name)
4623+#endif
4624+
4625+#if __OPTION_EGLIBC_DB_ALIASES
4626+# define DA(name) D(name)
4627+#else
4628+# define DA(name)
4629+#endif
4630+
4631+DN(ahosts)
4632+DN(ahostsv4)
4633+DN(ahostsv6)
4634+DA(aliases)
4635+DN(ethers)
4636 D(group)
4637 D(gshadow)
4638-D(hosts)
4639-D(initgroups)
4640-D(netgroup)
4641-D(networks)
4642+DN(hosts)
4643+DN(initgroups)
4644+DN(netgroup)
4645+DN(networks)
4646 D(passwd)
4647-D(protocols)
4648+DN(protocols)
4649 #if HAVE_SUNRPC
4650-D(rpc)
4651+DN(rpc)
4652 #endif
4653-D(services)
4654+DN(services)
4655 D(shadow)
4656 #undef D
4657 { NULL, NULL }
4658diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c
4659index f5b9036..f09f7fe 100644
4660--- a/nss/getnssent_r.c
4661+++ b/nss/getnssent_r.c
4662@@ -16,6 +16,7 @@
4663 <http://www.gnu.org/licenses/>. */
4664
4665 #include <errno.h>
4666+#include <gnu/option-groups.h>
4667 #include <netdb.h>
4668 #include "nsswitch.h"
4669
4670@@ -59,11 +60,13 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct,
4671 } fct;
4672 int no_more;
4673
4674+#if __OPTION_EGLIBC_INET
4675 if (res && __res_maybe_init (&_res, 0) == -1)
4676 {
4677 __set_h_errno (NETDB_INTERNAL);
4678 return;
4679 }
4680+#endif /* __OPTION_EGLIBC_INET */
4681
4682 /* Cycle through the services and run their `setXXent' functions until
4683 we find an available service. */
4684@@ -101,11 +104,13 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct,
4685 } fct;
4686 int no_more;
4687
4688+#if __OPTION_EGLIBC_INET
4689 if (res && __res_maybe_init (&_res, 0) == -1)
4690 {
4691 __set_h_errno (NETDB_INTERNAL);
4692 return;
4693 }
4694+#endif /* __OPTION_EGLIBC_INET */
4695
4696 /* Cycle through all the services and run their endXXent functions. */
4697 no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
4698@@ -141,12 +146,14 @@ __nss_getent_r (const char *getent_func_name,
4699 int no_more;
4700 enum nss_status status;
4701
4702+#if __OPTION_EGLIBC_INET
4703 if (res && __res_maybe_init (&_res, 0) == -1)
4704 {
4705 *h_errnop = NETDB_INTERNAL;
4706 *result = NULL;
4707 return errno;
4708 }
4709+#endif /* __OPTION_EGLIBC_INET */
4710
4711 /* Initialize status to return if no more functions are found. */
4712 status = NSS_STATUS_NOTFOUND;
4713@@ -161,7 +168,7 @@ __nss_getent_r (const char *getent_func_name,
4714 int is_last_nip = *nip == *last_nip;
4715
4716 status = DL_CALL_FCT (fct.f,
4717- (resbuf, buffer, buflen, &errno, &h_errno));
4718+ (resbuf, buffer, buflen, &errno, h_errnop));
4719
4720 /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
4721 provided buffer is too small. In this case we should give
4722diff --git a/nss/nsswitch.c b/nss/nsswitch.c
4723index 9712623..c81e207 100644
4724--- a/nss/nsswitch.c
4725+++ b/nss/nsswitch.c
4726@@ -26,6 +26,7 @@
4727 #include <stdio_ext.h>
4728 #include <stdlib.h>
4729 #include <string.h>
4730+#include <gnu/option-groups.h>
4731
4732 #include <aliases.h>
4733 #include <grp.h>
4734@@ -41,6 +42,15 @@
4735 #include "../nscd/nscd_proto.h"
4736 #include <sysdep.h>
4737
4738+/* When OPTION_EGLIBC_NSSWITCH is disabled, we use fixed tables of
4739+ databases and services, generated at library build time. Thus:
4740+ - We can't reconfigure individual databases, so we don't need a
4741+ name-to-database map.
4742+ - We never add databases or service libraries, or look up functions
4743+ at runtime, so there's no need for a lock to protect our tables.
4744+ See ../option-groups.def for the details. */
4745+#if __OPTION_EGLIBC_NSSWITCH
4746+
4747 /* Prototypes for the local functions. */
4748 static name_database *nss_parse_file (const char *fname) internal_function;
4749 static name_database_entry *nss_getline (char *line) internal_function;
4750@@ -79,6 +89,9 @@ bool __nss_database_custom[NSS_DBSIDX_max];
4751
4752 __libc_lock_define_initialized (static, lock)
4753
4754+#define lock_nsswitch __libc_lock_lock (lock)
4755+#define unlock_nsswitch __libc_lock_unlock (lock)
4756+
4757 #if !defined DO_STATIC_NSS || defined SHARED
4758 /* String with revision number of the shared object files. */
4759 static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15;
4760@@ -93,6 +106,20 @@ static name_database *service_table;
4761 __libc_freeres. */
4762 static name_database_entry *defconfig_entries;
4763
4764+#else /* __OPTION_EGLIBC_NSSWITCH */
4765+
4766+/* Bring in the statically initialized service table we generated at
4767+ build time. */
4768+#include "fixed-nsswitch.h"
4769+
4770+const static name_database *service_table = &fixed_name_database;
4771+
4772+/* Nothing ever changes, so there's no need to lock anything. */
4773+#define lock_nsswitch (0)
4774+#define unlock_nsswitch (0)
4775+
4776+#endif /* __OPTION_EGLIBC_NSSWITCH */
4777+
4778
4779 #ifdef USE_NSCD
4780 /* Nonzero if this is the nscd process. */
4781@@ -109,20 +136,22 @@ __nss_database_lookup (const char *database, const char *alternate_name,
4782 const char *defconfig, service_user **ni)
4783 {
4784 /* Prevent multiple threads to change the service table. */
4785- __libc_lock_lock (lock);
4786+ lock_nsswitch;
4787
4788 /* Reconsider database variable in case some other thread called
4789 `__nss_configure_lookup' while we waited for the lock. */
4790 if (*ni != NULL)
4791 {
4792- __libc_lock_unlock (lock);
4793+ unlock_nsswitch;
4794 return 0;
4795 }
4796
4797+#if __OPTION_EGLIBC_NSSWITCH
4798 /* Are we initialized yet? */
4799 if (service_table == NULL)
4800 /* Read config file. */
4801 service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
4802+#endif
4803
4804 /* Test whether configuration data is available. */
4805 if (service_table != NULL)
4806@@ -144,6 +173,7 @@ __nss_database_lookup (const char *database, const char *alternate_name,
4807 *ni = entry->service;
4808 }
4809
4810+#if __OPTION_EGLIBC_NSSWITCH
4811 /* No configuration data is available, either because nsswitch.conf
4812 doesn't exist or because it doesn't have a line for this database.
4813
4814@@ -166,13 +196,23 @@ __nss_database_lookup (const char *database, const char *alternate_name,
4815 {
4816 entry->next = defconfig_entries;
4817 entry->service = *ni;
4818- entry->name[0] = '\0';
4819+ entry->name = "";
4820 defconfig_entries = entry;
4821 }
4822 }
4823 }
4824+#else
4825+ /* Without the dynamic behavior, we can't process defconfig. The
4826+ databases the user specified at library build time are all you
4827+ get. */
4828+ if (*ni == NULL)
4829+ {
4830+ unlock_nsswitch;
4831+ return -1;
4832+ }
4833+#endif
4834
4835- __libc_lock_unlock (lock);
4836+ unlock_nsswitch;
4837
4838 return *ni != NULL ? 0 : -1;
4839 }
4840@@ -252,6 +292,7 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name,
4841 libc_hidden_def (__nss_next2)
4842
4843
4844+#if __OPTION_EGLIBC_NSSWITCH
4845 int
4846 attribute_compat_text_section
4847 __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
4848@@ -300,13 +341,13 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
4849 }
4850
4851 /* Prevent multiple threads to change the service table. */
4852- __libc_lock_lock (lock);
4853+ lock_nsswitch;
4854
4855 /* Install new rules. */
4856 *databases[cnt].dbp = new_db;
4857 __nss_database_custom[cnt] = true;
4858
4859- __libc_lock_unlock (lock);
4860+ unlock_nsswitch;
4861
4862 return 0;
4863 }
4864@@ -402,7 +443,7 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
4865 void **found, *result;
4866
4867 /* We now modify global data. Protect it. */
4868- __libc_lock_lock (lock);
4869+ lock_nsswitch;
4870
4871 /* Search the tree of functions previously requested. Data in the
4872 tree are `known_function' structures, whose first member is a
4873@@ -413,7 +454,7 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
4874 enough to a pointer to our structure to use as a lookup key that
4875 will be passed to `known_compare' (above). */
4876
4877- found = __tsearch (&fct_name, &ni->known, &known_compare);
4878+ found = __tsearch (&fct_name, &ni->known.tree, &known_compare);
4879 if (found == NULL)
4880 /* This means out-of-memory. */
4881 result = NULL;
4882@@ -440,7 +481,7 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
4883 #endif
4884 /* Oops. We can't instantiate this node properly.
4885 Remove it from the tree. */
4886- __tdelete (&fct_name, &ni->known, &known_compare);
4887+ __tdelete (&fct_name, &ni->known.tree, &known_compare);
4888 free (known);
4889 result = NULL;
4890 }
4891@@ -520,13 +561,43 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
4892 }
4893
4894 /* Remove the lock. */
4895- __libc_lock_unlock (lock);
4896+ unlock_nsswitch;
4897
4898 return result;
4899 }
4900 libc_hidden_def (__nss_lookup_function)
4901
4902
4903+#else /* below if ! __OPTION_EGLIBC_NSSWITCH */
4904+
4905+
4906+int
4907+__nss_configure_lookup (const char *dbname, const char *service_line)
4908+{
4909+ /* We can't dynamically configure lookup without
4910+ OPTION_EGLIBC_NSSWITCH. */
4911+ __set_errno (EINVAL);
4912+ return -1;
4913+}
4914+
4915+
4916+void *
4917+__nss_lookup_function (service_user *ni, const char *fct_name)
4918+{
4919+ int i;
4920+ const known_function **known = ni->known.array;
4921+
4922+ for (i = 0; known[i]; i++)
4923+ if (strcmp (fct_name, known[i]->fct_name) == 0)
4924+ return known[i]->fct_ptr;
4925+
4926+ return NULL;
4927+}
4928+libc_hidden_def (__nss_lookup_function)
4929+#endif
4930+
4931+
4932+#if __OPTION_EGLIBC_NSSWITCH
4933 static name_database *
4934 internal_function
4935 nss_parse_file (const char *fname)
4936@@ -632,8 +703,10 @@ nss_parse_service_list (const char *line)
4937 + (line - name + 1));
4938 if (new_service == NULL)
4939 return result;
4940+ new_service->name = (char *) (new_service + 1);
4941
4942- *((char *) __mempcpy (new_service->name, name, line - name)) = '\0';
4943+ *((char *) __mempcpy ((char *) new_service->name, name, line - name))
4944+ = '\0';
4945
4946 /* Set default actions. */
4947 new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
4948@@ -642,7 +715,7 @@ nss_parse_service_list (const char *line)
4949 new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
4950 new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
4951 new_service->library = NULL;
4952- new_service->known = NULL;
4953+ new_service->known.tree = NULL;
4954 new_service->next = NULL;
4955
4956 while (isspace (line[0]))
4957@@ -778,9 +851,10 @@ nss_getline (char *line)
4958 result = (name_database_entry *) malloc (sizeof (name_database_entry) + len);
4959 if (result == NULL)
4960 return NULL;
4961+ result->name = (char *) (result + 1);
4962
4963 /* Save the database name. */
4964- memcpy (result->name, name, len);
4965+ memcpy ((char *) result->name, name, len);
4966
4967 /* Parse the list of services. */
4968 result->service = nss_parse_service_list (line);
4969@@ -816,6 +890,7 @@ nss_new_service (name_database *database, const char *name)
4970 return *currentp;
4971 }
4972 #endif
4973+#endif /* __OPTION_EGLIBC_NSSWITCH */
4974
4975
4976 #if defined SHARED && defined USE_NSCD
4977@@ -834,6 +909,7 @@ nss_load_all_libraries (const char *service, const char *def)
4978 }
4979
4980
4981+#if __OPTION_EGLIBC_INET
4982 /* Called by nscd and nscd alone. */
4983 void
4984 __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
4985@@ -857,8 +933,10 @@ __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
4986 __nss_not_use_nscd_services = -1;
4987 __nss_not_use_nscd_netgroup = -1;
4988 }
4989+#endif /* __OPTION_EGLIBC_INET */
4990 #endif
4991
4992+#if __OPTION_EGLIBC_NSSWITCH
4993 static void
4994 free_database_entries (name_database_entry *entry)
4995 {
4996@@ -871,8 +949,8 @@ free_database_entries (name_database_entry *entry)
4997 {
4998 service_user *olds = service;
4999
5000- if (service->known != NULL)
5001- __tdestroy (service->known, free);
5002+ if (service->known.tree != NULL)
5003+ __tdestroy (service->known.tree, free);
5004
5005 service = service->next;
5006 free (olds);
5007@@ -926,3 +1004,4 @@ libc_freeres_fn (free_mem)
5008
5009 free (top);
5010 }
5011+#endif /* __OPTION_EGLIBC_NSSWITCH */
5012diff --git a/nss/nsswitch.h b/nss/nsswitch.h
5013index a5318fa..1730977 100644
5014--- a/nss/nsswitch.h
5015+++ b/nss/nsswitch.h
5016@@ -65,10 +65,20 @@ typedef struct service_user
5017 lookup_actions actions[5];
5018 /* Link to the underlying library object. */
5019 service_library *library;
5020- /* Collection of known functions. */
5021- void *known;
5022+ /* Collection of known functions.
5023+
5024+ With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
5025+ 'tsearch'-style tree.
5026+
5027+ With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
5028+ pointers to known_function structures, NULL-terminated. */
5029+ union
5030+ {
5031+ void *tree;
5032+ const known_function **array;
5033+ } known;
5034 /* Name of the service (`files', `dns', `nis', ...). */
5035- char name[0];
5036+ const char *name;
5037 } service_user;
5038
5039 /* To access the action based on the status value use this macro. */
5040@@ -82,7 +92,7 @@ typedef struct name_database_entry
5041 /* List of service to be used. */
5042 service_user *service;
5043 /* Name of the database. */
5044- char name[0];
5045+ const char *name;
5046 } name_database_entry;
5047
5048
5049diff --git a/posix/Makefile b/posix/Makefile
5050index 15e8818..609ed03 100644
5051--- a/posix/Makefile
5052+++ b/posix/Makefile
5053@@ -18,6 +18,8 @@
5054 #
5055 # Sub-makefile for POSIX portion of the library.
5056 #
5057+include ../option-groups.mak
5058+
5059 subdir := posix
5060
5061 include ../Makeconfig
5062@@ -43,13 +45,24 @@ routines := \
5063 getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid \
5064 getresuid getresgid setresuid setresgid \
5065 pathconf sysconf fpathconf \
5066- glob glob64 fnmatch regex \
5067+ glob glob64 fnmatch \
5068 confstr \
5069 getopt getopt1 getopt_init \
5070 sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax \
5071 sched_primin sched_rr_gi sched_getaffinity sched_setaffinity \
5072- getaddrinfo gai_strerror wordexp \
5073 pread pwrite pread64 pwrite64 \
5074+ posix_madvise \
5075+ get_child_max sched_cpucount sched_cpualloc sched_cpufree
5076+
5077+routines-$(OPTION_EGLIBC_INET) += getaddrinfo gai_strerror
5078+
5079+ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
5080+routines-$(OPTION_POSIX_REGEXP) += regex
5081+else
5082+routines-$(OPTION_POSIX_REGEXP) += xregex
5083+endif
5084+
5085+routines-$(OPTION_EGLIBC_SPAWN) += \
5086 spawn_faction_init spawn_faction_destroy spawn_faction_addclose \
5087 spawn_faction_addopen spawn_faction_adddup2 \
5088 spawnattr_init spawnattr_destroy \
5089@@ -61,37 +74,54 @@ routines := \
5090 posix_madvise \
5091 get_child_max sched_cpucount sched_cpualloc sched_cpufree
5092
5093+routines-$(OPTION_EGLIBC_WORDEXP) += wordexp
5094+
5095 aux := init-posix environ
5096-tests := tstgetopt testfnm runtests runptests \
5097+tests := tstgetopt testfnm runtests \
5098 tst-preadwrite tst-preadwrite64 test-vfork regexbug1 \
5099- tst-mmap tst-getaddrinfo tst-truncate \
5100- tst-truncate64 tst-fork tst-fnmatch tst-regexloc tst-dir \
5101- tst-chmod bug-regex1 bug-regex2 bug-regex3 bug-regex4 \
5102- tst-gnuglob tst-regex bug-regex5 bug-regex6 bug-regex7 \
5103- bug-regex8 bug-regex9 bug-regex10 bug-regex11 bug-regex12 \
5104- bug-regex13 bug-regex14 bug-regex15 bug-regex16 \
5105- bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
5106- bug-regex21 bug-regex22 bug-regex23 bug-regex24 \
5107- bug-regex25 bug-regex26 bug-regex27 bug-regex28 \
5108+ tst-mmap tst-truncate \
5109+ tst-truncate64 tst-fork tst-dir \
5110+ tst-chmod bug-regex2 bug-regex3 bug-regex4 \
5111+ tst-gnuglob bug-regex6 bug-regex7 \
5112+ bug-regex8 bug-regex9 bug-regex10 bug-regex12 \
5113+ bug-regex14 bug-regex15 \
5114+ bug-regex21 bug-regex24 \
5115+ bug-regex27 bug-regex28 \
5116 bug-regex29 bug-regex30 bug-regex31 bug-regex32 \
5117- bug-regex33 tst-nice tst-nanosleep tst-regex2 \
5118- transbug tst-rxspencer tst-pcre tst-boost \
5119- bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
5120- tst-getaddrinfo2 bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
5121+ tst-nice tst-nanosleep \
5122+ transbug \
5123+ tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
5124+ bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
5125 tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \
5126 tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
5127 tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
5128- tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
5129- tst-rfc3484-3 \
5130- tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
5131+ tst-execvp3 tst-execvp4 \
5132+ tst-fnmatch2 tst-cpucount tst-cpuset \
5133 bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
5134 bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
5135 tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \
5136 tst-fnmatch3 bug-regex36 tst-getaddrinfo5
5137-xtests := bug-ga2
5138+
5139+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
5140+ += tst-fnmatch tst-regexloc bug-regex1 bug-regex5 \
5141+ bug-regex23 bug-regex25 bug-regex32 bug-regex33
5142+tests-$(OPTION_EGLIBC_INET) \
5143+ += tst-getaddrinfo bug-ga1 tst-getaddrinfo2 \
5144+ tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 tst-getaddrinfo3
5145+tests-$(OPTION_POSIX_REGEXP_GLIBC) \
5146+ += runptests bug-regex11 bug-regex13 bug-regex16 \
5147+ tst-regex2 tst-rxspencer tst-pcre tst-boost
5148+ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP_GLIBC))
5149+tests += tst-regex bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
5150+ bug-regex22 bug-regex26
5151+endif
5152+xtests-$(OPTION_EGLIBC_INET) += bug-ga2
5153+
5154 ifeq (yes,$(build-shared))
5155 test-srcs := globtest
5156-tests += wordexp-test tst-exec tst-spawn
5157+tests += tst-exec
5158+tests-$(OPTION_EGLIBC_SPAWN) += tst-spawn
5159+tests-$(OPTION_EGLIBC_WORDEXP) += wordexp-test
5160 endif
5161 tests-static = tst-exec-static tst-spawn-static
5162 tests += $(tests-static)
5163@@ -117,7 +147,10 @@ generated += $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
5164
5165 ifeq ($(run-built-tests),yes)
5166 ifeq (yes,$(build-shared))
5167-tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out
5168+tests-special += $(objpfx)globtest.out
5169+ifeq (y,$(OPTION_EGLIBC_WORDEXP))
5170+tests-special += $(objpfx)wordexp-tst.out
5171+endif
5172 endif
5173 endif
5174
5175@@ -125,12 +158,16 @@ endif
5176 # XXX Please note that for now we ignore the result of this test.
5177 tests-special += $(objpfx)annexc.out
5178 ifeq ($(run-built-tests),yes)
5179-tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
5180+tests-special += $(objpfx)bug-regex2-mem.out \
5181 $(objpfx)bug-regex21-mem.out $(objpfx)bug-regex31-mem.out \
5182- $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
5183- $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
5184+ $(objpfx)tst-getconf.out \
5185 $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
5186 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
5187+ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
5188+tests-special += $(objpfx)bug-regex14-mem.out $(objpfx)tst-rxspencer-no-utf8-mem.out \
5189+ $(objpfx)tst-pcre-mem.out $(objpfx)tst-boost-mem.out
5190+endif
5191+
5192 xtests-special += $(objpfx)bug-ga2-mem.out
5193 endif
5194
5195@@ -143,6 +180,8 @@ $(objpfx)globtest.out: globtest.sh $(objpfx)globtest
5196 $(SHELL) $< $(common-objpfx) '$(test-via-rtld-prefix)' \
5197 '$(test-program-prefix)' '$(test-wrapper-env)'; \
5198 $(evaluate-test)
5199+LDLIBS-globtest += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
5200+
5201 $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test
5202 $(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \
5203 '$(run-program-env)' '$(test-program-prefix-after-env)'; \
5204@@ -205,7 +244,10 @@ tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir);
5205 tst-chmod-ARGS = $(objdir)
5206 tst-vfork3-ARGS = --test-dir=$(objpfx)
5207
5208-tst-rxspencer-ARGS = --utf8 rxspencer/tests
5209+tst-rxspencer-ARGS = rxspencer/tests
5210+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
5211+tst-rxspencer-ARGS += --utf8
5212+endif
5213 tst-rxspencer-no-utf8-ARGS = rxspencer/tests
5214 tst-pcre-ARGS = PCRE.tests
5215 tst-boost-ARGS = BOOST.tests
5216diff --git a/posix/bug-regex1.c b/posix/bug-regex1.c
5217index 38eb543..17cd1a0 100644
5218--- a/posix/bug-regex1.c
5219+++ b/posix/bug-regex1.c
5220@@ -4,6 +4,7 @@
5221 #include <string.h>
5222 #include <regex.h>
5223 #include <wchar.h>
5224+#include <gnu/option-groups.h>
5225
5226 int
5227 main (void)
5228@@ -17,7 +18,9 @@ main (void)
5229 memset (&regex, '\0', sizeof (regex));
5230
5231 setlocale (LC_ALL, "de_DE.ISO-8859-1");
5232+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
5233 fwide (stdout, -1);
5234+#endif
5235
5236 re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_DEBUG);
5237
5238diff --git a/posix/bug-regex6.c b/posix/bug-regex6.c
5239index efcc890..3b270c7 100644
5240--- a/posix/bug-regex6.c
5241+++ b/posix/bug-regex6.c
5242@@ -22,6 +22,7 @@
5243 #include <string.h>
5244 #include <sys/types.h>
5245 #include <regex.h>
5246+#include <gnu/option-groups.h>
5247
5248
5249 int
5250@@ -30,7 +31,12 @@ main (int argc, char *argv[])
5251 regex_t re;
5252 regmatch_t mat[10];
5253 int i, j, ret = 0;
5254- const char *locales[] = { "C", "de_DE.UTF-8" };
5255+ const char *locales[] = {
5256+ "C",
5257+#if __OPTION_EGLIBC_LOCALE_CODE
5258+ "de_DE.UTF-8"
5259+#endif
5260+ };
5261 const char *string = "http://www.regex.com/pattern/matching.html#intro";
5262 regmatch_t expect[10] = {
5263 { 0, 48 }, { 0, 5 }, { 0, 4 }, { 5, 20 }, { 7, 20 }, { 20, 42 },
5264diff --git a/posix/fnmatch.c b/posix/fnmatch.c
5265index fd85efa..01cc9fe 100644
5266--- a/posix/fnmatch.c
5267+++ b/posix/fnmatch.c
5268@@ -30,6 +30,10 @@
5269 #include <ctype.h>
5270 #include <string.h>
5271
5272+#if defined _LIBC
5273+# include <gnu/option-groups.h>
5274+#endif
5275+
5276 #if defined STDC_HEADERS || defined _LIBC
5277 # include <stdlib.h>
5278 #endif
5279@@ -131,7 +135,7 @@ extern int fnmatch (const char *pattern, const char *string, int flags);
5280 # define ISWCTYPE(WC, WT) iswctype (WC, WT)
5281 # endif
5282
5283-# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
5284+# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS && _LIBC && __OPTION_EGLIBC_LOCALE_CODE)
5285 /* In this case we are implementing the multibyte character handling. */
5286 # define HANDLE_MULTIBYTE 1
5287 # endif
5288diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c
5289index f46c9df..74e1754 100644
5290--- a/posix/fnmatch_loop.c
5291+++ b/posix/fnmatch_loop.c
5292@@ -15,6 +15,8 @@
5293 License along with the GNU C Library; if not, see
5294 <http://www.gnu.org/licenses/>. */
5295
5296+#include <gnu/option-groups.h>
5297+
5298 #include <stdint.h>
5299
5300 struct STRUCT
5301@@ -54,10 +56,15 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
5302 const char *collseq = (const char *)
5303 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
5304 # else
5305+# if __OPTION_EGLIBC_LOCALE_CODE
5306 const UCHAR *collseq = (const UCHAR *)
5307 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
5308-# endif
5309-#endif
5310+# define COLLSEQ_BYTE_LOOKUP(ix) (collseq[(ix)])
5311+# else
5312+# define COLLSEQ_BYTE_LOOKUP(ix) (ix)
5313+# endif /* __OPTION_EGLIBC_LOCALE_CODE */
5314+# endif /* WIDE_CHAR_VERSION */
5315+#endif /* _LIBC */
5316
5317 while ((c = *p++) != L('\0'))
5318 {
5319@@ -277,7 +284,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
5320 /* Leave room for the null. */
5321 CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
5322 size_t c1 = 0;
5323-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
5324+#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
5325 wctype_t wt;
5326 #endif
5327 const CHAR *startp = p;
5328@@ -307,7 +314,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
5329 }
5330 str[c1] = L('\0');
5331
5332-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
5333+#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
5334 wt = IS_CHAR_CLASS (str);
5335 if (wt == 0)
5336 /* Invalid character class name. */
5337@@ -680,8 +687,10 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
5338 else
5339 lcollseq = __collseq_table_lookup (collseq, cold);
5340 # else
5341- fcollseq = collseq[fn];
5342- lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
5343+ fcollseq = COLLSEQ_BYTE_LOOKUP (fn);
5344+ lcollseq = (is_seqval
5345+ ? cold
5346+ : COLLSEQ_BYTE_LOOKUP ((UCHAR) cold));
5347 # endif
5348
5349 is_seqval = 0;
5350@@ -857,7 +866,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
5351 goto matched;
5352 }
5353 # else
5354- hcollseq = collseq[cend];
5355+ hcollseq = COLLSEQ_BYTE_LOOKUP (cend);
5356 # endif
5357 }
5358
5359diff --git a/posix/glob.c b/posix/glob.c
5360index d65e55d..1ac00a1 100644
5361--- a/posix/glob.c
5362+++ b/posix/glob.c
5363@@ -25,6 +25,9 @@
5364 #include <sys/types.h>
5365 #include <sys/stat.h>
5366 #include <stddef.h>
5367+#ifdef _LIBC
5368+# include <gnu/option-groups.h>
5369+#endif
5370
5371 /* Outcomment the following line for production quality code. */
5372 /* #define NDEBUG 1 */
5373@@ -607,6 +610,7 @@ glob (pattern, flags, errfunc, pglob)
5374 if (home_dir == NULL || home_dir[0] == '\0')
5375 home_dir = "c:/users/default"; /* poor default */
5376 # else
5377+# if ! _LIBC || __OPTION_EGLIBC_GETLOGIN
5378 if (home_dir == NULL || home_dir[0] == '\0')
5379 {
5380 int success;
5381@@ -623,19 +627,19 @@ glob (pattern, flags, errfunc, pglob)
5382 if (success)
5383 {
5384 struct passwd *p;
5385-# if defined HAVE_GETPWNAM_R || defined _LIBC
5386+# if defined HAVE_GETPWNAM_R || defined _LIBC
5387 long int pwbuflen = GETPW_R_SIZE_MAX ();
5388 char *pwtmpbuf;
5389 struct passwd pwbuf;
5390 int malloc_pwtmpbuf = 0;
5391 int save = errno;
5392
5393-# ifndef _LIBC
5394+# ifndef _LIBC
5395 if (pwbuflen == -1)
5396 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
5397 Try a moderate value. */
5398 pwbuflen = 1024;
5399-# endif
5400+# endif
5401 if (__libc_use_alloca (alloca_used + pwbuflen))
5402 pwtmpbuf = alloca_account (pwbuflen, alloca_used);
5403 else
5404@@ -682,9 +686,9 @@ glob (pattern, flags, errfunc, pglob)
5405 }
5406 __set_errno (save);
5407 }
5408-# else
5409+# else
5410 p = getpwnam (name);
5411-# endif
5412+# endif
5413 if (p != NULL)
5414 {
5415 if (!malloc_pwtmpbuf)
5416@@ -713,6 +717,7 @@ glob (pattern, flags, errfunc, pglob)
5417 }
5418 }
5419 }
5420+# endif /* ! _LIBC || __OPTION_EGLIBC_GETLOGIN */
5421 if (home_dir == NULL || home_dir[0] == '\0')
5422 {
5423 if (flags & GLOB_TILDE_CHECK)
5424diff --git a/posix/regcomp.c b/posix/regcomp.c
5425index bf8aa16..6a41251 100644
5426--- a/posix/regcomp.c
5427+++ b/posix/regcomp.c
5428@@ -18,6 +18,7 @@
5429 <http://www.gnu.org/licenses/>. */
5430
5431 #include <stdint.h>
5432+#include <gnu/option-groups.h>
5433
5434 #ifdef _LIBC
5435 # include <locale/weight.h>
5436@@ -309,7 +310,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
5437 {
5438 re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
5439 int node_cnt;
5440- int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
5441+ int icase = (dfa_mb_cur_max (dfa) == 1 && (bufp->syntax & RE_ICASE));
5442 for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
5443 {
5444 int node = init_state->nodes.elems[node_cnt];
5445@@ -319,9 +320,9 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
5446 {
5447 re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
5448 #ifdef RE_ENABLE_I18N
5449- if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
5450+ if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
5451 {
5452- unsigned char *buf = alloca (dfa->mb_cur_max), *p;
5453+ unsigned char *buf = alloca (dfa_mb_cur_max (dfa)), *p;
5454 wchar_t wc;
5455 mbstate_t state;
5456
5457@@ -352,7 +353,11 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
5458 re_set_fastmap (fastmap, icase, ch);
5459 }
5460 }
5461-#ifdef RE_ENABLE_I18N
5462+
5463+ /* When OPTION_EGLIBC_LOCALE_CODE is disabled, the current
5464+ locale is always C, which has no rules and no multi-byte
5465+ characters. */
5466+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
5467 else if (type == COMPLEX_BRACKET)
5468 {
5469 re_charset_t *cset = dfa->nodes[node].opr.mbcset;
5470@@ -380,7 +385,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
5471 i.e. where we would not find an invalid sequence. This only
5472 applies to multibyte character sets; for single byte character
5473 sets, the SIMPLE_BRACKET again suffices. */
5474- if (dfa->mb_cur_max > 1
5475+ if (dfa_mb_cur_max (dfa) > 1
5476 && (cset->nchar_classes || cset->non_match || cset->nranges
5477 # ifdef _LIBC
5478 || cset->nequiv_classes
5479@@ -408,7 +413,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
5480 memset (&state, '\0', sizeof (state));
5481 if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
5482 re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
5483- if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
5484+ if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
5485 {
5486 if (__wcrtomb (buf, __towlower (cset->mbchars[i]), &state)
5487 != (size_t) -1)
5488@@ -417,7 +422,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
5489 }
5490 }
5491 }
5492-#endif /* RE_ENABLE_I18N */
5493+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
5494 else if (type == OP_PERIOD
5495 #ifdef RE_ENABLE_I18N
5496 || type == OP_UTF8_PERIOD
5497@@ -860,11 +865,15 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
5498
5499 dfa->mb_cur_max = MB_CUR_MAX;
5500 #ifdef _LIBC
5501- if (dfa->mb_cur_max == 6
5502+ if (dfa_mb_cur_max (dfa) == 6
5503 && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
5504 dfa->is_utf8 = 1;
5505+# if __OPTION_EGLIBC_LOCALE_CODE
5506 dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
5507 != 0);
5508+# else
5509+ dfa->map_notascii = 0;
5510+# endif
5511 #else
5512 # ifdef HAVE_LANGINFO_CODESET
5513 codeset_name = nl_langinfo (CODESET);
5514@@ -890,7 +899,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
5515 #endif
5516
5517 #ifdef RE_ENABLE_I18N
5518- if (dfa->mb_cur_max > 1)
5519+ if (dfa_mb_cur_max (dfa) > 1)
5520 {
5521 if (dfa->is_utf8)
5522 dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
5523@@ -1788,7 +1797,7 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
5524 token->word_char = 0;
5525 #ifdef RE_ENABLE_I18N
5526 token->mb_partial = 0;
5527- if (input->mb_cur_max > 1 &&
5528+ if (string_mb_cur_max (input) > 1 &&
5529 !re_string_first_byte (input, re_string_cur_idx (input)))
5530 {
5531 token->type = CHARACTER;
5532@@ -1809,7 +1818,7 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
5533 token->opr.c = c2;
5534 token->type = CHARACTER;
5535 #ifdef RE_ENABLE_I18N
5536- if (input->mb_cur_max > 1)
5537+ if (string_mb_cur_max (input) > 1)
5538 {
5539 wint_t wc = re_string_wchar_at (input,
5540 re_string_cur_idx (input) + 1);
5541@@ -1923,7 +1932,7 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
5542
5543 token->type = CHARACTER;
5544 #ifdef RE_ENABLE_I18N
5545- if (input->mb_cur_max > 1)
5546+ if (string_mb_cur_max (input) > 1)
5547 {
5548 wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
5549 token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
5550@@ -2023,7 +2032,7 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
5551 token->opr.c = c;
5552
5553 #ifdef RE_ENABLE_I18N
5554- if (input->mb_cur_max > 1 &&
5555+ if (string_mb_cur_max (input) > 1 &&
5556 !re_string_first_byte (input, re_string_cur_idx (input)))
5557 {
5558 token->type = CHARACTER;
5559@@ -2246,7 +2255,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
5560 return NULL;
5561 }
5562 #ifdef RE_ENABLE_I18N
5563- if (dfa->mb_cur_max > 1)
5564+ if (dfa_mb_cur_max (dfa) > 1)
5565 {
5566 while (!re_string_eoi (regexp)
5567 && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
5568@@ -2384,7 +2393,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
5569 *err = REG_ESPACE;
5570 return NULL;
5571 }
5572- if (dfa->mb_cur_max > 1)
5573+ if (dfa_mb_cur_max (dfa) > 1)
5574 dfa->has_mb_node = 1;
5575 break;
5576 case OP_WORD:
5577@@ -2690,7 +2699,7 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
5578 However, for !_LIBC we have no collation elements: if the
5579 character set is single byte, the single byte character set
5580 that we build below suffices. parse_bracket_exp passes
5581- no MBCSET if dfa->mb_cur_max == 1. */
5582+ no MBCSET if dfa_mb_cur_max (dfa) == 1. */
5583 if (mbcset)
5584 {
5585 /* Check the space of the arrays. */
5586@@ -2786,7 +2795,13 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5587 reg_syntax_t syntax, reg_errcode_t *err)
5588 {
5589 #ifdef _LIBC
5590+#if __OPTION_EGLIBC_LOCALE_CODE
5591 const unsigned char *collseqmb;
5592+# define COLLSEQMB_LOOKUP(ix) (collseqmb[(ix)])
5593+#else
5594+# define COLLSEQMB_LOOKUP(ix) (ix)
5595+#endif
5596+
5597 const char *collseqwc;
5598 uint32_t nrules;
5599 int32_t table_size;
5600@@ -2834,18 +2849,20 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5601 if (MB_CUR_MAX == 1)
5602 */
5603 if (nrules == 0)
5604- return collseqmb[br_elem->opr.ch];
5605+ return COLLSEQMB_LOOKUP (br_elem->opr.ch);
5606 else
5607 {
5608 wint_t wc = __btowc (br_elem->opr.ch);
5609 return __collseq_table_lookup (collseqwc, wc);
5610 }
5611 }
5612+#if __OPTION_EGLIBC_LOCALE_CODE
5613 else if (br_elem->type == MB_CHAR)
5614 {
5615 if (nrules != 0)
5616 return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
5617 }
5618+#endif
5619 else if (br_elem->type == COLL_SYM)
5620 {
5621 size_t sym_name_len = strlen ((char *) br_elem->opr.name);
5622@@ -2876,11 +2893,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5623 {
5624 /* No valid character. Match it as a single byte
5625 character. */
5626- return collseqmb[br_elem->opr.name[0]];
5627+ return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
5628 }
5629 }
5630 else if (sym_name_len == 1)
5631- return collseqmb[br_elem->opr.name[0]];
5632+ return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
5633 }
5634 return UINT_MAX;
5635 }
5636@@ -2920,7 +2937,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5637 However, if we have no collation elements, and the character set
5638 is single byte, the single byte character set that we
5639 build below suffices. */
5640- if (nrules > 0 || dfa->mb_cur_max > 1)
5641+ if (nrules > 0 || dfa_mb_cur_max (dfa) > 1)
5642 {
5643 /* Check the space of the arrays. */
5644 if (BE (*range_alloc == mbcset->nranges, 0))
5645@@ -2957,7 +2974,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5646 if (MB_CUR_MAX == 1)
5647 */
5648 if (nrules == 0)
5649- ch_collseq = collseqmb[ch];
5650+ ch_collseq = COLLSEQMB_LOOKUP (ch);
5651 else
5652 ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
5653 if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
5654@@ -3035,7 +3052,10 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5655 re_bitset_ptr_t sbcset;
5656 #ifdef RE_ENABLE_I18N
5657 re_charset_t *mbcset;
5658- int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
5659+ int coll_sym_alloc = 0, range_alloc = 0;
5660+#if __OPTION_EGLIBC_LOCALE_CODE
5661+ int mbchar_alloc = 0;
5662+#endif
5663 int equiv_class_alloc = 0, char_class_alloc = 0;
5664 #endif /* not RE_ENABLE_I18N */
5665 int non_match = 0;
5666@@ -3043,9 +3063,15 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5667 int token_len;
5668 int first_round = 1;
5669 #ifdef _LIBC
5670+#if __OPTION_EGLIBC_LOCALE_CODE
5671 collseqmb = (const unsigned char *)
5672 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
5673 nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
5674+#else
5675+ /* This is true when OPTION_EGLIBC_LOCALE_CODE is disabled, but the
5676+ compiler can't figure that out. */
5677+ nrules = 0;
5678+#endif
5679 if (nrules)
5680 {
5681 /*
5682@@ -3175,7 +3201,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5683 #else
5684 # ifdef RE_ENABLE_I18N
5685 *err = build_range_exp (sbcset,
5686- dfa->mb_cur_max > 1 ? mbcset : NULL,
5687+ dfa_mb_cur_max (dfa) > 1 ? mbcset : NULL,
5688 &range_alloc, &start_elem, &end_elem);
5689 # else
5690 *err = build_range_exp (sbcset, &start_elem, &end_elem);
5691@@ -3191,7 +3217,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5692 case SB_CHAR:
5693 bitset_set (sbcset, start_elem.opr.ch);
5694 break;
5695-#ifdef RE_ENABLE_I18N
5696+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
5697 case MB_CHAR:
5698 /* Check whether the array has enough space. */
5699 if (BE (mbchar_alloc == mbcset->nmbchars, 0))
5700@@ -3209,7 +3235,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5701 }
5702 mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
5703 break;
5704-#endif /* RE_ENABLE_I18N */
5705+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
5706 case EQUIV_CLASS:
5707 *err = build_equiv_class (sbcset,
5708 #ifdef RE_ENABLE_I18N
5709@@ -3259,11 +3285,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
5710
5711 #ifdef RE_ENABLE_I18N
5712 /* Ensure only single byte characters are set. */
5713- if (dfa->mb_cur_max > 1)
5714+ if (dfa_mb_cur_max (dfa) > 1)
5715 bitset_mask (sbcset, dfa->sb_char);
5716
5717 if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
5718- || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
5719+ || mbcset->nranges || (dfa_mb_cur_max (dfa) > 1 && (mbcset->nchar_classes
5720 || mbcset->non_match)))
5721 {
5722 bin_tree_t *mbc_tree;
5723@@ -3332,7 +3358,7 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
5724 re_token_t *token, int token_len, re_dfa_t *dfa,
5725 reg_syntax_t syntax, int accept_hyphen)
5726 {
5727-#ifdef RE_ENABLE_I18N
5728+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
5729 int cur_char_size;
5730 cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
5731 if (cur_char_size > 1)
5732@@ -3342,7 +3368,7 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
5733 re_string_skip_bytes (regexp, cur_char_size);
5734 return REG_NOERROR;
5735 }
5736-#endif /* RE_ENABLE_I18N */
5737+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
5738 re_string_skip_bytes (regexp, token_len); /* Skip a token. */
5739 if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
5740 || token->type == OP_OPEN_EQUIV_CLASS)
5741@@ -3422,7 +3448,9 @@ build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
5742 build_equiv_class (bitset_t sbcset, const unsigned char *name)
5743 #endif /* not RE_ENABLE_I18N */
5744 {
5745-#ifdef _LIBC
5746+ /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C locale
5747+ is supported; it has no collation rules. */
5748+#if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
5749 uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
5750 if (nrules != 0)
5751 {
5752@@ -3492,7 +3520,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
5753 mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
5754 }
5755 else
5756-#endif /* _LIBC */
5757+#endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
5758 {
5759 if (BE (strlen ((const char *) name) != 1, 0))
5760 return REG_ECOLLATE;
5761@@ -3526,7 +3554,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
5762 && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
5763 name = "alpha";
5764
5765-#ifdef RE_ENABLE_I18N
5766+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
5767 /* Check the space of the arrays. */
5768 if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
5769 {
5770@@ -3542,7 +3570,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
5771 *char_class_alloc = new_char_class_alloc;
5772 }
5773 mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
5774-#endif /* RE_ENABLE_I18N */
5775+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
5776
5777 #define BUILD_CHARCLASS_LOOP(ctype_func) \
5778 do { \
5779@@ -3653,7 +3681,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
5780
5781 #ifdef RE_ENABLE_I18N
5782 /* Ensure only single byte characters are set. */
5783- if (dfa->mb_cur_max > 1)
5784+ if (dfa_mb_cur_max (dfa) > 1)
5785 bitset_mask (sbcset, dfa->sb_char);
5786 #endif
5787
5788@@ -3665,7 +3693,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
5789 goto build_word_op_espace;
5790
5791 #ifdef RE_ENABLE_I18N
5792- if (dfa->mb_cur_max > 1)
5793+ if (dfa_mb_cur_max (dfa) > 1)
5794 {
5795 bin_tree_t *mbc_tree;
5796 /* Build a tree for complex bracket. */
5797diff --git a/posix/regex.h b/posix/regex.h
5798index 5b1981e..2941f94 100644
5799--- a/posix/regex.h
5800+++ b/posix/regex.h
5801@@ -21,6 +21,7 @@
5802 #define _REGEX_H 1
5803
5804 #include <sys/types.h>
5805+#include <gnu/option-groups.h>
5806
5807 /* Allow the use in C++ code. */
5808 #ifdef __cplusplus
5809@@ -156,6 +157,8 @@ typedef unsigned long int reg_syntax_t;
5810 treated as 'a\{1'. */
5811 # define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
5812
5813+/* EGLIBC: Old regex implementation does not support these. */
5814+# if __OPTION_POSIX_REGEXP_GLIBC
5815 /* If this bit is set, then ignore case when matching.
5816 If not set, then case is significant. */
5817 # define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
5818@@ -172,6 +175,7 @@ typedef unsigned long int reg_syntax_t;
5819 /* If this bit is set, then no_sub will be set to 1 during
5820 re_compile_pattern. */
5821 # define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
5822+# endif /* __OPTION_POSIX_REGEXP_GLIBC */
5823 #endif
5824
5825 /* This global variable defines the particular regexp syntax to use (for
5826@@ -231,8 +235,13 @@ extern reg_syntax_t re_syntax_options;
5827 (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
5828 | RE_INTERVALS | RE_NO_EMPTY_RANGES)
5829
5830+#if __OPTION_POSIX_REGEXP_GLIBC
5831 #define RE_SYNTAX_POSIX_BASIC \
5832 (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
5833+#else
5834+#define RE_SYNTAX_POSIX_BASIC \
5835+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
5836+#endif
5837
5838 /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
5839 RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
5840@@ -298,9 +307,11 @@ extern reg_syntax_t re_syntax_options;
5841 /* Like REG_NOTBOL, except for the end-of-line. */
5842 #define REG_NOTEOL (1 << 1)
5843
5844+#if __OPTION_POSIX_REGEXP_GLIBC
5845 /* Use PMATCH[0] to delimit the start and end of the search in the
5846 buffer. */
5847 #define REG_STARTEND (1 << 2)
5848+#endif
5849
5850
5851 /* If any error codes are removed, changed, or added, update the
5852diff --git a/posix/regex_internal.c b/posix/regex_internal.c
5853index 8597d7e..d53b2a8 100644
5854--- a/posix/regex_internal.c
5855+++ b/posix/regex_internal.c
5856@@ -43,8 +43,8 @@ re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
5857 int init_buf_len;
5858
5859 /* Ensure at least one character fits into the buffers. */
5860- if (init_len < dfa->mb_cur_max)
5861- init_len = dfa->mb_cur_max;
5862+ if (init_len < dfa_mb_cur_max (dfa))
5863+ init_len = dfa_mb_cur_max (dfa);
5864 init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
5865 re_string_construct_common (str, len, pstr, trans, icase, dfa);
5866
5867@@ -55,7 +55,7 @@ re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
5868 pstr->word_char = dfa->word_char;
5869 pstr->word_ops_used = dfa->word_ops_used;
5870 pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
5871- pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
5872+ pstr->valid_len = (pstr->mbs_allocated || dfa_mb_cur_max (dfa) > 1) ? 0 : len;
5873 pstr->valid_raw_len = pstr->valid_len;
5874 return REG_NOERROR;
5875 }
5876@@ -82,7 +82,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
5877 if (icase)
5878 {
5879 #ifdef RE_ENABLE_I18N
5880- if (dfa->mb_cur_max > 1)
5881+ if (dfa_mb_cur_max (dfa) > 1)
5882 {
5883 while (1)
5884 {
5885@@ -91,7 +91,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
5886 return ret;
5887 if (pstr->valid_raw_len >= len)
5888 break;
5889- if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
5890+ if (pstr->bufs_len > pstr->valid_len + dfa_mb_cur_max (dfa))
5891 break;
5892 ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
5893 if (BE (ret != REG_NOERROR, 0))
5894@@ -105,7 +105,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
5895 else
5896 {
5897 #ifdef RE_ENABLE_I18N
5898- if (dfa->mb_cur_max > 1)
5899+ if (dfa_mb_cur_max (dfa) > 1)
5900 build_wcs_buffer (pstr);
5901 else
5902 #endif /* RE_ENABLE_I18N */
5903@@ -130,7 +130,7 @@ internal_function __attribute_warn_unused_result__
5904 re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
5905 {
5906 #ifdef RE_ENABLE_I18N
5907- if (pstr->mb_cur_max > 1)
5908+ if (string_mb_cur_max (pstr) > 1)
5909 {
5910 wint_t *new_wcs;
5911
5912@@ -177,7 +177,7 @@ re_string_construct_common (const char *str, int len, re_string_t *pstr,
5913 pstr->trans = trans;
5914 pstr->icase = icase ? 1 : 0;
5915 pstr->mbs_allocated = (trans != NULL || icase);
5916- pstr->mb_cur_max = dfa->mb_cur_max;
5917+ pstr->mb_cur_max = dfa_mb_cur_max (dfa);
5918 pstr->is_utf8 = dfa->is_utf8;
5919 pstr->map_notascii = dfa->map_notascii;
5920 pstr->stop = pstr->len;
5921@@ -203,7 +203,7 @@ build_wcs_buffer (re_string_t *pstr)
5922 {
5923 #ifdef _LIBC
5924 unsigned char buf[MB_LEN_MAX];
5925- assert (MB_LEN_MAX >= pstr->mb_cur_max);
5926+ assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
5927 #else
5928 unsigned char buf[64];
5929 #endif
5930@@ -226,7 +226,7 @@ build_wcs_buffer (re_string_t *pstr)
5931 {
5932 int i, ch;
5933
5934- for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
5935+ for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
5936 {
5937 ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
5938 buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
5939@@ -275,7 +275,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
5940 size_t mbclen;
5941 #ifdef _LIBC
5942 char buf[MB_LEN_MAX];
5943- assert (MB_LEN_MAX >= pstr->mb_cur_max);
5944+ assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
5945 #else
5946 char buf[64];
5947 #endif
5948@@ -369,7 +369,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
5949 {
5950 int i, ch;
5951
5952- for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
5953+ for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
5954 {
5955 ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
5956 buf[i] = pstr->trans[ch];
5957@@ -567,8 +567,9 @@ re_string_translate_buffer (re_string_t *pstr)
5958 }
5959
5960 /* This function re-construct the buffers.
5961- Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
5962- convert to upper case in case of REG_ICASE, apply translation. */
5963+ Concretely, convert to wide character in case of
5964+ string_mb_cur_max (pstr) > 1, convert to upper case in case of
5965+ REG_ICASE, apply translation. */
5966
5967 static reg_errcode_t
5968 internal_function __attribute_warn_unused_result__
5969@@ -579,7 +580,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
5970 {
5971 /* Reset buffer. */
5972 #ifdef RE_ENABLE_I18N
5973- if (pstr->mb_cur_max > 1)
5974+ if (string_mb_cur_max (pstr) > 1)
5975 memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
5976 #endif /* RE_ENABLE_I18N */
5977 pstr->len = pstr->raw_len;
5978@@ -670,7 +671,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
5979 pstr->tip_context = re_string_context_at (pstr, offset - 1,
5980 eflags);
5981 #ifdef RE_ENABLE_I18N
5982- if (pstr->mb_cur_max > 1)
5983+ if (string_mb_cur_max (pstr) > 1)
5984 memmove (pstr->wcs, pstr->wcs + offset,
5985 (pstr->valid_len - offset) * sizeof (wint_t));
5986 #endif /* RE_ENABLE_I18N */
5987@@ -699,7 +700,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
5988 #endif
5989 pstr->valid_len = 0;
5990 #ifdef RE_ENABLE_I18N
5991- if (pstr->mb_cur_max > 1)
5992+ if (string_mb_cur_max (pstr) > 1)
5993 {
5994 int wcs_idx;
5995 wint_t wc = WEOF;
5996@@ -711,7 +712,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
5997 /* Special case UTF-8. Multi-byte chars start with any
5998 byte other than 0x80 - 0xbf. */
5999 raw = pstr->raw_mbs + pstr->raw_mbs_idx;
6000- end = raw + (offset - pstr->mb_cur_max);
6001+ end = raw + (offset - string_mb_cur_max (pstr));
6002 if (end < pstr->raw_mbs)
6003 end = pstr->raw_mbs;
6004 p = raw + offset - 1;
6005@@ -803,7 +804,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
6006
6007 /* Then build the buffers. */
6008 #ifdef RE_ENABLE_I18N
6009- if (pstr->mb_cur_max > 1)
6010+ if (string_mb_cur_max (pstr) > 1)
6011 {
6012 if (pstr->icase)
6013 {
6014@@ -841,7 +842,7 @@ re_string_peek_byte_case (const re_string_t *pstr, int idx)
6015 return re_string_peek_byte (pstr, idx);
6016
6017 #ifdef RE_ENABLE_I18N
6018- if (pstr->mb_cur_max > 1
6019+ if (string_mb_cur_max (pstr) > 1
6020 && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
6021 return re_string_peek_byte (pstr, idx);
6022 #endif
6023@@ -930,7 +931,7 @@ re_string_context_at (const re_string_t *input, int idx, int eflags)
6024 return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
6025 : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
6026 #ifdef RE_ENABLE_I18N
6027- if (input->mb_cur_max > 1)
6028+ if (string_mb_cur_max (input) > 1)
6029 {
6030 wint_t wc;
6031 int wc_idx = idx;
6032@@ -1444,7 +1445,7 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
6033 dfa->nodes[dfa->nodes_len].constraint = 0;
6034 #ifdef RE_ENABLE_I18N
6035 dfa->nodes[dfa->nodes_len].accept_mb =
6036- (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
6037+ (type == OP_PERIOD && dfa_mb_cur_max (dfa) > 1) || type == COMPLEX_BRACKET;
6038 #endif
6039 dfa->nexts[dfa->nodes_len] = -1;
6040 re_node_set_init_empty (dfa->edests + dfa->nodes_len);
6041diff --git a/posix/regex_internal.h b/posix/regex_internal.h
6042index 154e969..c43909a 100644
6043--- a/posix/regex_internal.h
6044+++ b/posix/regex_internal.h
6045@@ -26,6 +26,10 @@
6046 #include <stdlib.h>
6047 #include <string.h>
6048
6049+#if defined _LIBC
6050+# include <gnu/option-groups.h>
6051+#endif
6052+
6053 #if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
6054 # include <langinfo.h>
6055 #endif
6056@@ -369,6 +373,13 @@ struct re_string_t
6057 };
6058 typedef struct re_string_t re_string_t;
6059
6060+/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
6061+ help the compiler make use of that fact. */
6062+#if __OPTION_EGLIBC_LOCALE_CODE
6063+# define string_mb_cur_max(str) ((str)->mb_cur_max + 0)
6064+#else
6065+# define string_mb_cur_max(str) (1)
6066+#endif
6067
6068 struct re_dfa_t;
6069 typedef struct re_dfa_t re_dfa_t;
6070@@ -654,6 +665,14 @@ struct re_dfa_t
6071 __libc_lock_define (, lock)
6072 };
6073
6074+/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
6075+ help the compiler make use of that fact. */
6076+#if __OPTION_EGLIBC_LOCALE_CODE
6077+# define dfa_mb_cur_max(dfa) ((dfa)->mb_cur_max + 0)
6078+#else
6079+# define dfa_mb_cur_max(dfa) (1)
6080+#endif
6081+
6082 #define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
6083 #define re_node_set_remove(set,id) \
6084 (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
6085@@ -714,7 +733,7 @@ internal_function __attribute__ ((pure, unused))
6086 re_string_char_size_at (const re_string_t *pstr, int idx)
6087 {
6088 int byte_idx;
6089- if (pstr->mb_cur_max == 1)
6090+ if (string_mb_cur_max (pstr) == 1)
6091 return 1;
6092 for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
6093 if (pstr->wcs[idx + byte_idx] != WEOF)
6094@@ -726,7 +745,7 @@ static wint_t
6095 internal_function __attribute__ ((pure, unused))
6096 re_string_wchar_at (const re_string_t *pstr, int idx)
6097 {
6098- if (pstr->mb_cur_max == 1)
6099+ if (string_mb_cur_max (pstr) == 1)
6100 return (wint_t) pstr->mbs[idx];
6101 return (wint_t) pstr->wcs[idx];
6102 }
6103diff --git a/posix/regexec-compat.c b/posix/regexec-compat.c
6104new file mode 100644
6105index 0000000..0f9b7c7
6106--- /dev/null
6107+++ b/posix/regexec-compat.c
6108@@ -0,0 +1,39 @@
6109+/* Extended regular expression matching and search library.
6110+ Copyright (C) 2008 Free Software Foundation, Inc.
6111+ This file is part of the GNU C Library.
6112+ Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
6113+
6114+ The GNU C Library is free software; you can redistribute it and/or
6115+ modify it under the terms of the GNU Lesser General Public
6116+ License as published by the Free Software Foundation; either
6117+ version 2.1 of the License, or (at your option) any later version.
6118+
6119+ The GNU C Library is distributed in the hope that it will be useful,
6120+ but WITHOUT ANY WARRANTY; without even the implied warranty of
6121+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6122+ Lesser General Public License for more details.
6123+
6124+ You should have received a copy of the GNU Lesser General Public
6125+ License along with the GNU C Library; if not, write to the Free
6126+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
6127+ 02111-1307 USA. */
6128+
6129+#ifdef _LIBC
6130+# include <shlib-compat.h>
6131+versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
6132+
6133+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
6134+__typeof__ (__regexec) __compat_regexec;
6135+
6136+int
6137+attribute_compat_text_section
6138+__compat_regexec (const regex_t *__restrict preg,
6139+ const char *__restrict string, size_t nmatch,
6140+ regmatch_t pmatch[], int eflags)
6141+{
6142+ return regexec (preg, string, nmatch, pmatch,
6143+ eflags & (REG_NOTBOL | REG_NOTEOL));
6144+}
6145+compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
6146+# endif
6147+#endif
6148diff --git a/posix/regexec.c b/posix/regexec.c
6149index 70cd606..e3b49e4 100644
6150--- a/posix/regexec.c
6151+++ b/posix/regexec.c
6152@@ -18,6 +18,7 @@
6153 <http://www.gnu.org/licenses/>. */
6154
6155 #include <stdint.h>
6156+#include <gnu/option-groups.h>
6157
6158 static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
6159 int n) internal_function;
6160@@ -186,11 +187,11 @@ static int build_trtable (const re_dfa_t *dfa,
6161 static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
6162 const re_string_t *input, int idx)
6163 internal_function;
6164-# ifdef _LIBC
6165+# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
6166 static unsigned int find_collation_sequence_value (const unsigned char *mbs,
6167 size_t name_len)
6168 internal_function;
6169-# endif /* _LIBC */
6170+# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
6171 #endif /* RE_ENABLE_I18N */
6172 static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
6173 const re_dfastate_t *state,
6174@@ -255,25 +256,9 @@ regexec (preg, string, nmatch, pmatch, eflags)
6175 return err != REG_NOERROR;
6176 }
6177
6178-#ifdef _LIBC
6179-# include <shlib-compat.h>
6180-versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
6181-
6182-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
6183-__typeof__ (__regexec) __compat_regexec;
6184-
6185-int
6186-attribute_compat_text_section
6187-__compat_regexec (const regex_t *__restrict preg,
6188- const char *__restrict string, size_t nmatch,
6189- regmatch_t pmatch[], int eflags)
6190-{
6191- return regexec (preg, string, nmatch, pmatch,
6192- eflags & (REG_NOTBOL | REG_NOTEOL));
6193-}
6194-compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
6195-# endif
6196-#endif
6197+/* EGLIBC: The code that used to be here was move to a separate file
6198+ so that it can be shared with xregex.c. */
6199+#include "regexec-compat.c"
6200
6201 /* Entry points for GNU code. */
6202
6203@@ -728,7 +713,7 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
6204 incr = (range < 0) ? -1 : 1;
6205 left_lim = (range < 0) ? start + range : start;
6206 right_lim = (range < 0) ? start : start + range;
6207- sb = dfa->mb_cur_max == 1;
6208+ sb = dfa_mb_cur_max (dfa) == 1;
6209 match_kind =
6210 (fastmap
6211 ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
6212@@ -3448,7 +3433,7 @@ out_free:
6213 if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
6214 goto out_free;
6215
6216- if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
6217+ if (dest_states[i] != dest_states_word[i] && dfa_mb_cur_max (dfa) > 1)
6218 need_word_trtable = 1;
6219
6220 dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
6221@@ -3590,7 +3575,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
6222 else if (type == OP_PERIOD)
6223 {
6224 #ifdef RE_ENABLE_I18N
6225- if (dfa->mb_cur_max > 1)
6226+ if (dfa_mb_cur_max (dfa) > 1)
6227 bitset_merge (accepts, dfa->sb_char);
6228 else
6229 #endif
6230@@ -3641,7 +3626,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
6231 continue;
6232 }
6233 #ifdef RE_ENABLE_I18N
6234- if (dfa->mb_cur_max > 1)
6235+ if (dfa_mb_cur_max (dfa) > 1)
6236 for (j = 0; j < BITSET_WORDS; ++j)
6237 any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
6238 else
6239@@ -3660,7 +3645,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
6240 continue;
6241 }
6242 #ifdef RE_ENABLE_I18N
6243- if (dfa->mb_cur_max > 1)
6244+ if (dfa_mb_cur_max (dfa) > 1)
6245 for (j = 0; j < BITSET_WORDS; ++j)
6246 any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
6247 else
6248@@ -3836,12 +3821,6 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
6249 if (node->type == COMPLEX_BRACKET)
6250 {
6251 const re_charset_t *cset = node->opr.mbcset;
6252-# ifdef _LIBC
6253- const unsigned char *pin
6254- = ((const unsigned char *) re_string_get_buffer (input) + str_idx);
6255- int j;
6256- uint32_t nrules;
6257-# endif /* _LIBC */
6258 int match_len = 0;
6259 wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
6260 ? re_string_wchar_at (input, str_idx) : 0);
6261@@ -3853,6 +3832,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
6262 match_len = char_len;
6263 goto check_node_accept_bytes_match;
6264 }
6265+#if __OPTION_EGLIBC_LOCALE_CODE
6266 /* match with character_class? */
6267 for (i = 0; i < cset->nchar_classes; ++i)
6268 {
6269@@ -3863,14 +3843,22 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
6270 goto check_node_accept_bytes_match;
6271 }
6272 }
6273+#endif
6274+
6275+ /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C
6276+ locale is supported; it has no collation rules. */
6277+# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
6278+ const unsigned char *pin
6279+ = ((const unsigned char *) re_string_get_buffer (input) + str_idx);
6280+ int j;
6281+ uint32_t nrules;
6282
6283-# ifdef _LIBC
6284 nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
6285 if (nrules != 0)
6286 {
6287 unsigned int in_collseq = 0;
6288 const int32_t *table, *indirect;
6289- const unsigned char *weights, *extra;
6290+ const unsigned char *weights, *extra = NULL;
6291 const char *collseqwc;
6292
6293 /* match with collating_symbol? */
6294@@ -3955,8 +3943,12 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
6295 }
6296 }
6297 else
6298-# endif /* _LIBC */
6299+# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
6300 {
6301+ /* In the _LIBC version, if OPTION_EGLIBC_LOCALE_CODE is
6302+ disabled, there can be no multibyte range endpoints, and
6303+ cset->nranges is always zero. */
6304+#if __OPTION_EGLIBC_LOCALE_CODE
6305 /* match with range expression? */
6306 #if __GNUC__ >= 2
6307 wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
6308@@ -3975,6 +3967,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
6309 goto check_node_accept_bytes_match;
6310 }
6311 }
6312+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
6313 }
6314 check_node_accept_bytes_match:
6315 if (!cset->non_match)
6316@@ -3990,7 +3983,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
6317 return 0;
6318 }
6319
6320-# ifdef _LIBC
6321+# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
6322 static unsigned int
6323 internal_function
6324 find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
6325@@ -4048,7 +4041,7 @@ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
6326 return UINT_MAX;
6327 }
6328 }
6329-# endif /* _LIBC */
6330+# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
6331 #endif /* RE_ENABLE_I18N */
6332
6333 /* Check whether the node accepts the byte which is IDX-th
6334@@ -4139,7 +4132,7 @@ extend_buffers (re_match_context_t *mctx, int min_len)
6335 if (pstr->icase)
6336 {
6337 #ifdef RE_ENABLE_I18N
6338- if (pstr->mb_cur_max > 1)
6339+ if (string_mb_cur_max (pstr) > 1)
6340 {
6341 ret = build_wcs_upper_buffer (pstr);
6342 if (BE (ret != REG_NOERROR, 0))
6343@@ -4152,7 +4145,7 @@ extend_buffers (re_match_context_t *mctx, int min_len)
6344 else
6345 {
6346 #ifdef RE_ENABLE_I18N
6347- if (pstr->mb_cur_max > 1)
6348+ if (string_mb_cur_max (pstr) > 1)
6349 build_wcs_buffer (pstr);
6350 else
6351 #endif /* RE_ENABLE_I18N */
6352diff --git a/posix/xregex.c b/posix/xregex.c
6353new file mode 100644
6354index 0000000..d3f7ace
6355--- /dev/null
6356+++ b/posix/xregex.c
6357@@ -0,0 +1,8215 @@
6358+/* Extended regular expression matching and search library,
6359+ version 0.12.
6360+ (Implements POSIX draft P1003.2/D11.2, except for some of the
6361+ internationalization features.)
6362+
6363+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
6364+ 2002, 2005 Free Software Foundation, Inc.
6365+ This file is part of the GNU C Library.
6366+
6367+ The GNU C Library is free software; you can redistribute it and/or
6368+ modify it under the terms of the GNU Lesser General Public
6369+ License as published by the Free Software Foundation; either
6370+ version 2.1 of the License, or (at your option) any later version.
6371+
6372+ The GNU C Library is distributed in the hope that it will be useful,
6373+ but WITHOUT ANY WARRANTY; without even the implied warranty of
6374+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6375+ Lesser General Public License for more details.
6376+
6377+ You should have received a copy of the GNU Lesser General Public
6378+ License along with the GNU C Library; if not, write to the Free
6379+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
6380+ 02110-1301 USA. */
6381+
6382+/* AIX requires this to be the first thing in the file. */
6383+#if defined _AIX && !defined __GNUC__ && !defined REGEX_MALLOC
6384+ #pragma alloca
6385+#endif
6386+
6387+#undef _GNU_SOURCE
6388+#define _GNU_SOURCE
6389+
6390+#ifndef INSIDE_RECURSION
6391+# ifdef HAVE_CONFIG_H
6392+# include <config.h>
6393+# endif
6394+#endif
6395+
6396+/*#include <ansidecl.h>*/
6397+
6398+
6399+#ifndef INSIDE_RECURSION
6400+
6401+# if defined STDC_HEADERS && !defined emacs
6402+# include <stddef.h>
6403+# else
6404+/* We need this for `regex.h', and perhaps for the Emacs include files. */
6405+# include <sys/types.h>
6406+# endif
6407+
6408+# if (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_BTOWC)
6409+# define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC)
6410+# else
6411+# define WIDE_CHAR_SUPPORT 0
6412+# endif
6413+/* For platform which support the ISO C amendement 1 functionality we
6414+ support user defined character classes. */
6415+# if WIDE_CHAR_SUPPORT
6416+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
6417+# include <wchar.h>
6418+# include <wctype.h>
6419+# endif
6420+
6421+# ifdef _LIBC
6422+/* We have to keep the namespace clean. */
6423+# define regfree(preg) __regfree (preg)
6424+# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
6425+# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
6426+# define regerror(errcode, preg, errbuf, errbuf_size) \
6427+ __regerror(errcode, preg, errbuf, errbuf_size)
6428+# define re_set_registers(bu, re, nu, st, en) \
6429+ __re_set_registers (bu, re, nu, st, en)
6430+# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
6431+ __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
6432+# define re_match(bufp, string, size, pos, regs) \
6433+ __re_match (bufp, string, size, pos, regs)
6434+# define re_search(bufp, string, size, startpos, range, regs) \
6435+ __re_search (bufp, string, size, startpos, range, regs)
6436+# define re_compile_pattern(pattern, length, bufp) \
6437+ __re_compile_pattern (pattern, length, bufp)
6438+# define re_set_syntax(syntax) __re_set_syntax (syntax)
6439+# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
6440+ __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
6441+# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
6442+
6443+# define btowc __btowc
6444+
6445+/* We are also using some library internals. */
6446+# include <locale/localeinfo.h>
6447+# include <locale/elem-hash.h>
6448+# include <langinfo.h>
6449+# include <locale/coll-lookup.h>
6450+# endif
6451+
6452+/* This is for other GNU distributions with internationalized messages. */
6453+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
6454+# include <libintl.h>
6455+# ifdef _LIBC
6456+# undef gettext
6457+# define gettext(msgid) __dcgettext ("libc", msgid, LC_MESSAGES)
6458+# endif
6459+# else
6460+# define gettext(msgid) (msgid)
6461+# endif
6462+
6463+# ifndef gettext_noop
6464+/* This define is so xgettext can find the internationalizable
6465+ strings. */
6466+# define gettext_noop(String) String
6467+# endif
6468+
6469+/* The `emacs' switch turns on certain matching commands
6470+ that make sense only in Emacs. */
6471+# ifdef emacs
6472+
6473+# include "lisp.h"
6474+# include "buffer.h"
6475+# include "syntax.h"
6476+
6477+# else /* not emacs */
6478+
6479+/* If we are not linking with Emacs proper,
6480+ we can't use the relocating allocator
6481+ even if config.h says that we can. */
6482+# undef REL_ALLOC
6483+
6484+# if defined STDC_HEADERS || defined _LIBC
6485+# include <stdlib.h>
6486+# else
6487+char *malloc ();
6488+char *realloc ();
6489+# endif
6490+
6491+/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
6492+ If nothing else has been done, use the method below. */
6493+# ifdef INHIBIT_STRING_HEADER
6494+# if !(defined HAVE_BZERO && defined HAVE_BCOPY)
6495+# if !defined bzero && !defined bcopy
6496+# undef INHIBIT_STRING_HEADER
6497+# endif
6498+# endif
6499+# endif
6500+
6501+/* This is the normal way of making sure we have a bcopy and a bzero.
6502+ This is used in most programs--a few other programs avoid this
6503+ by defining INHIBIT_STRING_HEADER. */
6504+# ifndef INHIBIT_STRING_HEADER
6505+# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC
6506+# include <string.h>
6507+# ifndef bzero
6508+# ifndef _LIBC
6509+# define bzero(s, n) (memset (s, '\0', n), (s))
6510+# else
6511+# define bzero(s, n) __bzero (s, n)
6512+# endif
6513+# endif
6514+# else
6515+# include <strings.h>
6516+# ifndef memcmp
6517+# define memcmp(s1, s2, n) bcmp (s1, s2, n)
6518+# endif
6519+# ifndef memcpy
6520+# define memcpy(d, s, n) (bcopy (s, d, n), (d))
6521+# endif
6522+# endif
6523+# endif
6524+
6525+/* Define the syntax stuff for \<, \>, etc. */
6526+
6527+/* This must be nonzero for the wordchar and notwordchar pattern
6528+ commands in re_match_2. */
6529+# ifndef Sword
6530+# define Sword 1
6531+# endif
6532+
6533+# ifdef SWITCH_ENUM_BUG
6534+# define SWITCH_ENUM_CAST(x) ((int)(x))
6535+# else
6536+# define SWITCH_ENUM_CAST(x) (x)
6537+# endif
6538+
6539+# endif /* not emacs */
6540+
6541+# if defined _LIBC || HAVE_LIMITS_H
6542+# include <limits.h>
6543+# endif
6544+
6545+# ifndef MB_LEN_MAX
6546+# define MB_LEN_MAX 1
6547+# endif
6548+
6549+/* Get the interface, including the syntax bits. */
6550+# include "regex.h"
6551+
6552+/* isalpha etc. are used for the character classes. */
6553+# include <ctype.h>
6554+
6555+/* Jim Meyering writes:
6556+
6557+ "... Some ctype macros are valid only for character codes that
6558+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
6559+ using /bin/cc or gcc but without giving an ansi option). So, all
6560+ ctype uses should be through macros like ISPRINT... If
6561+ STDC_HEADERS is defined, then autoconf has verified that the ctype
6562+ macros don't need to be guarded with references to isascii. ...
6563+ Defining isascii to 1 should let any compiler worth its salt
6564+ eliminate the && through constant folding."
6565+ Solaris defines some of these symbols so we must undefine them first. */
6566+
6567+# undef ISASCII
6568+# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
6569+# define ISASCII(c) 1
6570+# else
6571+# define ISASCII(c) isascii(c)
6572+# endif
6573+
6574+# ifdef isblank
6575+# define ISBLANK(c) (ISASCII (c) && isblank (c))
6576+# else
6577+# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
6578+# endif
6579+# ifdef isgraph
6580+# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
6581+# else
6582+# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
6583+# endif
6584+
6585+# undef ISPRINT
6586+# define ISPRINT(c) (ISASCII (c) && isprint (c))
6587+# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
6588+# define ISALNUM(c) (ISASCII (c) && isalnum (c))
6589+# define ISALPHA(c) (ISASCII (c) && isalpha (c))
6590+# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
6591+# define ISLOWER(c) (ISASCII (c) && islower (c))
6592+# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
6593+# define ISSPACE(c) (ISASCII (c) && isspace (c))
6594+# define ISUPPER(c) (ISASCII (c) && isupper (c))
6595+# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
6596+
6597+# ifdef _tolower
6598+# define TOLOWER(c) _tolower(c)
6599+# else
6600+# define TOLOWER(c) tolower(c)
6601+# endif
6602+
6603+# ifndef NULL
6604+# define NULL (void *)0
6605+# endif
6606+
6607+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
6608+ since ours (we hope) works properly with all combinations of
6609+ machines, compilers, `char' and `unsigned char' argument types.
6610+ (Per Bothner suggested the basic approach.) */
6611+# undef SIGN_EXTEND_CHAR
6612+# if __STDC__
6613+# define SIGN_EXTEND_CHAR(c) ((signed char) (c))
6614+# else /* not __STDC__ */
6615+/* As in Harbison and Steele. */
6616+# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
6617+# endif
6618+
6619+# ifndef emacs
6620+/* How many characters in the character set. */
6621+# define CHAR_SET_SIZE 256
6622+
6623+# ifdef SYNTAX_TABLE
6624+
6625+extern char *re_syntax_table;
6626+
6627+# else /* not SYNTAX_TABLE */
6628+
6629+static char re_syntax_table[CHAR_SET_SIZE];
6630+
6631+static void init_syntax_once (void);
6632+
6633+static void
6634+init_syntax_once (void)
6635+{
6636+ register int c;
6637+ static int done = 0;
6638+
6639+ if (done)
6640+ return;
6641+ bzero (re_syntax_table, sizeof re_syntax_table);
6642+
6643+ for (c = 0; c < CHAR_SET_SIZE; ++c)
6644+ if (ISALNUM (c))
6645+ re_syntax_table[c] = Sword;
6646+
6647+ re_syntax_table['_'] = Sword;
6648+
6649+ done = 1;
6650+}
6651+
6652+# endif /* not SYNTAX_TABLE */
6653+
6654+# define SYNTAX(c) re_syntax_table[(unsigned char) (c)]
6655+
6656+# endif /* emacs */
6657+
6658+/* Integer type for pointers. */
6659+# if !defined _LIBC && !defined HAVE_UINTPTR_T
6660+typedef unsigned long int uintptr_t;
6661+# endif
6662+
6663+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
6664+ use `alloca' instead of `malloc'. This is because using malloc in
6665+ re_search* or re_match* could cause memory leaks when C-g is used in
6666+ Emacs; also, malloc is slower and causes storage fragmentation. On
6667+ the other hand, malloc is more portable, and easier to debug.
6668+
6669+ Because we sometimes use alloca, some routines have to be macros,
6670+ not functions -- `alloca'-allocated space disappears at the end of the
6671+ function it is called in. */
6672+
6673+# ifdef REGEX_MALLOC
6674+
6675+# define REGEX_ALLOCATE malloc
6676+# define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
6677+# define REGEX_FREE free
6678+
6679+# else /* not REGEX_MALLOC */
6680+
6681+/* Emacs already defines alloca, sometimes. */
6682+# ifndef alloca
6683+
6684+/* Make alloca work the best possible way. */
6685+# ifdef __GNUC__
6686+# define alloca __builtin_alloca
6687+# else /* not __GNUC__ */
6688+# if HAVE_ALLOCA_H
6689+# include <alloca.h>
6690+# endif /* HAVE_ALLOCA_H */
6691+# endif /* not __GNUC__ */
6692+
6693+# endif /* not alloca */
6694+
6695+# define REGEX_ALLOCATE alloca
6696+
6697+/* Assumes a `char *destination' variable. */
6698+# define REGEX_REALLOCATE(source, osize, nsize) \
6699+ (destination = (char *) alloca (nsize), \
6700+ memcpy (destination, source, osize))
6701+
6702+/* No need to do anything to free, after alloca. */
6703+# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */
6704+
6705+# endif /* not REGEX_MALLOC */
6706+
6707+/* Define how to allocate the failure stack. */
6708+
6709+# if defined REL_ALLOC && defined REGEX_MALLOC
6710+
6711+# define REGEX_ALLOCATE_STACK(size) \
6712+ r_alloc (&failure_stack_ptr, (size))
6713+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
6714+ r_re_alloc (&failure_stack_ptr, (nsize))
6715+# define REGEX_FREE_STACK(ptr) \
6716+ r_alloc_free (&failure_stack_ptr)
6717+
6718+# else /* not using relocating allocator */
6719+
6720+# ifdef REGEX_MALLOC
6721+
6722+# define REGEX_ALLOCATE_STACK malloc
6723+# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
6724+# define REGEX_FREE_STACK free
6725+
6726+# else /* not REGEX_MALLOC */
6727+
6728+# define REGEX_ALLOCATE_STACK alloca
6729+
6730+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
6731+ REGEX_REALLOCATE (source, osize, nsize)
6732+/* No need to explicitly free anything. */
6733+# define REGEX_FREE_STACK(arg)
6734+
6735+# endif /* not REGEX_MALLOC */
6736+# endif /* not using relocating allocator */
6737+
6738+
6739+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
6740+ `string1' or just past its end. This works if PTR is NULL, which is
6741+ a good thing. */
6742+# define FIRST_STRING_P(ptr) \
6743+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
6744+
6745+/* (Re)Allocate N items of type T using malloc, or fail. */
6746+# define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
6747+# define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
6748+# define RETALLOC_IF(addr, n, t) \
6749+ if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
6750+# define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
6751+
6752+# define BYTEWIDTH 8 /* In bits. */
6753+
6754+# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
6755+
6756+# undef MAX
6757+# undef MIN
6758+# define MAX(a, b) ((a) > (b) ? (a) : (b))
6759+# define MIN(a, b) ((a) < (b) ? (a) : (b))
6760+
6761+typedef char boolean;
6762+# define false 0
6763+# define true 1
6764+
6765+static reg_errcode_t byte_regex_compile (const char *pattern, size_t size,
6766+ reg_syntax_t syntax,
6767+ struct re_pattern_buffer *bufp);
6768+
6769+static int byte_re_match_2_internal (struct re_pattern_buffer *bufp,
6770+ const char *string1, int size1,
6771+ const char *string2, int size2,
6772+ int pos,
6773+ struct re_registers *regs,
6774+ int stop);
6775+static int byte_re_search_2 (struct re_pattern_buffer *bufp,
6776+ const char *string1, int size1,
6777+ const char *string2, int size2,
6778+ int startpos, int range,
6779+ struct re_registers *regs, int stop);
6780+static int byte_re_compile_fastmap (struct re_pattern_buffer *bufp);
6781+
6782+#ifdef MBS_SUPPORT
6783+static reg_errcode_t wcs_regex_compile (const char *pattern, size_t size,
6784+ reg_syntax_t syntax,
6785+ struct re_pattern_buffer *bufp);
6786+
6787+
6788+static int wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
6789+ const char *cstring1, int csize1,
6790+ const char *cstring2, int csize2,
6791+ int pos,
6792+ struct re_registers *regs,
6793+ int stop,
6794+ wchar_t *string1, int size1,
6795+ wchar_t *string2, int size2,
6796+ int *mbs_offset1, int *mbs_offset2);
6797+static int wcs_re_search_2 (struct re_pattern_buffer *bufp,
6798+ const char *string1, int size1,
6799+ const char *string2, int size2,
6800+ int startpos, int range,
6801+ struct re_registers *regs, int stop);
6802+static int wcs_re_compile_fastmap (struct re_pattern_buffer *bufp);
6803+#endif
6804+
6805+/* These are the command codes that appear in compiled regular
6806+ expressions. Some opcodes are followed by argument bytes. A
6807+ command code can specify any interpretation whatsoever for its
6808+ arguments. Zero bytes may appear in the compiled regular expression. */
6809+
6810+typedef enum
6811+{
6812+ no_op = 0,
6813+
6814+ /* Succeed right away--no more backtracking. */
6815+ succeed,
6816+
6817+ /* Followed by one byte giving n, then by n literal bytes. */
6818+ exactn,
6819+
6820+# ifdef MBS_SUPPORT
6821+ /* Same as exactn, but contains binary data. */
6822+ exactn_bin,
6823+# endif
6824+
6825+ /* Matches any (more or less) character. */
6826+ anychar,
6827+
6828+ /* Matches any one char belonging to specified set. First
6829+ following byte is number of bitmap bytes. Then come bytes
6830+ for a bitmap saying which chars are in. Bits in each byte
6831+ are ordered low-bit-first. A character is in the set if its
6832+ bit is 1. A character too large to have a bit in the map is
6833+ automatically not in the set. */
6834+ /* ifdef MBS_SUPPORT, following element is length of character
6835+ classes, length of collating symbols, length of equivalence
6836+ classes, length of character ranges, and length of characters.
6837+ Next, character class element, collating symbols elements,
6838+ equivalence class elements, range elements, and character
6839+ elements follow.
6840+ See regex_compile function. */
6841+ charset,
6842+
6843+ /* Same parameters as charset, but match any character that is
6844+ not one of those specified. */
6845+ charset_not,
6846+
6847+ /* Start remembering the text that is matched, for storing in a
6848+ register. Followed by one byte with the register number, in
6849+ the range 0 to one less than the pattern buffer's re_nsub
6850+ field. Then followed by one byte with the number of groups
6851+ inner to this one. (This last has to be part of the
6852+ start_memory only because we need it in the on_failure_jump
6853+ of re_match_2.) */
6854+ start_memory,
6855+
6856+ /* Stop remembering the text that is matched and store it in a
6857+ memory register. Followed by one byte with the register
6858+ number, in the range 0 to one less than `re_nsub' in the
6859+ pattern buffer, and one byte with the number of inner groups,
6860+ just like `start_memory'. (We need the number of inner
6861+ groups here because we don't have any easy way of finding the
6862+ corresponding start_memory when we're at a stop_memory.) */
6863+ stop_memory,
6864+
6865+ /* Match a duplicate of something remembered. Followed by one
6866+ byte containing the register number. */
6867+ duplicate,
6868+
6869+ /* Fail unless at beginning of line. */
6870+ begline,
6871+
6872+ /* Fail unless at end of line. */
6873+ endline,
6874+
6875+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
6876+ of string to be matched (if not). */
6877+ begbuf,
6878+
6879+ /* Analogously, for end of buffer/string. */
6880+ endbuf,
6881+
6882+ /* Followed by two byte relative address to which to jump. */
6883+ jump,
6884+
6885+ /* Same as jump, but marks the end of an alternative. */
6886+ jump_past_alt,
6887+
6888+ /* Followed by two-byte relative address of place to resume at
6889+ in case of failure. */
6890+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6891+ on_failure_jump,
6892+
6893+ /* Like on_failure_jump, but pushes a placeholder instead of the
6894+ current string position when executed. */
6895+ on_failure_keep_string_jump,
6896+
6897+ /* Throw away latest failure point and then jump to following
6898+ two-byte relative address. */
6899+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6900+ pop_failure_jump,
6901+
6902+ /* Change to pop_failure_jump if know won't have to backtrack to
6903+ match; otherwise change to jump. This is used to jump
6904+ back to the beginning of a repeat. If what follows this jump
6905+ clearly won't match what the repeat does, such that we can be
6906+ sure that there is no use backtracking out of repetitions
6907+ already matched, then we change it to a pop_failure_jump.
6908+ Followed by two-byte address. */
6909+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6910+ maybe_pop_jump,
6911+
6912+ /* Jump to following two-byte address, and push a dummy failure
6913+ point. This failure point will be thrown away if an attempt
6914+ is made to use it for a failure. A `+' construct makes this
6915+ before the first repeat. Also used as an intermediary kind
6916+ of jump when compiling an alternative. */
6917+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6918+ dummy_failure_jump,
6919+
6920+ /* Push a dummy failure point and continue. Used at the end of
6921+ alternatives. */
6922+ push_dummy_failure,
6923+
6924+ /* Followed by two-byte relative address and two-byte number n.
6925+ After matching N times, jump to the address upon failure. */
6926+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6927+ succeed_n,
6928+
6929+ /* Followed by two-byte relative address, and two-byte number n.
6930+ Jump to the address N times, then fail. */
6931+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6932+ jump_n,
6933+
6934+ /* Set the following two-byte relative address to the
6935+ subsequent two-byte number. The address *includes* the two
6936+ bytes of number. */
6937+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6938+ set_number_at,
6939+
6940+ wordchar, /* Matches any word-constituent character. */
6941+ notwordchar, /* Matches any char that is not a word-constituent. */
6942+
6943+ wordbeg, /* Succeeds if at word beginning. */
6944+ wordend, /* Succeeds if at word end. */
6945+
6946+ wordbound, /* Succeeds if at a word boundary. */
6947+ notwordbound /* Succeeds if not at a word boundary. */
6948+
6949+# ifdef emacs
6950+ ,before_dot, /* Succeeds if before point. */
6951+ at_dot, /* Succeeds if at point. */
6952+ after_dot, /* Succeeds if after point. */
6953+
6954+ /* Matches any character whose syntax is specified. Followed by
6955+ a byte which contains a syntax code, e.g., Sword. */
6956+ syntaxspec,
6957+
6958+ /* Matches any character whose syntax is not that specified. */
6959+ notsyntaxspec
6960+# endif /* emacs */
6961+} re_opcode_t;
6962+#endif /* not INSIDE_RECURSION */
6963+
6964+
6965+#ifdef BYTE
6966+# define CHAR_T char
6967+# define UCHAR_T unsigned char
6968+# define COMPILED_BUFFER_VAR bufp->buffer
6969+# define OFFSET_ADDRESS_SIZE 2
6970+# define PREFIX(name) byte_##name
6971+# define ARG_PREFIX(name) name
6972+# define PUT_CHAR(c) putchar (c)
6973+# include <locale/weight.h>
6974+# define FINDIDX findidx
6975+#else
6976+# ifdef WCHAR
6977+# define CHAR_T wchar_t
6978+# define UCHAR_T wchar_t
6979+# define COMPILED_BUFFER_VAR wc_buffer
6980+# define OFFSET_ADDRESS_SIZE 1 /* the size which STORE_NUMBER macro use */
6981+# define CHAR_CLASS_SIZE ((__alignof__(wctype_t)+sizeof(wctype_t))/sizeof(CHAR_T)+1)
6982+# define PREFIX(name) wcs_##name
6983+# define ARG_PREFIX(name) c##name
6984+/* Should we use wide stream?? */
6985+# define PUT_CHAR(c) printf ("%C", c);
6986+# define TRUE 1
6987+# define FALSE 0
6988+# define findidx findidxwc
6989+# include <locale/weightwc.h>
6990+# undef findidx
6991+# define FINDIDX findidxwc
6992+# else
6993+# ifdef MBS_SUPPORT
6994+# define WCHAR
6995+# define INSIDE_RECURSION
6996+# include "xregex.c"
6997+# undef INSIDE_RECURSION
6998+# endif
6999+# define BYTE
7000+# define INSIDE_RECURSION
7001+# include "xregex.c"
7002+# undef INSIDE_RECURSION
7003+# endif
7004+#endif
7005+
7006+#ifdef INSIDE_RECURSION
7007+/* Common operations on the compiled pattern. */
7008+
7009+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
7010+/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */
7011+
7012+# ifdef WCHAR
7013+# define STORE_NUMBER(destination, number) \
7014+ do { \
7015+ *(destination) = (UCHAR_T)(number); \
7016+ } while (0)
7017+# else /* BYTE */
7018+# define STORE_NUMBER(destination, number) \
7019+ do { \
7020+ (destination)[0] = (number) & 0377; \
7021+ (destination)[1] = (number) >> 8; \
7022+ } while (0)
7023+# endif /* WCHAR */
7024+
7025+/* Same as STORE_NUMBER, except increment DESTINATION to
7026+ the byte after where the number is stored. Therefore, DESTINATION
7027+ must be an lvalue. */
7028+/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */
7029+
7030+# define STORE_NUMBER_AND_INCR(destination, number) \
7031+ do { \
7032+ STORE_NUMBER (destination, number); \
7033+ (destination) += OFFSET_ADDRESS_SIZE; \
7034+ } while (0)
7035+
7036+/* Put into DESTINATION a number stored in two contiguous bytes starting
7037+ at SOURCE. */
7038+/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */
7039+
7040+# ifdef WCHAR
7041+# define EXTRACT_NUMBER(destination, source) \
7042+ do { \
7043+ (destination) = *(source); \
7044+ } while (0)
7045+# else /* BYTE */
7046+# define EXTRACT_NUMBER(destination, source) \
7047+ do { \
7048+ (destination) = *(source) & 0377; \
7049+ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
7050+ } while (0)
7051+# endif
7052+
7053+# ifdef DEBUG
7054+static void PREFIX(extract_number) (int *dest, UCHAR_T *source);
7055+static void
7056+PREFIX(extract_number) (int *dest, UCHAR_T *source)
7057+{
7058+# ifdef WCHAR
7059+ *dest = *source;
7060+# else /* BYTE */
7061+ int temp = SIGN_EXTEND_CHAR (*(source + 1));
7062+ *dest = *source & 0377;
7063+ *dest += temp << 8;
7064+# endif
7065+}
7066+
7067+# ifndef EXTRACT_MACROS /* To debug the macros. */
7068+# undef EXTRACT_NUMBER
7069+# define EXTRACT_NUMBER(dest, src) PREFIX(extract_number) (&dest, src)
7070+# endif /* not EXTRACT_MACROS */
7071+
7072+# endif /* DEBUG */
7073+
7074+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
7075+ SOURCE must be an lvalue. */
7076+
7077+# define EXTRACT_NUMBER_AND_INCR(destination, source) \
7078+ do { \
7079+ EXTRACT_NUMBER (destination, source); \
7080+ (source) += OFFSET_ADDRESS_SIZE; \
7081+ } while (0)
7082+
7083+# ifdef DEBUG
7084+static void PREFIX(extract_number_and_incr) (int *destination,
7085+ UCHAR_T **source);
7086+static void
7087+PREFIX(extract_number_and_incr) (int *destination, UCHAR_T **source)
7088+{
7089+ PREFIX(extract_number) (destination, *source);
7090+ *source += OFFSET_ADDRESS_SIZE;
7091+}
7092+
7093+# ifndef EXTRACT_MACROS
7094+# undef EXTRACT_NUMBER_AND_INCR
7095+# define EXTRACT_NUMBER_AND_INCR(dest, src) \
7096+ PREFIX(extract_number_and_incr) (&dest, &src)
7097+# endif /* not EXTRACT_MACROS */
7098+
7099+# endif /* DEBUG */
7100+
7101+
7102+
7103+/* If DEBUG is defined, Regex prints many voluminous messages about what
7104+ it is doing (if the variable `debug' is nonzero). If linked with the
7105+ main program in `iregex.c', you can enter patterns and strings
7106+ interactively. And if linked with the main program in `main.c' and
7107+ the other test files, you can run the already-written tests. */
7108+
7109+# ifdef DEBUG
7110+
7111+# ifndef DEFINED_ONCE
7112+
7113+/* We use standard I/O for debugging. */
7114+# include <stdio.h>
7115+
7116+/* It is useful to test things that ``must'' be true when debugging. */
7117+# include <assert.h>
7118+
7119+static int debug;
7120+
7121+# define DEBUG_STATEMENT(e) e
7122+# define DEBUG_PRINT1(x) if (debug) printf (x)
7123+# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
7124+# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
7125+# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
7126+# endif /* not DEFINED_ONCE */
7127+
7128+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
7129+ if (debug) PREFIX(print_partial_compiled_pattern) (s, e)
7130+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
7131+ if (debug) PREFIX(print_double_string) (w, s1, sz1, s2, sz2)
7132+
7133+
7134+/* Print the fastmap in human-readable form. */
7135+
7136+# ifndef DEFINED_ONCE
7137+void
7138+print_fastmap (char *fastmap)
7139+{
7140+ unsigned was_a_range = 0;
7141+ unsigned i = 0;
7142+
7143+ while (i < (1 << BYTEWIDTH))
7144+ {
7145+ if (fastmap[i++])
7146+ {
7147+ was_a_range = 0;
7148+ putchar (i - 1);
7149+ while (i < (1 << BYTEWIDTH) && fastmap[i])
7150+ {
7151+ was_a_range = 1;
7152+ i++;
7153+ }
7154+ if (was_a_range)
7155+ {
7156+ printf ("-");
7157+ putchar (i - 1);
7158+ }
7159+ }
7160+ }
7161+ putchar ('\n');
7162+}
7163+# endif /* not DEFINED_ONCE */
7164+
7165+
7166+/* Print a compiled pattern string in human-readable form, starting at
7167+ the START pointer into it and ending just before the pointer END. */
7168+
7169+void
7170+PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end)
7171+{
7172+ int mcnt, mcnt2;
7173+ UCHAR_T *p1;
7174+ UCHAR_T *p = start;
7175+ UCHAR_T *pend = end;
7176+
7177+ if (start == NULL)
7178+ {
7179+ printf ("(null)\n");
7180+ return;
7181+ }
7182+
7183+ /* Loop over pattern commands. */
7184+ while (p < pend)
7185+ {
7186+# ifdef _LIBC
7187+ printf ("%td:\t", p - start);
7188+# else
7189+ printf ("%ld:\t", (long int) (p - start));
7190+# endif
7191+
7192+ switch ((re_opcode_t) *p++)
7193+ {
7194+ case no_op:
7195+ printf ("/no_op");
7196+ break;
7197+
7198+ case exactn:
7199+ mcnt = *p++;
7200+ printf ("/exactn/%d", mcnt);
7201+ do
7202+ {
7203+ putchar ('/');
7204+ PUT_CHAR (*p++);
7205+ }
7206+ while (--mcnt);
7207+ break;
7208+
7209+# ifdef MBS_SUPPORT
7210+ case exactn_bin:
7211+ mcnt = *p++;
7212+ printf ("/exactn_bin/%d", mcnt);
7213+ do
7214+ {
7215+ printf("/%lx", (long int) *p++);
7216+ }
7217+ while (--mcnt);
7218+ break;
7219+# endif /* MBS_SUPPORT */
7220+
7221+ case start_memory:
7222+ mcnt = *p++;
7223+ printf ("/start_memory/%d/%ld", mcnt, (long int) *p++);
7224+ break;
7225+
7226+ case stop_memory:
7227+ mcnt = *p++;
7228+ printf ("/stop_memory/%d/%ld", mcnt, (long int) *p++);
7229+ break;
7230+
7231+ case duplicate:
7232+ printf ("/duplicate/%ld", (long int) *p++);
7233+ break;
7234+
7235+ case anychar:
7236+ printf ("/anychar");
7237+ break;
7238+
7239+ case charset:
7240+ case charset_not:
7241+ {
7242+# ifdef WCHAR
7243+ int i, length;
7244+ wchar_t *workp = p;
7245+ printf ("/charset [%s",
7246+ (re_opcode_t) *(workp - 1) == charset_not ? "^" : "");
7247+ p += 5;
7248+ length = *workp++; /* the length of char_classes */
7249+ for (i=0 ; i<length ; i++)
7250+ printf("[:%lx:]", (long int) *p++);
7251+ length = *workp++; /* the length of collating_symbol */
7252+ for (i=0 ; i<length ;)
7253+ {
7254+ printf("[.");
7255+ while(*p != 0)
7256+ PUT_CHAR((i++,*p++));
7257+ i++,p++;
7258+ printf(".]");
7259+ }
7260+ length = *workp++; /* the length of equivalence_class */
7261+ for (i=0 ; i<length ;)
7262+ {
7263+ printf("[=");
7264+ while(*p != 0)
7265+ PUT_CHAR((i++,*p++));
7266+ i++,p++;
7267+ printf("=]");
7268+ }
7269+ length = *workp++; /* the length of char_range */
7270+ for (i=0 ; i<length ; i++)
7271+ {
7272+ wchar_t range_start = *p++;
7273+ wchar_t range_end = *p++;
7274+ printf("%C-%C", range_start, range_end);
7275+ }
7276+ length = *workp++; /* the length of char */
7277+ for (i=0 ; i<length ; i++)
7278+ printf("%C", *p++);
7279+ putchar (']');
7280+# else
7281+ register int c, last = -100;
7282+ register int in_range = 0;
7283+
7284+ printf ("/charset [%s",
7285+ (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
7286+
7287+ assert (p + *p < pend);
7288+
7289+ for (c = 0; c < 256; c++)
7290+ if (c / 8 < *p
7291+ && (p[1 + (c/8)] & (1 << (c % 8))))
7292+ {
7293+ /* Are we starting a range? */
7294+ if (last + 1 == c && ! in_range)
7295+ {
7296+ putchar ('-');
7297+ in_range = 1;
7298+ }
7299+ /* Have we broken a range? */
7300+ else if (last + 1 != c && in_range)
7301+ {
7302+ putchar (last);
7303+ in_range = 0;
7304+ }
7305+
7306+ if (! in_range)
7307+ putchar (c);
7308+
7309+ last = c;
7310+ }
7311+
7312+ if (in_range)
7313+ putchar (last);
7314+
7315+ putchar (']');
7316+
7317+ p += 1 + *p;
7318+# endif /* WCHAR */
7319+ }
7320+ break;
7321+
7322+ case begline:
7323+ printf ("/begline");
7324+ break;
7325+
7326+ case endline:
7327+ printf ("/endline");
7328+ break;
7329+
7330+ case on_failure_jump:
7331+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7332+# ifdef _LIBC
7333+ printf ("/on_failure_jump to %td", p + mcnt - start);
7334+# else
7335+ printf ("/on_failure_jump to %ld", (long int) (p + mcnt - start));
7336+# endif
7337+ break;
7338+
7339+ case on_failure_keep_string_jump:
7340+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7341+# ifdef _LIBC
7342+ printf ("/on_failure_keep_string_jump to %td", p + mcnt - start);
7343+# else
7344+ printf ("/on_failure_keep_string_jump to %ld",
7345+ (long int) (p + mcnt - start));
7346+# endif
7347+ break;
7348+
7349+ case dummy_failure_jump:
7350+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7351+# ifdef _LIBC
7352+ printf ("/dummy_failure_jump to %td", p + mcnt - start);
7353+# else
7354+ printf ("/dummy_failure_jump to %ld", (long int) (p + mcnt - start));
7355+# endif
7356+ break;
7357+
7358+ case push_dummy_failure:
7359+ printf ("/push_dummy_failure");
7360+ break;
7361+
7362+ case maybe_pop_jump:
7363+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7364+# ifdef _LIBC
7365+ printf ("/maybe_pop_jump to %td", p + mcnt - start);
7366+# else
7367+ printf ("/maybe_pop_jump to %ld", (long int) (p + mcnt - start));
7368+# endif
7369+ break;
7370+
7371+ case pop_failure_jump:
7372+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7373+# ifdef _LIBC
7374+ printf ("/pop_failure_jump to %td", p + mcnt - start);
7375+# else
7376+ printf ("/pop_failure_jump to %ld", (long int) (p + mcnt - start));
7377+# endif
7378+ break;
7379+
7380+ case jump_past_alt:
7381+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7382+# ifdef _LIBC
7383+ printf ("/jump_past_alt to %td", p + mcnt - start);
7384+# else
7385+ printf ("/jump_past_alt to %ld", (long int) (p + mcnt - start));
7386+# endif
7387+ break;
7388+
7389+ case jump:
7390+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7391+# ifdef _LIBC
7392+ printf ("/jump to %td", p + mcnt - start);
7393+# else
7394+ printf ("/jump to %ld", (long int) (p + mcnt - start));
7395+# endif
7396+ break;
7397+
7398+ case succeed_n:
7399+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7400+ p1 = p + mcnt;
7401+ PREFIX(extract_number_and_incr) (&mcnt2, &p);
7402+# ifdef _LIBC
7403+ printf ("/succeed_n to %td, %d times", p1 - start, mcnt2);
7404+# else
7405+ printf ("/succeed_n to %ld, %d times",
7406+ (long int) (p1 - start), mcnt2);
7407+# endif
7408+ break;
7409+
7410+ case jump_n:
7411+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7412+ p1 = p + mcnt;
7413+ PREFIX(extract_number_and_incr) (&mcnt2, &p);
7414+ printf ("/jump_n to %d, %d times", p1 - start, mcnt2);
7415+ break;
7416+
7417+ case set_number_at:
7418+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7419+ p1 = p + mcnt;
7420+ PREFIX(extract_number_and_incr) (&mcnt2, &p);
7421+# ifdef _LIBC
7422+ printf ("/set_number_at location %td to %d", p1 - start, mcnt2);
7423+# else
7424+ printf ("/set_number_at location %ld to %d",
7425+ (long int) (p1 - start), mcnt2);
7426+# endif
7427+ break;
7428+
7429+ case wordbound:
7430+ printf ("/wordbound");
7431+ break;
7432+
7433+ case notwordbound:
7434+ printf ("/notwordbound");
7435+ break;
7436+
7437+ case wordbeg:
7438+ printf ("/wordbeg");
7439+ break;
7440+
7441+ case wordend:
7442+ printf ("/wordend");
7443+ break;
7444+
7445+# ifdef emacs
7446+ case before_dot:
7447+ printf ("/before_dot");
7448+ break;
7449+
7450+ case at_dot:
7451+ printf ("/at_dot");
7452+ break;
7453+
7454+ case after_dot:
7455+ printf ("/after_dot");
7456+ break;
7457+
7458+ case syntaxspec:
7459+ printf ("/syntaxspec");
7460+ mcnt = *p++;
7461+ printf ("/%d", mcnt);
7462+ break;
7463+
7464+ case notsyntaxspec:
7465+ printf ("/notsyntaxspec");
7466+ mcnt = *p++;
7467+ printf ("/%d", mcnt);
7468+ break;
7469+# endif /* emacs */
7470+
7471+ case wordchar:
7472+ printf ("/wordchar");
7473+ break;
7474+
7475+ case notwordchar:
7476+ printf ("/notwordchar");
7477+ break;
7478+
7479+ case begbuf:
7480+ printf ("/begbuf");
7481+ break;
7482+
7483+ case endbuf:
7484+ printf ("/endbuf");
7485+ break;
7486+
7487+ default:
7488+ printf ("?%ld", (long int) *(p-1));
7489+ }
7490+
7491+ putchar ('\n');
7492+ }
7493+
7494+# ifdef _LIBC
7495+ printf ("%td:\tend of pattern.\n", p - start);
7496+# else
7497+ printf ("%ld:\tend of pattern.\n", (long int) (p - start));
7498+# endif
7499+}
7500+
7501+
7502+void
7503+PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp)
7504+{
7505+ UCHAR_T *buffer = (UCHAR_T*) bufp->buffer;
7506+
7507+ PREFIX(print_partial_compiled_pattern) (buffer, buffer
7508+ + bufp->used / sizeof(UCHAR_T));
7509+ printf ("%ld bytes used/%ld bytes allocated.\n",
7510+ bufp->used, bufp->allocated);
7511+
7512+ if (bufp->fastmap_accurate && bufp->fastmap)
7513+ {
7514+ printf ("fastmap: ");
7515+ print_fastmap (bufp->fastmap);
7516+ }
7517+
7518+# ifdef _LIBC
7519+ printf ("re_nsub: %Zd\t", bufp->re_nsub);
7520+# else
7521+ printf ("re_nsub: %ld\t", (long int) bufp->re_nsub);
7522+# endif
7523+ printf ("regs_alloc: %d\t", bufp->regs_allocated);
7524+ printf ("can_be_null: %d\t", bufp->can_be_null);
7525+ printf ("newline_anchor: %d\n", bufp->newline_anchor);
7526+ printf ("no_sub: %d\t", bufp->no_sub);
7527+ printf ("not_bol: %d\t", bufp->not_bol);
7528+ printf ("not_eol: %d\t", bufp->not_eol);
7529+ printf ("syntax: %lx\n", bufp->syntax);
7530+ /* Perhaps we should print the translate table? */
7531+}
7532+
7533+
7534+void
7535+PREFIX(print_double_string) (const CHAR_T *where, const CHAR_T *string1,
7536+ int size1, const CHAR_T *string2, int size2)
7537+{
7538+ int this_char;
7539+
7540+ if (where == NULL)
7541+ printf ("(null)");
7542+ else
7543+ {
7544+ int cnt;
7545+
7546+ if (FIRST_STRING_P (where))
7547+ {
7548+ for (this_char = where - string1; this_char < size1; this_char++)
7549+ PUT_CHAR (string1[this_char]);
7550+
7551+ where = string2;
7552+ }
7553+
7554+ cnt = 0;
7555+ for (this_char = where - string2; this_char < size2; this_char++)
7556+ {
7557+ PUT_CHAR (string2[this_char]);
7558+ if (++cnt > 100)
7559+ {
7560+ fputs ("...", stdout);
7561+ break;
7562+ }
7563+ }
7564+ }
7565+}
7566+
7567+# ifndef DEFINED_ONCE
7568+void
7569+printchar (int c)
7570+{
7571+ putc (c, stderr);
7572+}
7573+# endif
7574+
7575+# else /* not DEBUG */
7576+
7577+# ifndef DEFINED_ONCE
7578+# undef assert
7579+# define assert(e)
7580+
7581+# define DEBUG_STATEMENT(e)
7582+# define DEBUG_PRINT1(x)
7583+# define DEBUG_PRINT2(x1, x2)
7584+# define DEBUG_PRINT3(x1, x2, x3)
7585+# define DEBUG_PRINT4(x1, x2, x3, x4)
7586+# endif /* not DEFINED_ONCE */
7587+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
7588+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
7589+
7590+# endif /* not DEBUG */
7591+
7592+
7593+
7594+# ifdef WCHAR
7595+/* This convert a multibyte string to a wide character string.
7596+ And write their correspondances to offset_buffer(see below)
7597+ and write whether each wchar_t is binary data to is_binary.
7598+ This assume invalid multibyte sequences as binary data.
7599+ We assume offset_buffer and is_binary is already allocated
7600+ enough space. */
7601+
7602+static size_t convert_mbs_to_wcs (CHAR_T *dest, const unsigned char* src,
7603+ size_t len, int *offset_buffer,
7604+ char *is_binary);
7605+static size_t
7606+convert_mbs_to_wcs (CHAR_T *dest, const unsigned char*src, size_t len,
7607+ int *offset_buffer, char *is_binary)
7608+ /* It hold correspondances between src(char string) and
7609+ dest(wchar_t string) for optimization.
7610+ e.g. src = "xxxyzz"
7611+ dest = {'X', 'Y', 'Z'}
7612+ (each "xxx", "y" and "zz" represent one multibyte character
7613+ corresponding to 'X', 'Y' and 'Z'.)
7614+ offset_buffer = {0, 0+3("xxx"), 0+3+1("y"), 0+3+1+2("zz")}
7615+ = {0, 3, 4, 6}
7616+ */
7617+{
7618+ wchar_t *pdest = dest;
7619+ const unsigned char *psrc = src;
7620+ size_t wc_count = 0;
7621+
7622+ mbstate_t mbs;
7623+ int i, consumed;
7624+ size_t mb_remain = len;
7625+ size_t mb_count = 0;
7626+
7627+ /* Initialize the conversion state. */
7628+ memset (&mbs, 0, sizeof (mbstate_t));
7629+
7630+ offset_buffer[0] = 0;
7631+ for( ; mb_remain > 0 ; ++wc_count, ++pdest, mb_remain -= consumed,
7632+ psrc += consumed)
7633+ {
7634+#ifdef _LIBC
7635+ consumed = __mbrtowc (pdest, psrc, mb_remain, &mbs);
7636+#else
7637+ consumed = mbrtowc (pdest, psrc, mb_remain, &mbs);
7638+#endif
7639+
7640+ if (consumed <= 0)
7641+ /* failed to convert. maybe src contains binary data.
7642+ So we consume 1 byte manualy. */
7643+ {
7644+ *pdest = *psrc;
7645+ consumed = 1;
7646+ is_binary[wc_count] = TRUE;
7647+ }
7648+ else
7649+ is_binary[wc_count] = FALSE;
7650+ /* In sjis encoding, we use yen sign as escape character in
7651+ place of reverse solidus. So we convert 0x5c(yen sign in
7652+ sjis) to not 0xa5(yen sign in UCS2) but 0x5c(reverse
7653+ solidus in UCS2). */
7654+ if (consumed == 1 && (int) *psrc == 0x5c && (int) *pdest == 0xa5)
7655+ *pdest = (wchar_t) *psrc;
7656+
7657+ offset_buffer[wc_count + 1] = mb_count += consumed;
7658+ }
7659+
7660+ /* Fill remain of the buffer with sentinel. */
7661+ for (i = wc_count + 1 ; i <= len ; i++)
7662+ offset_buffer[i] = mb_count + 1;
7663+
7664+ return wc_count;
7665+}
7666+
7667+# endif /* WCHAR */
7668+
7669+#else /* not INSIDE_RECURSION */
7670+
7671+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
7672+ also be assigned to arbitrarily: each pattern buffer stores its own
7673+ syntax, so it can be changed between regex compilations. */
7674+/* This has no initializer because initialized variables in Emacs
7675+ become read-only after dumping. */
7676+reg_syntax_t re_syntax_options;
7677+
7678+
7679+/* Specify the precise syntax of regexps for compilation. This provides
7680+ for compatibility for various utilities which historically have
7681+ different, incompatible syntaxes.
7682+
7683+ The argument SYNTAX is a bit mask comprised of the various bits
7684+ defined in regex.h. We return the old syntax. */
7685+
7686+reg_syntax_t
7687+re_set_syntax (reg_syntax_t syntax)
7688+{
7689+ reg_syntax_t ret = re_syntax_options;
7690+
7691+ re_syntax_options = syntax;
7692+# ifdef DEBUG
7693+ if (syntax & RE_DEBUG)
7694+ debug = 1;
7695+ else if (debug) /* was on but now is not */
7696+ debug = 0;
7697+# endif /* DEBUG */
7698+ return ret;
7699+}
7700+# ifdef _LIBC
7701+weak_alias (__re_set_syntax, re_set_syntax)
7702+# endif
7703+
7704+/* This table gives an error message for each of the error codes listed
7705+ in regex.h. Obviously the order here has to be same as there.
7706+ POSIX doesn't require that we do anything for REG_NOERROR,
7707+ but why not be nice? */
7708+
7709+static const char *re_error_msgid[] =
7710+ {
7711+ gettext_noop ("Success"), /* REG_NOERROR */
7712+ gettext_noop ("No match"), /* REG_NOMATCH */
7713+ gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
7714+ gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
7715+ gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
7716+ gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
7717+ gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
7718+ gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */
7719+ gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
7720+ gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
7721+ gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
7722+ gettext_noop ("Invalid range end"), /* REG_ERANGE */
7723+ gettext_noop ("Memory exhausted"), /* REG_ESPACE */
7724+ gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
7725+ gettext_noop ("Premature end of regular expression"), /* REG_EEND */
7726+ gettext_noop ("Regular expression too big"), /* REG_ESIZE */
7727+ gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
7728+ };
7729+
7730+#endif /* INSIDE_RECURSION */
7731+
7732+#ifndef DEFINED_ONCE
7733+/* Avoiding alloca during matching, to placate r_alloc. */
7734+
7735+/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
7736+ searching and matching functions should not call alloca. On some
7737+ systems, alloca is implemented in terms of malloc, and if we're
7738+ using the relocating allocator routines, then malloc could cause a
7739+ relocation, which might (if the strings being searched are in the
7740+ ralloc heap) shift the data out from underneath the regexp
7741+ routines.
7742+
7743+ Here's another reason to avoid allocation: Emacs
7744+ processes input from X in a signal handler; processing X input may
7745+ call malloc; if input arrives while a matching routine is calling
7746+ malloc, then we're scrod. But Emacs can't just block input while
7747+ calling matching routines; then we don't notice interrupts when
7748+ they come in. So, Emacs blocks input around all regexp calls
7749+ except the matching calls, which it leaves unprotected, in the
7750+ faith that they will not malloc. */
7751+
7752+/* Normally, this is fine. */
7753+# define MATCH_MAY_ALLOCATE
7754+
7755+/* When using GNU C, we are not REALLY using the C alloca, no matter
7756+ what config.h may say. So don't take precautions for it. */
7757+# ifdef __GNUC__
7758+# undef C_ALLOCA
7759+# endif
7760+
7761+/* The match routines may not allocate if (1) they would do it with malloc
7762+ and (2) it's not safe for them to use malloc.
7763+ Note that if REL_ALLOC is defined, matching would not use malloc for the
7764+ failure stack, but we would still use it for the register vectors;
7765+ so REL_ALLOC should not affect this. */
7766+# if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs
7767+# undef MATCH_MAY_ALLOCATE
7768+# endif
7769+#endif /* not DEFINED_ONCE */
7770+
7771+#ifdef INSIDE_RECURSION
7772+/* Failure stack declarations and macros; both re_compile_fastmap and
7773+ re_match_2 use a failure stack. These have to be macros because of
7774+ REGEX_ALLOCATE_STACK. */
7775+
7776+
7777+/* Number of failure points for which to initially allocate space
7778+ when matching. If this number is exceeded, we allocate more
7779+ space, so it is not a hard limit. */
7780+# ifndef INIT_FAILURE_ALLOC
7781+# define INIT_FAILURE_ALLOC 5
7782+# endif
7783+
7784+/* Roughly the maximum number of failure points on the stack. Would be
7785+ exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
7786+ This is a variable only so users of regex can assign to it; we never
7787+ change it ourselves. */
7788+
7789+
7790+# ifndef DEFINED_ONCE
7791+
7792+# ifdef INT_IS_16BIT
7793+# define RE_M_F_TYPE long int
7794+# else
7795+# define RE_M_F_TYPE int
7796+# endif /* INT_IS_16BIT */
7797+
7798+# ifdef MATCH_MAY_ALLOCATE
7799+/* 4400 was enough to cause a crash on Alpha OSF/1,
7800+ whose default stack limit is 2mb. */
7801+# define RE_M_F_DEFAULT 4000
7802+# else
7803+# define RE_M_F_DEFAULT 2000
7804+# endif /* MATCH_MAY_ALLOCATE */
7805+
7806+# include <shlib-compat.h>
7807+
7808+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
7809+link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
7810+RE_M_F_TYPE re_max_failures = RE_M_F_DEFAULT;
7811+# else
7812+RE_M_F_TYPE re_max_failures attribute_hidden = RE_M_F_DEFAULT;
7813+# endif /* SHLIB_COMPAT */
7814+
7815+# undef RE_M_F_TYPE
7816+# undef RE_M_F_DEFAULT
7817+
7818+# endif /* DEFINED_ONCE */
7819+
7820+# ifdef INT_IS_16BIT
7821+
7822+union PREFIX(fail_stack_elt)
7823+{
7824+ UCHAR_T *pointer;
7825+ long int integer;
7826+};
7827+
7828+typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
7829+
7830+typedef struct
7831+{
7832+ PREFIX(fail_stack_elt_t) *stack;
7833+ unsigned long int size;
7834+ unsigned long int avail; /* Offset of next open position. */
7835+} PREFIX(fail_stack_type);
7836+
7837+# else /* not INT_IS_16BIT */
7838+
7839+union PREFIX(fail_stack_elt)
7840+{
7841+ UCHAR_T *pointer;
7842+ int integer;
7843+};
7844+
7845+typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
7846+
7847+typedef struct
7848+{
7849+ PREFIX(fail_stack_elt_t) *stack;
7850+ unsigned size;
7851+ unsigned avail; /* Offset of next open position. */
7852+} PREFIX(fail_stack_type);
7853+
7854+# endif /* INT_IS_16BIT */
7855+
7856+# ifndef DEFINED_ONCE
7857+# define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
7858+# define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
7859+# define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
7860+# endif
7861+
7862+
7863+/* Define macros to initialize and free the failure stack.
7864+ Do `return -2' if the alloc fails. */
7865+
7866+# ifdef MATCH_MAY_ALLOCATE
7867+# define INIT_FAIL_STACK() \
7868+ do { \
7869+ fail_stack.stack = (PREFIX(fail_stack_elt_t) *) \
7870+ REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (PREFIX(fail_stack_elt_t))); \
7871+ \
7872+ if (fail_stack.stack == NULL) \
7873+ return -2; \
7874+ \
7875+ fail_stack.size = INIT_FAILURE_ALLOC; \
7876+ fail_stack.avail = 0; \
7877+ } while (0)
7878+
7879+# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack)
7880+# else
7881+# define INIT_FAIL_STACK() \
7882+ do { \
7883+ fail_stack.avail = 0; \
7884+ } while (0)
7885+
7886+# define RESET_FAIL_STACK()
7887+# endif
7888+
7889+
7890+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
7891+
7892+ Return 1 if succeeds, and 0 if either ran out of memory
7893+ allocating space for it or it was already too large.
7894+
7895+ REGEX_REALLOCATE_STACK requires `destination' be declared. */
7896+
7897+# define DOUBLE_FAIL_STACK(fail_stack) \
7898+ ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \
7899+ ? 0 \
7900+ : ((fail_stack).stack = (PREFIX(fail_stack_elt_t) *) \
7901+ REGEX_REALLOCATE_STACK ((fail_stack).stack, \
7902+ (fail_stack).size * sizeof (PREFIX(fail_stack_elt_t)), \
7903+ ((fail_stack).size << 1) * sizeof (PREFIX(fail_stack_elt_t))),\
7904+ \
7905+ (fail_stack).stack == NULL \
7906+ ? 0 \
7907+ : ((fail_stack).size <<= 1, \
7908+ 1)))
7909+
7910+
7911+/* Push pointer POINTER on FAIL_STACK.
7912+ Return 1 if was able to do so and 0 if ran out of memory allocating
7913+ space to do so. */
7914+# define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \
7915+ ((FAIL_STACK_FULL () \
7916+ && !DOUBLE_FAIL_STACK (FAIL_STACK)) \
7917+ ? 0 \
7918+ : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \
7919+ 1))
7920+
7921+/* Push a pointer value onto the failure stack.
7922+ Assumes the variable `fail_stack'. Probably should only
7923+ be called from within `PUSH_FAILURE_POINT'. */
7924+# define PUSH_FAILURE_POINTER(item) \
7925+ fail_stack.stack[fail_stack.avail++].pointer = (UCHAR_T *) (item)
7926+
7927+/* This pushes an integer-valued item onto the failure stack.
7928+ Assumes the variable `fail_stack'. Probably should only
7929+ be called from within `PUSH_FAILURE_POINT'. */
7930+# define PUSH_FAILURE_INT(item) \
7931+ fail_stack.stack[fail_stack.avail++].integer = (item)
7932+
7933+/* Push a fail_stack_elt_t value onto the failure stack.
7934+ Assumes the variable `fail_stack'. Probably should only
7935+ be called from within `PUSH_FAILURE_POINT'. */
7936+# define PUSH_FAILURE_ELT(item) \
7937+ fail_stack.stack[fail_stack.avail++] = (item)
7938+
7939+/* These three POP... operations complement the three PUSH... operations.
7940+ All assume that `fail_stack' is nonempty. */
7941+# define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
7942+# define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
7943+# define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
7944+
7945+/* Used to omit pushing failure point id's when we're not debugging. */
7946+# ifdef DEBUG
7947+# define DEBUG_PUSH PUSH_FAILURE_INT
7948+# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
7949+# else
7950+# define DEBUG_PUSH(item)
7951+# define DEBUG_POP(item_addr)
7952+# endif
7953+
7954+
7955+/* Push the information about the state we will need
7956+ if we ever fail back to it.
7957+
7958+ Requires variables fail_stack, regstart, regend, reg_info, and
7959+ num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination'
7960+ be declared.
7961+
7962+ Does `return FAILURE_CODE' if runs out of memory. */
7963+
7964+# define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
7965+ do { \
7966+ char *destination; \
7967+ /* Must be int, so when we don't save any registers, the arithmetic \
7968+ of 0 + -1 isn't done as unsigned. */ \
7969+ /* Can't be int, since there is not a shred of a guarantee that int \
7970+ is wide enough to hold a value of something to which pointer can \
7971+ be assigned */ \
7972+ active_reg_t this_reg; \
7973+ \
7974+ DEBUG_STATEMENT (failure_id++); \
7975+ DEBUG_STATEMENT (nfailure_points_pushed++); \
7976+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
7977+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
7978+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
7979+ \
7980+ DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \
7981+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
7982+ \
7983+ /* Ensure we have enough space allocated for what we will push. */ \
7984+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
7985+ { \
7986+ if (!DOUBLE_FAIL_STACK (fail_stack)) \
7987+ return failure_code; \
7988+ \
7989+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
7990+ (fail_stack).size); \
7991+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
7992+ } \
7993+ \
7994+ /* Push the info, starting with the registers. */ \
7995+ DEBUG_PRINT1 ("\n"); \
7996+ \
7997+ if (1) \
7998+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
7999+ this_reg++) \
8000+ { \
8001+ DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \
8002+ DEBUG_STATEMENT (num_regs_pushed++); \
8003+ \
8004+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
8005+ PUSH_FAILURE_POINTER (regstart[this_reg]); \
8006+ \
8007+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
8008+ PUSH_FAILURE_POINTER (regend[this_reg]); \
8009+ \
8010+ DEBUG_PRINT2 (" info: %p\n ", \
8011+ reg_info[this_reg].word.pointer); \
8012+ DEBUG_PRINT2 (" match_null=%d", \
8013+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
8014+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
8015+ DEBUG_PRINT2 (" matched_something=%d", \
8016+ MATCHED_SOMETHING (reg_info[this_reg])); \
8017+ DEBUG_PRINT2 (" ever_matched=%d", \
8018+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
8019+ DEBUG_PRINT1 ("\n"); \
8020+ PUSH_FAILURE_ELT (reg_info[this_reg].word); \
8021+ } \
8022+ \
8023+ DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\
8024+ PUSH_FAILURE_INT (lowest_active_reg); \
8025+ \
8026+ DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\
8027+ PUSH_FAILURE_INT (highest_active_reg); \
8028+ \
8029+ DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \
8030+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
8031+ PUSH_FAILURE_POINTER (pattern_place); \
8032+ \
8033+ DEBUG_PRINT2 (" Pushing string %p: `", string_place); \
8034+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
8035+ size2); \
8036+ DEBUG_PRINT1 ("'\n"); \
8037+ PUSH_FAILURE_POINTER (string_place); \
8038+ \
8039+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
8040+ DEBUG_PUSH (failure_id); \
8041+ } while (0)
8042+
8043+# ifndef DEFINED_ONCE
8044+/* This is the number of items that are pushed and popped on the stack
8045+ for each register. */
8046+# define NUM_REG_ITEMS 3
8047+
8048+/* Individual items aside from the registers. */
8049+# ifdef DEBUG
8050+# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
8051+# else
8052+# define NUM_NONREG_ITEMS 4
8053+# endif
8054+
8055+/* We push at most this many items on the stack. */
8056+/* We used to use (num_regs - 1), which is the number of registers
8057+ this regexp will save; but that was changed to 5
8058+ to avoid stack overflow for a regexp with lots of parens. */
8059+# define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
8060+
8061+/* We actually push this many items. */
8062+# define NUM_FAILURE_ITEMS \
8063+ (((0 \
8064+ ? 0 : highest_active_reg - lowest_active_reg + 1) \
8065+ * NUM_REG_ITEMS) \
8066+ + NUM_NONREG_ITEMS)
8067+
8068+/* How many items can still be added to the stack without overflowing it. */
8069+# define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
8070+# endif /* not DEFINED_ONCE */
8071+
8072+
8073+/* Pops what PUSH_FAIL_STACK pushes.
8074+
8075+ We restore into the parameters, all of which should be lvalues:
8076+ STR -- the saved data position.
8077+ PAT -- the saved pattern position.
8078+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
8079+ REGSTART, REGEND -- arrays of string positions.
8080+ REG_INFO -- array of information about each subexpression.
8081+
8082+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
8083+ `pend', `string1', `size1', `string2', and `size2'. */
8084+# define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
8085+{ \
8086+ DEBUG_STATEMENT (unsigned failure_id;) \
8087+ active_reg_t this_reg; \
8088+ const UCHAR_T *string_temp; \
8089+ \
8090+ assert (!FAIL_STACK_EMPTY ()); \
8091+ \
8092+ /* Remove failure points and point to how many regs pushed. */ \
8093+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
8094+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
8095+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
8096+ \
8097+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
8098+ \
8099+ DEBUG_POP (&failure_id); \
8100+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
8101+ \
8102+ /* If the saved string location is NULL, it came from an \
8103+ on_failure_keep_string_jump opcode, and we want to throw away the \
8104+ saved NULL, thus retaining our current position in the string. */ \
8105+ string_temp = POP_FAILURE_POINTER (); \
8106+ if (string_temp != NULL) \
8107+ str = (const CHAR_T *) string_temp; \
8108+ \
8109+ DEBUG_PRINT2 (" Popping string %p: `", str); \
8110+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
8111+ DEBUG_PRINT1 ("'\n"); \
8112+ \
8113+ pat = (UCHAR_T *) POP_FAILURE_POINTER (); \
8114+ DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \
8115+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
8116+ \
8117+ /* Restore register info. */ \
8118+ high_reg = (active_reg_t) POP_FAILURE_INT (); \
8119+ DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \
8120+ \
8121+ low_reg = (active_reg_t) POP_FAILURE_INT (); \
8122+ DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \
8123+ \
8124+ if (1) \
8125+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
8126+ { \
8127+ DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \
8128+ \
8129+ reg_info[this_reg].word = POP_FAILURE_ELT (); \
8130+ DEBUG_PRINT2 (" info: %p\n", \
8131+ reg_info[this_reg].word.pointer); \
8132+ \
8133+ regend[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER (); \
8134+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
8135+ \
8136+ regstart[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER (); \
8137+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
8138+ } \
8139+ else \
8140+ { \
8141+ for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
8142+ { \
8143+ reg_info[this_reg].word.integer = 0; \
8144+ regend[this_reg] = 0; \
8145+ regstart[this_reg] = 0; \
8146+ } \
8147+ highest_active_reg = high_reg; \
8148+ } \
8149+ \
8150+ set_regs_matched_done = 0; \
8151+ DEBUG_STATEMENT (nfailure_points_popped++); \
8152+} /* POP_FAILURE_POINT */
8153+
8154+/* Structure for per-register (a.k.a. per-group) information.
8155+ Other register information, such as the
8156+ starting and ending positions (which are addresses), and the list of
8157+ inner groups (which is a bits list) are maintained in separate
8158+ variables.
8159+
8160+ We are making a (strictly speaking) nonportable assumption here: that
8161+ the compiler will pack our bit fields into something that fits into
8162+ the type of `word', i.e., is something that fits into one item on the
8163+ failure stack. */
8164+
8165+
8166+/* Declarations and macros for re_match_2. */
8167+
8168+typedef union
8169+{
8170+ PREFIX(fail_stack_elt_t) word;
8171+ struct
8172+ {
8173+ /* This field is one if this group can match the empty string,
8174+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
8175+# define MATCH_NULL_UNSET_VALUE 3
8176+ unsigned match_null_string_p : 2;
8177+ unsigned is_active : 1;
8178+ unsigned matched_something : 1;
8179+ unsigned ever_matched_something : 1;
8180+ } bits;
8181+} PREFIX(register_info_type);
8182+
8183+# ifndef DEFINED_ONCE
8184+# define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
8185+# define IS_ACTIVE(R) ((R).bits.is_active)
8186+# define MATCHED_SOMETHING(R) ((R).bits.matched_something)
8187+# define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
8188+
8189+
8190+/* Call this when have matched a real character; it sets `matched' flags
8191+ for the subexpressions which we are currently inside. Also records
8192+ that those subexprs have matched. */
8193+# define SET_REGS_MATCHED() \
8194+ do \
8195+ { \
8196+ if (!set_regs_matched_done) \
8197+ { \
8198+ active_reg_t r; \
8199+ set_regs_matched_done = 1; \
8200+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
8201+ { \
8202+ MATCHED_SOMETHING (reg_info[r]) \
8203+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
8204+ = 1; \
8205+ } \
8206+ } \
8207+ } \
8208+ while (0)
8209+# endif /* not DEFINED_ONCE */
8210+
8211+/* Registers are set to a sentinel when they haven't yet matched. */
8212+static CHAR_T PREFIX(reg_unset_dummy);
8213+# define REG_UNSET_VALUE (&PREFIX(reg_unset_dummy))
8214+# define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
8215+
8216+/* Subroutine declarations and macros for regex_compile. */
8217+static void PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg);
8218+static void PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc,
8219+ int arg1, int arg2);
8220+static void PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc,
8221+ int arg, UCHAR_T *end);
8222+static void PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc,
8223+ int arg1, int arg2, UCHAR_T *end);
8224+static boolean PREFIX(at_begline_loc_p) (const CHAR_T *pattern,
8225+ const CHAR_T *p,
8226+ reg_syntax_t syntax);
8227+static boolean PREFIX(at_endline_loc_p) (const CHAR_T *p,
8228+ const CHAR_T *pend,
8229+ reg_syntax_t syntax);
8230+# ifdef WCHAR
8231+static reg_errcode_t wcs_compile_range (CHAR_T range_start,
8232+ const CHAR_T **p_ptr,
8233+ const CHAR_T *pend,
8234+ char *translate,
8235+ reg_syntax_t syntax,
8236+ UCHAR_T *b,
8237+ CHAR_T *char_set);
8238+static void insert_space (int num, CHAR_T *loc, CHAR_T *end);
8239+# else /* BYTE */
8240+static reg_errcode_t byte_compile_range (unsigned int range_start,
8241+ const char **p_ptr,
8242+ const char *pend,
8243+ RE_TRANSLATE_TYPE translate,
8244+ reg_syntax_t syntax,
8245+ unsigned char *b);
8246+# endif /* WCHAR */
8247+
8248+/* Fetch the next character in the uncompiled pattern---translating it
8249+ if necessary. Also cast from a signed character in the constant
8250+ string passed to us by the user to an unsigned char that we can use
8251+ as an array index (in, e.g., `translate'). */
8252+/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
8253+ because it is impossible to allocate 4GB array for some encodings
8254+ which have 4 byte character_set like UCS4. */
8255+# ifndef PATFETCH
8256+# ifdef WCHAR
8257+# define PATFETCH(c) \
8258+ do {if (p == pend) return REG_EEND; \
8259+ c = (UCHAR_T) *p++; \
8260+ if (translate && (c <= 0xff)) c = (UCHAR_T) translate[c]; \
8261+ } while (0)
8262+# else /* BYTE */
8263+# define PATFETCH(c) \
8264+ do {if (p == pend) return REG_EEND; \
8265+ c = (unsigned char) *p++; \
8266+ if (translate) c = (unsigned char) translate[c]; \
8267+ } while (0)
8268+# endif /* WCHAR */
8269+# endif
8270+
8271+/* Fetch the next character in the uncompiled pattern, with no
8272+ translation. */
8273+# define PATFETCH_RAW(c) \
8274+ do {if (p == pend) return REG_EEND; \
8275+ c = (UCHAR_T) *p++; \
8276+ } while (0)
8277+
8278+/* Go backwards one character in the pattern. */
8279+# define PATUNFETCH p--
8280+
8281+
8282+/* If `translate' is non-null, return translate[D], else just D. We
8283+ cast the subscript to translate because some data is declared as
8284+ `char *', to avoid warnings when a string constant is passed. But
8285+ when we use a character as a subscript we must make it unsigned. */
8286+/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
8287+ because it is impossible to allocate 4GB array for some encodings
8288+ which have 4 byte character_set like UCS4. */
8289+
8290+# ifndef TRANSLATE
8291+# ifdef WCHAR
8292+# define TRANSLATE(d) \
8293+ ((translate && ((UCHAR_T) (d)) <= 0xff) \
8294+ ? (char) translate[(unsigned char) (d)] : (d))
8295+# else /* BYTE */
8296+# define TRANSLATE(d) \
8297+ (translate ? (char) translate[(unsigned char) (d)] : (char) (d))
8298+# endif /* WCHAR */
8299+# endif
8300+
8301+
8302+/* Macros for outputting the compiled pattern into `buffer'. */
8303+
8304+/* If the buffer isn't allocated when it comes in, use this. */
8305+# define INIT_BUF_SIZE (32 * sizeof(UCHAR_T))
8306+
8307+/* Make sure we have at least N more bytes of space in buffer. */
8308+# ifdef WCHAR
8309+# define GET_BUFFER_SPACE(n) \
8310+ while (((unsigned long)b - (unsigned long)COMPILED_BUFFER_VAR \
8311+ + (n)*sizeof(CHAR_T)) > bufp->allocated) \
8312+ EXTEND_BUFFER ()
8313+# else /* BYTE */
8314+# define GET_BUFFER_SPACE(n) \
8315+ while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \
8316+ EXTEND_BUFFER ()
8317+# endif /* WCHAR */
8318+
8319+/* Make sure we have one more byte of buffer space and then add C to it. */
8320+# define BUF_PUSH(c) \
8321+ do { \
8322+ GET_BUFFER_SPACE (1); \
8323+ *b++ = (UCHAR_T) (c); \
8324+ } while (0)
8325+
8326+
8327+/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
8328+# define BUF_PUSH_2(c1, c2) \
8329+ do { \
8330+ GET_BUFFER_SPACE (2); \
8331+ *b++ = (UCHAR_T) (c1); \
8332+ *b++ = (UCHAR_T) (c2); \
8333+ } while (0)
8334+
8335+
8336+/* As with BUF_PUSH_2, except for three bytes. */
8337+# define BUF_PUSH_3(c1, c2, c3) \
8338+ do { \
8339+ GET_BUFFER_SPACE (3); \
8340+ *b++ = (UCHAR_T) (c1); \
8341+ *b++ = (UCHAR_T) (c2); \
8342+ *b++ = (UCHAR_T) (c3); \
8343+ } while (0)
8344+
8345+/* Store a jump with opcode OP at LOC to location TO. We store a
8346+ relative address offset by the three bytes the jump itself occupies. */
8347+# define STORE_JUMP(op, loc, to) \
8348+ PREFIX(store_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)))
8349+
8350+/* Likewise, for a two-argument jump. */
8351+# define STORE_JUMP2(op, loc, to, arg) \
8352+ PREFIX(store_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), arg)
8353+
8354+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
8355+# define INSERT_JUMP(op, loc, to) \
8356+ PREFIX(insert_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), b)
8357+
8358+/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
8359+# define INSERT_JUMP2(op, loc, to, arg) \
8360+ PREFIX(insert_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)),\
8361+ arg, b)
8362+
8363+/* This is not an arbitrary limit: the arguments which represent offsets
8364+ into the pattern are two bytes long. So if 2^16 bytes turns out to
8365+ be too small, many things would have to change. */
8366+/* Any other compiler which, like MSC, has allocation limit below 2^16
8367+ bytes will have to use approach similar to what was done below for
8368+ MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up
8369+ reallocating to 0 bytes. Such thing is not going to work too well.
8370+ You have been warned!! */
8371+# ifndef DEFINED_ONCE
8372+# if defined _MSC_VER && !defined WIN32
8373+/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
8374+ The REALLOC define eliminates a flurry of conversion warnings,
8375+ but is not required. */
8376+# define MAX_BUF_SIZE 65500L
8377+# define REALLOC(p,s) realloc ((p), (size_t) (s))
8378+# else
8379+# define MAX_BUF_SIZE (1L << 16)
8380+# define REALLOC(p,s) realloc ((p), (s))
8381+# endif
8382+
8383+/* Extend the buffer by twice its current size via realloc and
8384+ reset the pointers that pointed into the old block to point to the
8385+ correct places in the new one. If extending the buffer results in it
8386+ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
8387+# ifndef __BOUNDED_POINTERS__
8388+# define __BOUNDED_POINTERS__ 0
8389+# endif
8390+# if __BOUNDED_POINTERS__
8391+# define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated)
8392+# define MOVE_BUFFER_POINTER(P) \
8393+ (__ptrlow (P) += incr, SET_HIGH_BOUND (P), __ptrvalue (P) += incr)
8394+# define ELSE_EXTEND_BUFFER_HIGH_BOUND \
8395+ else \
8396+ { \
8397+ SET_HIGH_BOUND (b); \
8398+ SET_HIGH_BOUND (begalt); \
8399+ if (fixup_alt_jump) \
8400+ SET_HIGH_BOUND (fixup_alt_jump); \
8401+ if (laststart) \
8402+ SET_HIGH_BOUND (laststart); \
8403+ if (pending_exact) \
8404+ SET_HIGH_BOUND (pending_exact); \
8405+ }
8406+# else
8407+# define MOVE_BUFFER_POINTER(P) (P) += incr
8408+# define ELSE_EXTEND_BUFFER_HIGH_BOUND
8409+# endif
8410+# endif /* not DEFINED_ONCE */
8411+
8412+# ifdef WCHAR
8413+# define EXTEND_BUFFER() \
8414+ do { \
8415+ UCHAR_T *old_buffer = COMPILED_BUFFER_VAR; \
8416+ int wchar_count; \
8417+ if (bufp->allocated + sizeof(UCHAR_T) > MAX_BUF_SIZE) \
8418+ return REG_ESIZE; \
8419+ bufp->allocated <<= 1; \
8420+ if (bufp->allocated > MAX_BUF_SIZE) \
8421+ bufp->allocated = MAX_BUF_SIZE; \
8422+ /* How many characters the new buffer can have? */ \
8423+ wchar_count = bufp->allocated / sizeof(UCHAR_T); \
8424+ if (wchar_count == 0) wchar_count = 1; \
8425+ /* Truncate the buffer to CHAR_T align. */ \
8426+ bufp->allocated = wchar_count * sizeof(UCHAR_T); \
8427+ RETALLOC (COMPILED_BUFFER_VAR, wchar_count, UCHAR_T); \
8428+ bufp->buffer = (char*)COMPILED_BUFFER_VAR; \
8429+ if (COMPILED_BUFFER_VAR == NULL) \
8430+ return REG_ESPACE; \
8431+ /* If the buffer moved, move all the pointers into it. */ \
8432+ if (old_buffer != COMPILED_BUFFER_VAR) \
8433+ { \
8434+ int incr = COMPILED_BUFFER_VAR - old_buffer; \
8435+ MOVE_BUFFER_POINTER (b); \
8436+ MOVE_BUFFER_POINTER (begalt); \
8437+ if (fixup_alt_jump) \
8438+ MOVE_BUFFER_POINTER (fixup_alt_jump); \
8439+ if (laststart) \
8440+ MOVE_BUFFER_POINTER (laststart); \
8441+ if (pending_exact) \
8442+ MOVE_BUFFER_POINTER (pending_exact); \
8443+ } \
8444+ ELSE_EXTEND_BUFFER_HIGH_BOUND \
8445+ } while (0)
8446+# else /* BYTE */
8447+# define EXTEND_BUFFER() \
8448+ do { \
8449+ UCHAR_T *old_buffer = COMPILED_BUFFER_VAR; \
8450+ if (bufp->allocated == MAX_BUF_SIZE) \
8451+ return REG_ESIZE; \
8452+ bufp->allocated <<= 1; \
8453+ if (bufp->allocated > MAX_BUF_SIZE) \
8454+ bufp->allocated = MAX_BUF_SIZE; \
8455+ bufp->buffer = (UCHAR_T *) REALLOC (COMPILED_BUFFER_VAR, \
8456+ bufp->allocated); \
8457+ if (COMPILED_BUFFER_VAR == NULL) \
8458+ return REG_ESPACE; \
8459+ /* If the buffer moved, move all the pointers into it. */ \
8460+ if (old_buffer != COMPILED_BUFFER_VAR) \
8461+ { \
8462+ int incr = COMPILED_BUFFER_VAR - old_buffer; \
8463+ MOVE_BUFFER_POINTER (b); \
8464+ MOVE_BUFFER_POINTER (begalt); \
8465+ if (fixup_alt_jump) \
8466+ MOVE_BUFFER_POINTER (fixup_alt_jump); \
8467+ if (laststart) \
8468+ MOVE_BUFFER_POINTER (laststart); \
8469+ if (pending_exact) \
8470+ MOVE_BUFFER_POINTER (pending_exact); \
8471+ } \
8472+ ELSE_EXTEND_BUFFER_HIGH_BOUND \
8473+ } while (0)
8474+# endif /* WCHAR */
8475+
8476+# ifndef DEFINED_ONCE
8477+/* Since we have one byte reserved for the register number argument to
8478+ {start,stop}_memory, the maximum number of groups we can report
8479+ things about is what fits in that byte. */
8480+# define MAX_REGNUM 255
8481+
8482+/* But patterns can have more than `MAX_REGNUM' registers. We just
8483+ ignore the excess. */
8484+typedef unsigned regnum_t;
8485+
8486+
8487+/* Macros for the compile stack. */
8488+
8489+/* Since offsets can go either forwards or backwards, this type needs to
8490+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
8491+/* int may be not enough when sizeof(int) == 2. */
8492+typedef long pattern_offset_t;
8493+
8494+typedef struct
8495+{
8496+ pattern_offset_t begalt_offset;
8497+ pattern_offset_t fixup_alt_jump;
8498+ pattern_offset_t inner_group_offset;
8499+ pattern_offset_t laststart_offset;
8500+ regnum_t regnum;
8501+} compile_stack_elt_t;
8502+
8503+
8504+typedef struct
8505+{
8506+ compile_stack_elt_t *stack;
8507+ unsigned size;
8508+ unsigned avail; /* Offset of next open position. */
8509+} compile_stack_type;
8510+
8511+
8512+# define INIT_COMPILE_STACK_SIZE 32
8513+
8514+# define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
8515+# define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
8516+
8517+/* The next available element. */
8518+# define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
8519+
8520+# endif /* not DEFINED_ONCE */
8521+
8522+/* Set the bit for character C in a list. */
8523+# ifndef DEFINED_ONCE
8524+# define SET_LIST_BIT(c) \
8525+ (b[((unsigned char) (c)) / BYTEWIDTH] \
8526+ |= 1 << (((unsigned char) c) % BYTEWIDTH))
8527+# endif /* DEFINED_ONCE */
8528+
8529+/* Get the next unsigned number in the uncompiled pattern. */
8530+# define GET_UNSIGNED_NUMBER(num) \
8531+ { \
8532+ while (p != pend) \
8533+ { \
8534+ PATFETCH (c); \
8535+ if (c < '0' || c > '9') \
8536+ break; \
8537+ if (num <= RE_DUP_MAX) \
8538+ { \
8539+ if (num < 0) \
8540+ num = 0; \
8541+ num = num * 10 + c - '0'; \
8542+ } \
8543+ } \
8544+ }
8545+
8546+# ifndef DEFINED_ONCE
8547+# if WIDE_CHAR_SUPPORT
8548+/* The GNU C library provides support for user-defined character classes
8549+ and the functions from ISO C amendement 1. */
8550+# ifdef CHARCLASS_NAME_MAX
8551+# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
8552+# else
8553+/* This shouldn't happen but some implementation might still have this
8554+ problem. Use a reasonable default value. */
8555+# define CHAR_CLASS_MAX_LENGTH 256
8556+# endif
8557+
8558+# ifdef _LIBC
8559+# define IS_CHAR_CLASS(string) __wctype (string)
8560+# else
8561+# define IS_CHAR_CLASS(string) wctype (string)
8562+# endif
8563+# else
8564+# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
8565+
8566+# define IS_CHAR_CLASS(string) \
8567+ (STREQ (string, "alpha") || STREQ (string, "upper") \
8568+ || STREQ (string, "lower") || STREQ (string, "digit") \
8569+ || STREQ (string, "alnum") || STREQ (string, "xdigit") \
8570+ || STREQ (string, "space") || STREQ (string, "print") \
8571+ || STREQ (string, "punct") || STREQ (string, "graph") \
8572+ || STREQ (string, "cntrl") || STREQ (string, "blank"))
8573+# endif
8574+# endif /* DEFINED_ONCE */
8575+
8576+# ifndef MATCH_MAY_ALLOCATE
8577+
8578+/* If we cannot allocate large objects within re_match_2_internal,
8579+ we make the fail stack and register vectors global.
8580+ The fail stack, we grow to the maximum size when a regexp
8581+ is compiled.
8582+ The register vectors, we adjust in size each time we
8583+ compile a regexp, according to the number of registers it needs. */
8584+
8585+static PREFIX(fail_stack_type) fail_stack;
8586+
8587+/* Size with which the following vectors are currently allocated.
8588+ That is so we can make them bigger as needed,
8589+ but never make them smaller. */
8590+# ifdef DEFINED_ONCE
8591+static int regs_allocated_size;
8592+
8593+static const char ** regstart, ** regend;
8594+static const char ** old_regstart, ** old_regend;
8595+static const char **best_regstart, **best_regend;
8596+static const char **reg_dummy;
8597+# endif /* DEFINED_ONCE */
8598+
8599+static PREFIX(register_info_type) *PREFIX(reg_info);
8600+static PREFIX(register_info_type) *PREFIX(reg_info_dummy);
8601+
8602+/* Make the register vectors big enough for NUM_REGS registers,
8603+ but don't make them smaller. */
8604+
8605+static void
8606+PREFIX(regex_grow_registers) (int num_regs)
8607+{
8608+ if (num_regs > regs_allocated_size)
8609+ {
8610+ RETALLOC_IF (regstart, num_regs, const char *);
8611+ RETALLOC_IF (regend, num_regs, const char *);
8612+ RETALLOC_IF (old_regstart, num_regs, const char *);
8613+ RETALLOC_IF (old_regend, num_regs, const char *);
8614+ RETALLOC_IF (best_regstart, num_regs, const char *);
8615+ RETALLOC_IF (best_regend, num_regs, const char *);
8616+ RETALLOC_IF (PREFIX(reg_info), num_regs, PREFIX(register_info_type));
8617+ RETALLOC_IF (reg_dummy, num_regs, const char *);
8618+ RETALLOC_IF (PREFIX(reg_info_dummy), num_regs, PREFIX(register_info_type));
8619+
8620+ regs_allocated_size = num_regs;
8621+ }
8622+}
8623+
8624+# endif /* not MATCH_MAY_ALLOCATE */
8625+
8626+# ifndef DEFINED_ONCE
8627+static boolean group_in_compile_stack (compile_stack_type compile_stack,
8628+ regnum_t regnum);
8629+# endif /* not DEFINED_ONCE */
8630+
8631+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
8632+ Returns one of error codes defined in `regex.h', or zero for success.
8633+
8634+ Assumes the `allocated' (and perhaps `buffer') and `translate'
8635+ fields are set in BUFP on entry.
8636+
8637+ If it succeeds, results are put in BUFP (if it returns an error, the
8638+ contents of BUFP are undefined):
8639+ `buffer' is the compiled pattern;
8640+ `syntax' is set to SYNTAX;
8641+ `used' is set to the length of the compiled pattern;
8642+ `fastmap_accurate' is zero;
8643+ `re_nsub' is the number of subexpressions in PATTERN;
8644+ `not_bol' and `not_eol' are zero;
8645+
8646+ The `fastmap' and `newline_anchor' fields are neither
8647+ examined nor set. */
8648+
8649+/* Return, freeing storage we allocated. */
8650+# ifdef WCHAR
8651+# define FREE_STACK_RETURN(value) \
8652+ return (free(pattern), free(mbs_offset), free(is_binary), free (compile_stack.stack), value)
8653+# else
8654+# define FREE_STACK_RETURN(value) \
8655+ return (free (compile_stack.stack), value)
8656+# endif /* WCHAR */
8657+
8658+static reg_errcode_t
8659+PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
8660+ size_t ARG_PREFIX(size), reg_syntax_t syntax,
8661+ struct re_pattern_buffer *bufp)
8662+{
8663+ /* We fetch characters from PATTERN here. Even though PATTERN is
8664+ `char *' (i.e., signed), we declare these variables as unsigned, so
8665+ they can be reliably used as array indices. */
8666+ register UCHAR_T c, c1;
8667+
8668+#ifdef WCHAR
8669+ /* A temporary space to keep wchar_t pattern and compiled pattern. */
8670+ CHAR_T *pattern, *COMPILED_BUFFER_VAR;
8671+ size_t size;
8672+ /* offset buffer for optimization. See convert_mbs_to_wc. */
8673+ int *mbs_offset = NULL;
8674+ /* It hold whether each wchar_t is binary data or not. */
8675+ char *is_binary = NULL;
8676+ /* A flag whether exactn is handling binary data or not. */
8677+ char is_exactn_bin = FALSE;
8678+#endif /* WCHAR */
8679+
8680+ /* A random temporary spot in PATTERN. */
8681+ const CHAR_T *p1;
8682+
8683+ /* Points to the end of the buffer, where we should append. */
8684+ register UCHAR_T *b;
8685+
8686+ /* Keeps track of unclosed groups. */
8687+ compile_stack_type compile_stack;
8688+
8689+ /* Points to the current (ending) position in the pattern. */
8690+#ifdef WCHAR
8691+ const CHAR_T *p;
8692+ const CHAR_T *pend;
8693+#else /* BYTE */
8694+ const CHAR_T *p = pattern;
8695+ const CHAR_T *pend = pattern + size;
8696+#endif /* WCHAR */
8697+
8698+ /* How to translate the characters in the pattern. */
8699+ RE_TRANSLATE_TYPE translate = bufp->translate;
8700+
8701+ /* Address of the count-byte of the most recently inserted `exactn'
8702+ command. This makes it possible to tell if a new exact-match
8703+ character can be added to that command or if the character requires
8704+ a new `exactn' command. */
8705+ UCHAR_T *pending_exact = 0;
8706+
8707+ /* Address of start of the most recently finished expression.
8708+ This tells, e.g., postfix * where to find the start of its
8709+ operand. Reset at the beginning of groups and alternatives. */
8710+ UCHAR_T *laststart = 0;
8711+
8712+ /* Address of beginning of regexp, or inside of last group. */
8713+ UCHAR_T *begalt;
8714+
8715+ /* Address of the place where a forward jump should go to the end of
8716+ the containing expression. Each alternative of an `or' -- except the
8717+ last -- ends with a forward jump of this sort. */
8718+ UCHAR_T *fixup_alt_jump = 0;
8719+
8720+ /* Counts open-groups as they are encountered. Remembered for the
8721+ matching close-group on the compile stack, so the same register
8722+ number is put in the stop_memory as the start_memory. */
8723+ regnum_t regnum = 0;
8724+
8725+#ifdef WCHAR
8726+ /* Initialize the wchar_t PATTERN and offset_buffer. */
8727+ p = pend = pattern = TALLOC(csize + 1, CHAR_T);
8728+ mbs_offset = TALLOC(csize + 1, int);
8729+ is_binary = TALLOC(csize + 1, char);
8730+ if (pattern == NULL || mbs_offset == NULL || is_binary == NULL)
8731+ {
8732+ free(pattern);
8733+ free(mbs_offset);
8734+ free(is_binary);
8735+ return REG_ESPACE;
8736+ }
8737+ pattern[csize] = L'\0'; /* sentinel */
8738+ size = convert_mbs_to_wcs(pattern, cpattern, csize, mbs_offset, is_binary);
8739+ pend = p + size;
8740+ if (size < 0)
8741+ {
8742+ free(pattern);
8743+ free(mbs_offset);
8744+ free(is_binary);
8745+ return REG_BADPAT;
8746+ }
8747+#endif
8748+
8749+#ifdef DEBUG
8750+ DEBUG_PRINT1 ("\nCompiling pattern: ");
8751+ if (debug)
8752+ {
8753+ unsigned debug_count;
8754+
8755+ for (debug_count = 0; debug_count < size; debug_count++)
8756+ PUT_CHAR (pattern[debug_count]);
8757+ putchar ('\n');
8758+ }
8759+#endif /* DEBUG */
8760+
8761+ /* Initialize the compile stack. */
8762+ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
8763+ if (compile_stack.stack == NULL)
8764+ {
8765+#ifdef WCHAR
8766+ free(pattern);
8767+ free(mbs_offset);
8768+ free(is_binary);
8769+#endif
8770+ return REG_ESPACE;
8771+ }
8772+
8773+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
8774+ compile_stack.avail = 0;
8775+
8776+ /* Initialize the pattern buffer. */
8777+ bufp->syntax = syntax;
8778+ bufp->fastmap_accurate = 0;
8779+ bufp->not_bol = bufp->not_eol = 0;
8780+
8781+ /* Set `used' to zero, so that if we return an error, the pattern
8782+ printer (for debugging) will think there's no pattern. We reset it
8783+ at the end. */
8784+ bufp->used = 0;
8785+
8786+ /* Always count groups, whether or not bufp->no_sub is set. */
8787+ bufp->re_nsub = 0;
8788+
8789+#if !defined emacs && !defined SYNTAX_TABLE
8790+ /* Initialize the syntax table. */
8791+ init_syntax_once ();
8792+#endif
8793+
8794+ if (bufp->allocated == 0)
8795+ {
8796+ if (bufp->buffer)
8797+ { /* If zero allocated, but buffer is non-null, try to realloc
8798+ enough space. This loses if buffer's address is bogus, but
8799+ that is the user's responsibility. */
8800+#ifdef WCHAR
8801+ /* Free bufp->buffer and allocate an array for wchar_t pattern
8802+ buffer. */
8803+ free(bufp->buffer);
8804+ COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE/sizeof(UCHAR_T),
8805+ UCHAR_T);
8806+#else
8807+ RETALLOC (COMPILED_BUFFER_VAR, INIT_BUF_SIZE, UCHAR_T);
8808+#endif /* WCHAR */
8809+ }
8810+ else
8811+ { /* Caller did not allocate a buffer. Do it for them. */
8812+ COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE / sizeof(UCHAR_T),
8813+ UCHAR_T);
8814+ }
8815+
8816+ if (!COMPILED_BUFFER_VAR) FREE_STACK_RETURN (REG_ESPACE);
8817+#ifdef WCHAR
8818+ bufp->buffer = (char*)COMPILED_BUFFER_VAR;
8819+#endif /* WCHAR */
8820+ bufp->allocated = INIT_BUF_SIZE;
8821+ }
8822+#ifdef WCHAR
8823+ else
8824+ COMPILED_BUFFER_VAR = (UCHAR_T*) bufp->buffer;
8825+#endif
8826+
8827+ begalt = b = COMPILED_BUFFER_VAR;
8828+
8829+ /* Loop through the uncompiled pattern until we're at the end. */
8830+ while (p != pend)
8831+ {
8832+ PATFETCH (c);
8833+
8834+ switch (c)
8835+ {
8836+ case '^':
8837+ {
8838+ if ( /* If at start of pattern, it's an operator. */
8839+ p == pattern + 1
8840+ /* If context independent, it's an operator. */
8841+ || syntax & RE_CONTEXT_INDEP_ANCHORS
8842+ /* Otherwise, depends on what's come before. */
8843+ || PREFIX(at_begline_loc_p) (pattern, p, syntax))
8844+ BUF_PUSH (begline);
8845+ else
8846+ goto normal_char;
8847+ }
8848+ break;
8849+
8850+
8851+ case '$':
8852+ {
8853+ if ( /* If at end of pattern, it's an operator. */
8854+ p == pend
8855+ /* If context independent, it's an operator. */
8856+ || syntax & RE_CONTEXT_INDEP_ANCHORS
8857+ /* Otherwise, depends on what's next. */
8858+ || PREFIX(at_endline_loc_p) (p, pend, syntax))
8859+ BUF_PUSH (endline);
8860+ else
8861+ goto normal_char;
8862+ }
8863+ break;
8864+
8865+
8866+ case '+':
8867+ case '?':
8868+ if ((syntax & RE_BK_PLUS_QM)
8869+ || (syntax & RE_LIMITED_OPS))
8870+ goto normal_char;
8871+ handle_plus:
8872+ case '*':
8873+ /* If there is no previous pattern... */
8874+ if (!laststart)
8875+ {
8876+ if (syntax & RE_CONTEXT_INVALID_OPS)
8877+ FREE_STACK_RETURN (REG_BADRPT);
8878+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
8879+ goto normal_char;
8880+ }
8881+
8882+ {
8883+ /* Are we optimizing this jump? */
8884+ boolean keep_string_p = false;
8885+
8886+ /* 1 means zero (many) matches is allowed. */
8887+ char zero_times_ok = 0, many_times_ok = 0;
8888+
8889+ /* If there is a sequence of repetition chars, collapse it
8890+ down to just one (the right one). We can't combine
8891+ interval operators with these because of, e.g., `a{2}*',
8892+ which should only match an even number of `a's. */
8893+
8894+ for (;;)
8895+ {
8896+ zero_times_ok |= c != '+';
8897+ many_times_ok |= c != '?';
8898+
8899+ if (p == pend)
8900+ break;
8901+
8902+ PATFETCH (c);
8903+
8904+ if (c == '*'
8905+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
8906+ ;
8907+
8908+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
8909+ {
8910+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
8911+
8912+ PATFETCH (c1);
8913+ if (!(c1 == '+' || c1 == '?'))
8914+ {
8915+ PATUNFETCH;
8916+ PATUNFETCH;
8917+ break;
8918+ }
8919+
8920+ c = c1;
8921+ }
8922+ else
8923+ {
8924+ PATUNFETCH;
8925+ break;
8926+ }
8927+
8928+ /* If we get here, we found another repeat character. */
8929+ }
8930+
8931+ /* Star, etc. applied to an empty pattern is equivalent
8932+ to an empty pattern. */
8933+ if (!laststart)
8934+ break;
8935+
8936+ /* Now we know whether or not zero matches is allowed
8937+ and also whether or not two or more matches is allowed. */
8938+ if (many_times_ok)
8939+ { /* More than one repetition is allowed, so put in at the
8940+ end a backward relative jump from `b' to before the next
8941+ jump we're going to put in below (which jumps from
8942+ laststart to after this jump).
8943+
8944+ But if we are at the `*' in the exact sequence `.*\n',
8945+ insert an unconditional jump backwards to the .,
8946+ instead of the beginning of the loop. This way we only
8947+ push a failure point once, instead of every time
8948+ through the loop. */
8949+ assert (p - 1 > pattern);
8950+
8951+ /* Allocate the space for the jump. */
8952+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
8953+
8954+ /* We know we are not at the first character of the pattern,
8955+ because laststart was nonzero. And we've already
8956+ incremented `p', by the way, to be the character after
8957+ the `*'. Do we have to do something analogous here
8958+ for null bytes, because of RE_DOT_NOT_NULL? */
8959+ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
8960+ && zero_times_ok
8961+ && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
8962+ && !(syntax & RE_DOT_NEWLINE))
8963+ { /* We have .*\n. */
8964+ STORE_JUMP (jump, b, laststart);
8965+ keep_string_p = true;
8966+ }
8967+ else
8968+ /* Anything else. */
8969+ STORE_JUMP (maybe_pop_jump, b, laststart -
8970+ (1 + OFFSET_ADDRESS_SIZE));
8971+
8972+ /* We've added more stuff to the buffer. */
8973+ b += 1 + OFFSET_ADDRESS_SIZE;
8974+ }
8975+
8976+ /* On failure, jump from laststart to b + 3, which will be the
8977+ end of the buffer after this jump is inserted. */
8978+ /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE' instead of
8979+ 'b + 3'. */
8980+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
8981+ INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
8982+ : on_failure_jump,
8983+ laststart, b + 1 + OFFSET_ADDRESS_SIZE);
8984+ pending_exact = 0;
8985+ b += 1 + OFFSET_ADDRESS_SIZE;
8986+
8987+ if (!zero_times_ok)
8988+ {
8989+ /* At least one repetition is required, so insert a
8990+ `dummy_failure_jump' before the initial
8991+ `on_failure_jump' instruction of the loop. This
8992+ effects a skip over that instruction the first time
8993+ we hit that loop. */
8994+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
8995+ INSERT_JUMP (dummy_failure_jump, laststart, laststart +
8996+ 2 + 2 * OFFSET_ADDRESS_SIZE);
8997+ b += 1 + OFFSET_ADDRESS_SIZE;
8998+ }
8999+ }
9000+ break;
9001+
9002+
9003+ case '.':
9004+ laststart = b;
9005+ BUF_PUSH (anychar);
9006+ break;
9007+
9008+
9009+ case '[':
9010+ {
9011+ boolean had_char_class = false;
9012+#ifdef WCHAR
9013+ CHAR_T range_start = 0xffffffff;
9014+#else
9015+ unsigned int range_start = 0xffffffff;
9016+#endif
9017+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9018+
9019+#ifdef WCHAR
9020+ /* We assume a charset(_not) structure as a wchar_t array.
9021+ charset[0] = (re_opcode_t) charset(_not)
9022+ charset[1] = l (= length of char_classes)
9023+ charset[2] = m (= length of collating_symbols)
9024+ charset[3] = n (= length of equivalence_classes)
9025+ charset[4] = o (= length of char_ranges)
9026+ charset[5] = p (= length of chars)
9027+
9028+ charset[6] = char_class (wctype_t)
9029+ charset[6+CHAR_CLASS_SIZE] = char_class (wctype_t)
9030+ ...
9031+ charset[l+5] = char_class (wctype_t)
9032+
9033+ charset[l+6] = collating_symbol (wchar_t)
9034+ ...
9035+ charset[l+m+5] = collating_symbol (wchar_t)
9036+ ifdef _LIBC we use the index if
9037+ _NL_COLLATE_SYMB_EXTRAMB instead of
9038+ wchar_t string.
9039+
9040+ charset[l+m+6] = equivalence_classes (wchar_t)
9041+ ...
9042+ charset[l+m+n+5] = equivalence_classes (wchar_t)
9043+ ifdef _LIBC we use the index in
9044+ _NL_COLLATE_WEIGHT instead of
9045+ wchar_t string.
9046+
9047+ charset[l+m+n+6] = range_start
9048+ charset[l+m+n+7] = range_end
9049+ ...
9050+ charset[l+m+n+2o+4] = range_start
9051+ charset[l+m+n+2o+5] = range_end
9052+ ifdef _LIBC we use the value looked up
9053+ in _NL_COLLATE_COLLSEQ instead of
9054+ wchar_t character.
9055+
9056+ charset[l+m+n+2o+6] = char
9057+ ...
9058+ charset[l+m+n+2o+p+5] = char
9059+
9060+ */
9061+
9062+ /* We need at least 6 spaces: the opcode, the length of
9063+ char_classes, the length of collating_symbols, the length of
9064+ equivalence_classes, the length of char_ranges, the length of
9065+ chars. */
9066+ GET_BUFFER_SPACE (6);
9067+
9068+ /* Save b as laststart. And We use laststart as the pointer
9069+ to the first element of the charset here.
9070+ In other words, laststart[i] indicates charset[i]. */
9071+ laststart = b;
9072+
9073+ /* We test `*p == '^' twice, instead of using an if
9074+ statement, so we only need one BUF_PUSH. */
9075+ BUF_PUSH (*p == '^' ? charset_not : charset);
9076+ if (*p == '^')
9077+ p++;
9078+
9079+ /* Push the length of char_classes, the length of
9080+ collating_symbols, the length of equivalence_classes, the
9081+ length of char_ranges and the length of chars. */
9082+ BUF_PUSH_3 (0, 0, 0);
9083+ BUF_PUSH_2 (0, 0);
9084+
9085+ /* Remember the first position in the bracket expression. */
9086+ p1 = p;
9087+
9088+ /* charset_not matches newline according to a syntax bit. */
9089+ if ((re_opcode_t) b[-6] == charset_not
9090+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
9091+ {
9092+ BUF_PUSH('\n');
9093+ laststart[5]++; /* Update the length of characters */
9094+ }
9095+
9096+ /* Read in characters and ranges, setting map bits. */
9097+ for (;;)
9098+ {
9099+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9100+
9101+ PATFETCH (c);
9102+
9103+ /* \ might escape characters inside [...] and [^...]. */
9104+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
9105+ {
9106+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
9107+
9108+ PATFETCH (c1);
9109+ BUF_PUSH(c1);
9110+ laststart[5]++; /* Update the length of chars */
9111+ range_start = c1;
9112+ continue;
9113+ }
9114+
9115+ /* Could be the end of the bracket expression. If it's
9116+ not (i.e., when the bracket expression is `[]' so
9117+ far), the ']' character bit gets set way below. */
9118+ if (c == ']' && p != p1 + 1)
9119+ break;
9120+
9121+ /* Look ahead to see if it's a range when the last thing
9122+ was a character class. */
9123+ if (had_char_class && c == '-' && *p != ']')
9124+ FREE_STACK_RETURN (REG_ERANGE);
9125+
9126+ /* Look ahead to see if it's a range when the last thing
9127+ was a character: if this is a hyphen not at the
9128+ beginning or the end of a list, then it's the range
9129+ operator. */
9130+ if (c == '-'
9131+ && !(p - 2 >= pattern && p[-2] == '[')
9132+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
9133+ && *p != ']')
9134+ {
9135+ reg_errcode_t ret;
9136+ /* Allocate the space for range_start and range_end. */
9137+ GET_BUFFER_SPACE (2);
9138+ /* Update the pointer to indicate end of buffer. */
9139+ b += 2;
9140+ ret = wcs_compile_range (range_start, &p, pend, translate,
9141+ syntax, b, laststart);
9142+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
9143+ range_start = 0xffffffff;
9144+ }
9145+ else if (p[0] == '-' && p[1] != ']')
9146+ { /* This handles ranges made up of characters only. */
9147+ reg_errcode_t ret;
9148+
9149+ /* Move past the `-'. */
9150+ PATFETCH (c1);
9151+ /* Allocate the space for range_start and range_end. */
9152+ GET_BUFFER_SPACE (2);
9153+ /* Update the pointer to indicate end of buffer. */
9154+ b += 2;
9155+ ret = wcs_compile_range (c, &p, pend, translate, syntax, b,
9156+ laststart);
9157+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
9158+ range_start = 0xffffffff;
9159+ }
9160+
9161+ /* See if we're at the beginning of a possible character
9162+ class. */
9163+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
9164+ { /* Leave room for the null. */
9165+ char str[CHAR_CLASS_MAX_LENGTH + 1];
9166+
9167+ PATFETCH (c);
9168+ c1 = 0;
9169+
9170+ /* If pattern is `[[:'. */
9171+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9172+
9173+ for (;;)
9174+ {
9175+ PATFETCH (c);
9176+ if ((c == ':' && *p == ']') || p == pend)
9177+ break;
9178+ if (c1 < CHAR_CLASS_MAX_LENGTH)
9179+ str[c1++] = c;
9180+ else
9181+ /* This is in any case an invalid class name. */
9182+ str[0] = '\0';
9183+ }
9184+ str[c1] = '\0';
9185+
9186+ /* If isn't a word bracketed by `[:' and `:]':
9187+ undo the ending character, the letters, and leave
9188+ the leading `:' and `[' (but store them as character). */
9189+ if (c == ':' && *p == ']')
9190+ {
9191+ wctype_t wt;
9192+ uintptr_t alignedp;
9193+
9194+ /* Query the character class as wctype_t. */
9195+ wt = IS_CHAR_CLASS (str);
9196+ if (wt == 0)
9197+ FREE_STACK_RETURN (REG_ECTYPE);
9198+
9199+ /* Throw away the ] at the end of the character
9200+ class. */
9201+ PATFETCH (c);
9202+
9203+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9204+
9205+ /* Allocate the space for character class. */
9206+ GET_BUFFER_SPACE(CHAR_CLASS_SIZE);
9207+ /* Update the pointer to indicate end of buffer. */
9208+ b += CHAR_CLASS_SIZE;
9209+ /* Move data which follow character classes
9210+ not to violate the data. */
9211+ insert_space(CHAR_CLASS_SIZE,
9212+ laststart + 6 + laststart[1],
9213+ b - 1);
9214+ alignedp = ((uintptr_t)(laststart + 6 + laststart[1])
9215+ + __alignof__(wctype_t) - 1)
9216+ & ~(uintptr_t)(__alignof__(wctype_t) - 1);
9217+ /* Store the character class. */
9218+ *((wctype_t*)alignedp) = wt;
9219+ /* Update length of char_classes */
9220+ laststart[1] += CHAR_CLASS_SIZE;
9221+
9222+ had_char_class = true;
9223+ }
9224+ else
9225+ {
9226+ c1++;
9227+ while (c1--)
9228+ PATUNFETCH;
9229+ BUF_PUSH ('[');
9230+ BUF_PUSH (':');
9231+ laststart[5] += 2; /* Update the length of characters */
9232+ range_start = ':';
9233+ had_char_class = false;
9234+ }
9235+ }
9236+ else if (syntax & RE_CHAR_CLASSES && c == '[' && (*p == '='
9237+ || *p == '.'))
9238+ {
9239+ CHAR_T str[128]; /* Should be large enough. */
9240+ CHAR_T delim = *p; /* '=' or '.' */
9241+# ifdef _LIBC
9242+ uint32_t nrules =
9243+ _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
9244+# endif
9245+ PATFETCH (c);
9246+ c1 = 0;
9247+
9248+ /* If pattern is `[[=' or '[[.'. */
9249+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9250+
9251+ for (;;)
9252+ {
9253+ PATFETCH (c);
9254+ if ((c == delim && *p == ']') || p == pend)
9255+ break;
9256+ if (c1 < sizeof (str) - 1)
9257+ str[c1++] = c;
9258+ else
9259+ /* This is in any case an invalid class name. */
9260+ str[0] = '\0';
9261+ }
9262+ str[c1] = '\0';
9263+
9264+ if (c == delim && *p == ']' && str[0] != '\0')
9265+ {
9266+ unsigned int i, offset;
9267+ /* If we have no collation data we use the default
9268+ collation in which each character is in a class
9269+ by itself. It also means that ASCII is the
9270+ character set and therefore we cannot have character
9271+ with more than one byte in the multibyte
9272+ representation. */
9273+
9274+ /* If not defined _LIBC, we push the name and
9275+ `\0' for the sake of matching performance. */
9276+ int datasize = c1 + 1;
9277+
9278+# ifdef _LIBC
9279+ int32_t idx = 0;
9280+ if (nrules == 0)
9281+# endif
9282+ {
9283+ if (c1 != 1)
9284+ FREE_STACK_RETURN (REG_ECOLLATE);
9285+ }
9286+# ifdef _LIBC
9287+ else
9288+ {
9289+ const int32_t *table;
9290+ const int32_t *weights;
9291+ const int32_t *extra;
9292+ const int32_t *indirect;
9293+ wint_t *cp;
9294+
9295+ if(delim == '=')
9296+ {
9297+ /* We push the index for equivalence class. */
9298+ cp = (wint_t*)str;
9299+
9300+ table = (const int32_t *)
9301+ _NL_CURRENT (LC_COLLATE,
9302+ _NL_COLLATE_TABLEWC);
9303+ weights = (const int32_t *)
9304+ _NL_CURRENT (LC_COLLATE,
9305+ _NL_COLLATE_WEIGHTWC);
9306+ extra = (const wint_t *)
9307+ _NL_CURRENT (LC_COLLATE,
9308+ _NL_COLLATE_EXTRAWC);
9309+ indirect = (const int32_t *)
9310+ _NL_CURRENT (LC_COLLATE,
9311+ _NL_COLLATE_INDIRECTWC);
9312+
9313+ idx = FINDIDX (table, indirect, extra, &cp, 1);
9314+ if (idx == 0 || cp < (wint_t*) str + c1)
9315+ /* This is no valid character. */
9316+ FREE_STACK_RETURN (REG_ECOLLATE);
9317+
9318+ str[0] = (wchar_t)idx;
9319+ }
9320+ else /* delim == '.' */
9321+ {
9322+ /* We push collation sequence value
9323+ for collating symbol. */
9324+ int32_t table_size;
9325+ const int32_t *symb_table;
9326+ const unsigned char *extra;
9327+ int32_t idx;
9328+ int32_t elem;
9329+ int32_t second;
9330+ int32_t hash;
9331+ char char_str[c1];
9332+
9333+ /* We have to convert the name to a single-byte
9334+ string. This is possible since the names
9335+ consist of ASCII characters and the internal
9336+ representation is UCS4. */
9337+ for (i = 0; i < c1; ++i)
9338+ char_str[i] = str[i];
9339+
9340+ table_size =
9341+ _NL_CURRENT_WORD (LC_COLLATE,
9342+ _NL_COLLATE_SYMB_HASH_SIZEMB);
9343+ symb_table = (const int32_t *)
9344+ _NL_CURRENT (LC_COLLATE,
9345+ _NL_COLLATE_SYMB_TABLEMB);
9346+ extra = (const unsigned char *)
9347+ _NL_CURRENT (LC_COLLATE,
9348+ _NL_COLLATE_SYMB_EXTRAMB);
9349+
9350+ /* Locate the character in the hashing table. */
9351+ hash = elem_hash (char_str, c1);
9352+
9353+ idx = 0;
9354+ elem = hash % table_size;
9355+ second = hash % (table_size - 2);
9356+ while (symb_table[2 * elem] != 0)
9357+ {
9358+ /* First compare the hashing value. */
9359+ if (symb_table[2 * elem] == hash
9360+ && c1 == extra[symb_table[2 * elem + 1]]
9361+ && memcmp (char_str,
9362+ &extra[symb_table[2 * elem + 1]
9363+ + 1], c1) == 0)
9364+ {
9365+ /* Yep, this is the entry. */
9366+ idx = symb_table[2 * elem + 1];
9367+ idx += 1 + extra[idx];
9368+ break;
9369+ }
9370+
9371+ /* Next entry. */
9372+ elem += second;
9373+ }
9374+
9375+ if (symb_table[2 * elem] != 0)
9376+ {
9377+ /* Compute the index of the byte sequence
9378+ in the table. */
9379+ idx += 1 + extra[idx];
9380+ /* Adjust for the alignment. */
9381+ idx = (idx + 3) & ~3;
9382+
9383+ str[0] = (wchar_t) idx + 4;
9384+ }
9385+ else if (symb_table[2 * elem] == 0 && c1 == 1)
9386+ {
9387+ /* No valid character. Match it as a
9388+ single byte character. */
9389+ had_char_class = false;
9390+ BUF_PUSH(str[0]);
9391+ /* Update the length of characters */
9392+ laststart[5]++;
9393+ range_start = str[0];
9394+
9395+ /* Throw away the ] at the end of the
9396+ collating symbol. */
9397+ PATFETCH (c);
9398+ /* exit from the switch block. */
9399+ continue;
9400+ }
9401+ else
9402+ FREE_STACK_RETURN (REG_ECOLLATE);
9403+ }
9404+ datasize = 1;
9405+ }
9406+# endif
9407+ /* Throw away the ] at the end of the equivalence
9408+ class (or collating symbol). */
9409+ PATFETCH (c);
9410+
9411+ /* Allocate the space for the equivalence class
9412+ (or collating symbol) (and '\0' if needed). */
9413+ GET_BUFFER_SPACE(datasize);
9414+ /* Update the pointer to indicate end of buffer. */
9415+ b += datasize;
9416+
9417+ if (delim == '=')
9418+ { /* equivalence class */
9419+ /* Calculate the offset of char_ranges,
9420+ which is next to equivalence_classes. */
9421+ offset = laststart[1] + laststart[2]
9422+ + laststart[3] +6;
9423+ /* Insert space. */
9424+ insert_space(datasize, laststart + offset, b - 1);
9425+
9426+ /* Write the equivalence_class and \0. */
9427+ for (i = 0 ; i < datasize ; i++)
9428+ laststart[offset + i] = str[i];
9429+
9430+ /* Update the length of equivalence_classes. */
9431+ laststart[3] += datasize;
9432+ had_char_class = true;
9433+ }
9434+ else /* delim == '.' */
9435+ { /* collating symbol */
9436+ /* Calculate the offset of the equivalence_classes,
9437+ which is next to collating_symbols. */
9438+ offset = laststart[1] + laststart[2] + 6;
9439+ /* Insert space and write the collationg_symbol
9440+ and \0. */
9441+ insert_space(datasize, laststart + offset, b-1);
9442+ for (i = 0 ; i < datasize ; i++)
9443+ laststart[offset + i] = str[i];
9444+
9445+ /* In re_match_2_internal if range_start < -1, we
9446+ assume -range_start is the offset of the
9447+ collating symbol which is specified as
9448+ the character of the range start. So we assign
9449+ -(laststart[1] + laststart[2] + 6) to
9450+ range_start. */
9451+ range_start = -(laststart[1] + laststart[2] + 6);
9452+ /* Update the length of collating_symbol. */
9453+ laststart[2] += datasize;
9454+ had_char_class = false;
9455+ }
9456+ }
9457+ else
9458+ {
9459+ c1++;
9460+ while (c1--)
9461+ PATUNFETCH;
9462+ BUF_PUSH ('[');
9463+ BUF_PUSH (delim);
9464+ laststart[5] += 2; /* Update the length of characters */
9465+ range_start = delim;
9466+ had_char_class = false;
9467+ }
9468+ }
9469+ else
9470+ {
9471+ had_char_class = false;
9472+ BUF_PUSH(c);
9473+ laststart[5]++; /* Update the length of characters */
9474+ range_start = c;
9475+ }
9476+ }
9477+
9478+#else /* BYTE */
9479+ /* Ensure that we have enough space to push a charset: the
9480+ opcode, the length count, and the bitset; 34 bytes in all. */
9481+ GET_BUFFER_SPACE (34);
9482+
9483+ laststart = b;
9484+
9485+ /* We test `*p == '^' twice, instead of using an if
9486+ statement, so we only need one BUF_PUSH. */
9487+ BUF_PUSH (*p == '^' ? charset_not : charset);
9488+ if (*p == '^')
9489+ p++;
9490+
9491+ /* Remember the first position in the bracket expression. */
9492+ p1 = p;
9493+
9494+ /* Push the number of bytes in the bitmap. */
9495+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
9496+
9497+ /* Clear the whole map. */
9498+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
9499+
9500+ /* charset_not matches newline according to a syntax bit. */
9501+ if ((re_opcode_t) b[-2] == charset_not
9502+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
9503+ SET_LIST_BIT ('\n');
9504+
9505+ /* Read in characters and ranges, setting map bits. */
9506+ for (;;)
9507+ {
9508+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9509+
9510+ PATFETCH (c);
9511+
9512+ /* \ might escape characters inside [...] and [^...]. */
9513+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
9514+ {
9515+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
9516+
9517+ PATFETCH (c1);
9518+ SET_LIST_BIT (c1);
9519+ range_start = c1;
9520+ continue;
9521+ }
9522+
9523+ /* Could be the end of the bracket expression. If it's
9524+ not (i.e., when the bracket expression is `[]' so
9525+ far), the ']' character bit gets set way below. */
9526+ if (c == ']' && p != p1 + 1)
9527+ break;
9528+
9529+ /* Look ahead to see if it's a range when the last thing
9530+ was a character class. */
9531+ if (had_char_class && c == '-' && *p != ']')
9532+ FREE_STACK_RETURN (REG_ERANGE);
9533+
9534+ /* Look ahead to see if it's a range when the last thing
9535+ was a character: if this is a hyphen not at the
9536+ beginning or the end of a list, then it's the range
9537+ operator. */
9538+ if (c == '-'
9539+ && !(p - 2 >= pattern && p[-2] == '[')
9540+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
9541+ && *p != ']')
9542+ {
9543+ reg_errcode_t ret
9544+ = byte_compile_range (range_start, &p, pend, translate,
9545+ syntax, b);
9546+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
9547+ range_start = 0xffffffff;
9548+ }
9549+
9550+ else if (p[0] == '-' && p[1] != ']')
9551+ { /* This handles ranges made up of characters only. */
9552+ reg_errcode_t ret;
9553+
9554+ /* Move past the `-'. */
9555+ PATFETCH (c1);
9556+
9557+ ret = byte_compile_range (c, &p, pend, translate, syntax, b);
9558+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
9559+ range_start = 0xffffffff;
9560+ }
9561+
9562+ /* See if we're at the beginning of a possible character
9563+ class. */
9564+
9565+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
9566+ { /* Leave room for the null. */
9567+ char str[CHAR_CLASS_MAX_LENGTH + 1];
9568+
9569+ PATFETCH (c);
9570+ c1 = 0;
9571+
9572+ /* If pattern is `[[:'. */
9573+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9574+
9575+ for (;;)
9576+ {
9577+ PATFETCH (c);
9578+ if ((c == ':' && *p == ']') || p == pend)
9579+ break;
9580+ if (((int) c1) < CHAR_CLASS_MAX_LENGTH)
9581+ str[c1++] = c;
9582+ else
9583+ /* This is in any case an invalid class name. */
9584+ str[0] = '\0';
9585+ }
9586+ str[c1] = '\0';
9587+
9588+ /* If isn't a word bracketed by `[:' and `:]':
9589+ undo the ending character, the letters, and leave
9590+ the leading `:' and `[' (but set bits for them). */
9591+ if (c == ':' && *p == ']')
9592+ {
9593+# if WIDE_CHAR_SUPPORT
9594+ boolean is_lower = STREQ (str, "lower");
9595+ boolean is_upper = STREQ (str, "upper");
9596+ wctype_t wt;
9597+ int ch;
9598+
9599+ wt = IS_CHAR_CLASS (str);
9600+ if (wt == 0)
9601+ FREE_STACK_RETURN (REG_ECTYPE);
9602+
9603+ /* Throw away the ] at the end of the character
9604+ class. */
9605+ PATFETCH (c);
9606+
9607+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9608+
9609+ for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
9610+ {
9611+# ifdef _LIBC
9612+ if (__iswctype (__btowc (ch), wt))
9613+ SET_LIST_BIT (ch);
9614+# else
9615+ if (iswctype (btowc (ch), wt))
9616+ SET_LIST_BIT (ch);
9617+# endif
9618+
9619+ if (translate && (is_upper || is_lower)
9620+ && (ISUPPER (ch) || ISLOWER (ch)))
9621+ SET_LIST_BIT (ch);
9622+ }
9623+
9624+ had_char_class = true;
9625+# else
9626+ int ch;
9627+ boolean is_alnum = STREQ (str, "alnum");
9628+ boolean is_alpha = STREQ (str, "alpha");
9629+ boolean is_blank = STREQ (str, "blank");
9630+ boolean is_cntrl = STREQ (str, "cntrl");
9631+ boolean is_digit = STREQ (str, "digit");
9632+ boolean is_graph = STREQ (str, "graph");
9633+ boolean is_lower = STREQ (str, "lower");
9634+ boolean is_print = STREQ (str, "print");
9635+ boolean is_punct = STREQ (str, "punct");
9636+ boolean is_space = STREQ (str, "space");
9637+ boolean is_upper = STREQ (str, "upper");
9638+ boolean is_xdigit = STREQ (str, "xdigit");
9639+
9640+ if (!IS_CHAR_CLASS (str))
9641+ FREE_STACK_RETURN (REG_ECTYPE);
9642+
9643+ /* Throw away the ] at the end of the character
9644+ class. */
9645+ PATFETCH (c);
9646+
9647+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9648+
9649+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
9650+ {
9651+ /* This was split into 3 if's to
9652+ avoid an arbitrary limit in some compiler. */
9653+ if ( (is_alnum && ISALNUM (ch))
9654+ || (is_alpha && ISALPHA (ch))
9655+ || (is_blank && ISBLANK (ch))
9656+ || (is_cntrl && ISCNTRL (ch)))
9657+ SET_LIST_BIT (ch);
9658+ if ( (is_digit && ISDIGIT (ch))
9659+ || (is_graph && ISGRAPH (ch))
9660+ || (is_lower && ISLOWER (ch))
9661+ || (is_print && ISPRINT (ch)))
9662+ SET_LIST_BIT (ch);
9663+ if ( (is_punct && ISPUNCT (ch))
9664+ || (is_space && ISSPACE (ch))
9665+ || (is_upper && ISUPPER (ch))
9666+ || (is_xdigit && ISXDIGIT (ch)))
9667+ SET_LIST_BIT (ch);
9668+ if ( translate && (is_upper || is_lower)
9669+ && (ISUPPER (ch) || ISLOWER (ch)))
9670+ SET_LIST_BIT (ch);
9671+ }
9672+ had_char_class = true;
9673+# endif /* libc || wctype.h */
9674+ }
9675+ else
9676+ {
9677+ c1++;
9678+ while (c1--)
9679+ PATUNFETCH;
9680+ SET_LIST_BIT ('[');
9681+ SET_LIST_BIT (':');
9682+ range_start = ':';
9683+ had_char_class = false;
9684+ }
9685+ }
9686+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '=')
9687+ {
9688+ unsigned char str[MB_LEN_MAX + 1];
9689+# ifdef _LIBC
9690+ uint32_t nrules =
9691+ _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
9692+# endif
9693+
9694+ PATFETCH (c);
9695+ c1 = 0;
9696+
9697+ /* If pattern is `[[='. */
9698+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9699+
9700+ for (;;)
9701+ {
9702+ PATFETCH (c);
9703+ if ((c == '=' && *p == ']') || p == pend)
9704+ break;
9705+ if (c1 < MB_LEN_MAX)
9706+ str[c1++] = c;
9707+ else
9708+ /* This is in any case an invalid class name. */
9709+ str[0] = '\0';
9710+ }
9711+ str[c1] = '\0';
9712+
9713+ if (c == '=' && *p == ']' && str[0] != '\0')
9714+ {
9715+ /* If we have no collation data we use the default
9716+ collation in which each character is in a class
9717+ by itself. It also means that ASCII is the
9718+ character set and therefore we cannot have character
9719+ with more than one byte in the multibyte
9720+ representation. */
9721+# ifdef _LIBC
9722+ if (nrules == 0)
9723+# endif
9724+ {
9725+ if (c1 != 1)
9726+ FREE_STACK_RETURN (REG_ECOLLATE);
9727+
9728+ /* Throw away the ] at the end of the equivalence
9729+ class. */
9730+ PATFETCH (c);
9731+
9732+ /* Set the bit for the character. */
9733+ SET_LIST_BIT (str[0]);
9734+ }
9735+# ifdef _LIBC
9736+ else
9737+ {
9738+ /* Try to match the byte sequence in `str' against
9739+ those known to the collate implementation.
9740+ First find out whether the bytes in `str' are
9741+ actually from exactly one character. */
9742+ const int32_t *table;
9743+ const unsigned char *weights;
9744+ const unsigned char *extra;
9745+ const int32_t *indirect;
9746+ int32_t idx;
9747+ const unsigned char *cp = str;
9748+ int ch;
9749+
9750+ table = (const int32_t *)
9751+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
9752+ weights = (const unsigned char *)
9753+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
9754+ extra = (const unsigned char *)
9755+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
9756+ indirect = (const int32_t *)
9757+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
9758+ idx = FINDIDX (table, indirect, extra, &cp, 1);
9759+ if (idx == 0 || cp < str + c1)
9760+ /* This is no valid character. */
9761+ FREE_STACK_RETURN (REG_ECOLLATE);
9762+
9763+ /* Throw away the ] at the end of the equivalence
9764+ class. */
9765+ PATFETCH (c);
9766+
9767+ /* Now we have to go throught the whole table
9768+ and find all characters which have the same
9769+ first level weight.
9770+
9771+ XXX Note that this is not entirely correct.
9772+ we would have to match multibyte sequences
9773+ but this is not possible with the current
9774+ implementation. */
9775+ for (ch = 1; ch < 256; ++ch)
9776+ /* XXX This test would have to be changed if we
9777+ would allow matching multibyte sequences. */
9778+ if (table[ch] > 0)
9779+ {
9780+ int32_t idx2 = table[ch];
9781+ size_t len = weights[idx2];
9782+
9783+ /* Test whether the lenghts match. */
9784+ if (weights[idx] == len)
9785+ {
9786+ /* They do. New compare the bytes of
9787+ the weight. */
9788+ size_t cnt = 0;
9789+
9790+ while (cnt < len
9791+ && (weights[idx + 1 + cnt]
9792+ == weights[idx2 + 1 + cnt]))
9793+ ++cnt;
9794+
9795+ if (cnt == len)
9796+ /* They match. Mark the character as
9797+ acceptable. */
9798+ SET_LIST_BIT (ch);
9799+ }
9800+ }
9801+ }
9802+# endif
9803+ had_char_class = true;
9804+ }
9805+ else
9806+ {
9807+ c1++;
9808+ while (c1--)
9809+ PATUNFETCH;
9810+ SET_LIST_BIT ('[');
9811+ SET_LIST_BIT ('=');
9812+ range_start = '=';
9813+ had_char_class = false;
9814+ }
9815+ }
9816+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '.')
9817+ {
9818+ unsigned char str[128]; /* Should be large enough. */
9819+# ifdef _LIBC
9820+ uint32_t nrules =
9821+ _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
9822+# endif
9823+
9824+ PATFETCH (c);
9825+ c1 = 0;
9826+
9827+ /* If pattern is `[[.'. */
9828+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9829+
9830+ for (;;)
9831+ {
9832+ PATFETCH (c);
9833+ if ((c == '.' && *p == ']') || p == pend)
9834+ break;
9835+ if (c1 < sizeof (str))
9836+ str[c1++] = c;
9837+ else
9838+ /* This is in any case an invalid class name. */
9839+ str[0] = '\0';
9840+ }
9841+ str[c1] = '\0';
9842+
9843+ if (c == '.' && *p == ']' && str[0] != '\0')
9844+ {
9845+ /* If we have no collation data we use the default
9846+ collation in which each character is the name
9847+ for its own class which contains only the one
9848+ character. It also means that ASCII is the
9849+ character set and therefore we cannot have character
9850+ with more than one byte in the multibyte
9851+ representation. */
9852+# ifdef _LIBC
9853+ if (nrules == 0)
9854+# endif
9855+ {
9856+ if (c1 != 1)
9857+ FREE_STACK_RETURN (REG_ECOLLATE);
9858+
9859+ /* Throw away the ] at the end of the equivalence
9860+ class. */
9861+ PATFETCH (c);
9862+
9863+ /* Set the bit for the character. */
9864+ SET_LIST_BIT (str[0]);
9865+ range_start = ((const unsigned char *) str)[0];
9866+ }
9867+# ifdef _LIBC
9868+ else
9869+ {
9870+ /* Try to match the byte sequence in `str' against
9871+ those known to the collate implementation.
9872+ First find out whether the bytes in `str' are
9873+ actually from exactly one character. */
9874+ int32_t table_size;
9875+ const int32_t *symb_table;
9876+ const unsigned char *extra;
9877+ int32_t idx;
9878+ int32_t elem;
9879+ int32_t second;
9880+ int32_t hash;
9881+
9882+ table_size =
9883+ _NL_CURRENT_WORD (LC_COLLATE,
9884+ _NL_COLLATE_SYMB_HASH_SIZEMB);
9885+ symb_table = (const int32_t *)
9886+ _NL_CURRENT (LC_COLLATE,
9887+ _NL_COLLATE_SYMB_TABLEMB);
9888+ extra = (const unsigned char *)
9889+ _NL_CURRENT (LC_COLLATE,
9890+ _NL_COLLATE_SYMB_EXTRAMB);
9891+
9892+ /* Locate the character in the hashing table. */
9893+ hash = elem_hash ((const char *) str, c1);
9894+
9895+ idx = 0;
9896+ elem = hash % table_size;
9897+ second = hash % (table_size - 2);
9898+ while (symb_table[2 * elem] != 0)
9899+ {
9900+ /* First compare the hashing value. */
9901+ if (symb_table[2 * elem] == hash
9902+ && c1 == extra[symb_table[2 * elem + 1]]
9903+ && memcmp (str,
9904+ &extra[symb_table[2 * elem + 1]
9905+ + 1],
9906+ c1) == 0)
9907+ {
9908+ /* Yep, this is the entry. */
9909+ idx = symb_table[2 * elem + 1];
9910+ idx += 1 + extra[idx];
9911+ break;
9912+ }
9913+
9914+ /* Next entry. */
9915+ elem += second;
9916+ }
9917+
9918+ if (symb_table[2 * elem] == 0)
9919+ /* This is no valid character. */
9920+ FREE_STACK_RETURN (REG_ECOLLATE);
9921+
9922+ /* Throw away the ] at the end of the equivalence
9923+ class. */
9924+ PATFETCH (c);
9925+
9926+ /* Now add the multibyte character(s) we found
9927+ to the accept list.
9928+
9929+ XXX Note that this is not entirely correct.
9930+ we would have to match multibyte sequences
9931+ but this is not possible with the current
9932+ implementation. Also, we have to match
9933+ collating symbols, which expand to more than
9934+ one file, as a whole and not allow the
9935+ individual bytes. */
9936+ c1 = extra[idx++];
9937+ if (c1 == 1)
9938+ range_start = extra[idx];
9939+ while (c1-- > 0)
9940+ {
9941+ SET_LIST_BIT (extra[idx]);
9942+ ++idx;
9943+ }
9944+ }
9945+# endif
9946+ had_char_class = false;
9947+ }
9948+ else
9949+ {
9950+ c1++;
9951+ while (c1--)
9952+ PATUNFETCH;
9953+ SET_LIST_BIT ('[');
9954+ SET_LIST_BIT ('.');
9955+ range_start = '.';
9956+ had_char_class = false;
9957+ }
9958+ }
9959+ else
9960+ {
9961+ had_char_class = false;
9962+ SET_LIST_BIT (c);
9963+ range_start = c;
9964+ }
9965+ }
9966+
9967+ /* Discard any (non)matching list bytes that are all 0 at the
9968+ end of the map. Decrease the map-length byte too. */
9969+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
9970+ b[-1]--;
9971+ b += b[-1];
9972+#endif /* WCHAR */
9973+ }
9974+ break;
9975+
9976+
9977+ case '(':
9978+ if (syntax & RE_NO_BK_PARENS)
9979+ goto handle_open;
9980+ else
9981+ goto normal_char;
9982+
9983+
9984+ case ')':
9985+ if (syntax & RE_NO_BK_PARENS)
9986+ goto handle_close;
9987+ else
9988+ goto normal_char;
9989+
9990+
9991+ case '\n':
9992+ if (syntax & RE_NEWLINE_ALT)
9993+ goto handle_alt;
9994+ else
9995+ goto normal_char;
9996+
9997+
9998+ case '|':
9999+ if (syntax & RE_NO_BK_VBAR)
10000+ goto handle_alt;
10001+ else
10002+ goto normal_char;
10003+
10004+
10005+ case '{':
10006+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
10007+ goto handle_interval;
10008+ else
10009+ goto normal_char;
10010+
10011+
10012+ case '\\':
10013+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
10014+
10015+ /* Do not translate the character after the \, so that we can
10016+ distinguish, e.g., \B from \b, even if we normally would
10017+ translate, e.g., B to b. */
10018+ PATFETCH_RAW (c);
10019+
10020+ switch (c)
10021+ {
10022+ case '(':
10023+ if (syntax & RE_NO_BK_PARENS)
10024+ goto normal_backslash;
10025+
10026+ handle_open:
10027+ bufp->re_nsub++;
10028+ regnum++;
10029+
10030+ if (COMPILE_STACK_FULL)
10031+ {
10032+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
10033+ compile_stack_elt_t);
10034+ if (compile_stack.stack == NULL) return REG_ESPACE;
10035+
10036+ compile_stack.size <<= 1;
10037+ }
10038+
10039+ /* These are the values to restore when we hit end of this
10040+ group. They are all relative offsets, so that if the
10041+ whole pattern moves because of realloc, they will still
10042+ be valid. */
10043+ COMPILE_STACK_TOP.begalt_offset = begalt - COMPILED_BUFFER_VAR;
10044+ COMPILE_STACK_TOP.fixup_alt_jump
10045+ = fixup_alt_jump ? fixup_alt_jump - COMPILED_BUFFER_VAR + 1 : 0;
10046+ COMPILE_STACK_TOP.laststart_offset = b - COMPILED_BUFFER_VAR;
10047+ COMPILE_STACK_TOP.regnum = regnum;
10048+
10049+ /* We will eventually replace the 0 with the number of
10050+ groups inner to this one. But do not push a
10051+ start_memory for groups beyond the last one we can
10052+ represent in the compiled pattern. */
10053+ if (regnum <= MAX_REGNUM)
10054+ {
10055+ COMPILE_STACK_TOP.inner_group_offset = b
10056+ - COMPILED_BUFFER_VAR + 2;
10057+ BUF_PUSH_3 (start_memory, regnum, 0);
10058+ }
10059+
10060+ compile_stack.avail++;
10061+
10062+ fixup_alt_jump = 0;
10063+ laststart = 0;
10064+ begalt = b;
10065+ /* If we've reached MAX_REGNUM groups, then this open
10066+ won't actually generate any code, so we'll have to
10067+ clear pending_exact explicitly. */
10068+ pending_exact = 0;
10069+ break;
10070+
10071+
10072+ case ')':
10073+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
10074+
10075+ if (COMPILE_STACK_EMPTY)
10076+ {
10077+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
10078+ goto normal_backslash;
10079+ else
10080+ FREE_STACK_RETURN (REG_ERPAREN);
10081+ }
10082+
10083+ handle_close:
10084+ if (fixup_alt_jump)
10085+ { /* Push a dummy failure point at the end of the
10086+ alternative for a possible future
10087+ `pop_failure_jump' to pop. See comments at
10088+ `push_dummy_failure' in `re_match_2'. */
10089+ BUF_PUSH (push_dummy_failure);
10090+
10091+ /* We allocated space for this jump when we assigned
10092+ to `fixup_alt_jump', in the `handle_alt' case below. */
10093+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
10094+ }
10095+
10096+ /* See similar code for backslashed left paren above. */
10097+ if (COMPILE_STACK_EMPTY)
10098+ {
10099+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
10100+ goto normal_char;
10101+ else
10102+ FREE_STACK_RETURN (REG_ERPAREN);
10103+ }
10104+
10105+ /* Since we just checked for an empty stack above, this
10106+ ``can't happen''. */
10107+ assert (compile_stack.avail != 0);
10108+ {
10109+ /* We don't just want to restore into `regnum', because
10110+ later groups should continue to be numbered higher,
10111+ as in `(ab)c(de)' -- the second group is #2. */
10112+ regnum_t this_group_regnum;
10113+
10114+ compile_stack.avail--;
10115+ begalt = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.begalt_offset;
10116+ fixup_alt_jump
10117+ = COMPILE_STACK_TOP.fixup_alt_jump
10118+ ? COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.fixup_alt_jump - 1
10119+ : 0;
10120+ laststart = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.laststart_offset;
10121+ this_group_regnum = COMPILE_STACK_TOP.regnum;
10122+ /* If we've reached MAX_REGNUM groups, then this open
10123+ won't actually generate any code, so we'll have to
10124+ clear pending_exact explicitly. */
10125+ pending_exact = 0;
10126+
10127+ /* We're at the end of the group, so now we know how many
10128+ groups were inside this one. */
10129+ if (this_group_regnum <= MAX_REGNUM)
10130+ {
10131+ UCHAR_T *inner_group_loc
10132+ = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.inner_group_offset;
10133+
10134+ *inner_group_loc = regnum - this_group_regnum;
10135+ BUF_PUSH_3 (stop_memory, this_group_regnum,
10136+ regnum - this_group_regnum);
10137+ }
10138+ }
10139+ break;
10140+
10141+
10142+ case '|': /* `\|'. */
10143+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
10144+ goto normal_backslash;
10145+ handle_alt:
10146+ if (syntax & RE_LIMITED_OPS)
10147+ goto normal_char;
10148+
10149+ /* Insert before the previous alternative a jump which
10150+ jumps to this alternative if the former fails. */
10151+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
10152+ INSERT_JUMP (on_failure_jump, begalt,
10153+ b + 2 + 2 * OFFSET_ADDRESS_SIZE);
10154+ pending_exact = 0;
10155+ b += 1 + OFFSET_ADDRESS_SIZE;
10156+
10157+ /* The alternative before this one has a jump after it
10158+ which gets executed if it gets matched. Adjust that
10159+ jump so it will jump to this alternative's analogous
10160+ jump (put in below, which in turn will jump to the next
10161+ (if any) alternative's such jump, etc.). The last such
10162+ jump jumps to the correct final destination. A picture:
10163+ _____ _____
10164+ | | | |
10165+ | v | v
10166+ a | b | c
10167+
10168+ If we are at `b', then fixup_alt_jump right now points to a
10169+ three-byte space after `a'. We'll put in the jump, set
10170+ fixup_alt_jump to right after `b', and leave behind three
10171+ bytes which we'll fill in when we get to after `c'. */
10172+
10173+ if (fixup_alt_jump)
10174+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
10175+
10176+ /* Mark and leave space for a jump after this alternative,
10177+ to be filled in later either by next alternative or
10178+ when know we're at the end of a series of alternatives. */
10179+ fixup_alt_jump = b;
10180+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
10181+ b += 1 + OFFSET_ADDRESS_SIZE;
10182+
10183+ laststart = 0;
10184+ begalt = b;
10185+ break;
10186+
10187+
10188+ case '{':
10189+ /* If \{ is a literal. */
10190+ if (!(syntax & RE_INTERVALS)
10191+ /* If we're at `\{' and it's not the open-interval
10192+ operator. */
10193+ || (syntax & RE_NO_BK_BRACES))
10194+ goto normal_backslash;
10195+
10196+ handle_interval:
10197+ {
10198+ /* If got here, then the syntax allows intervals. */
10199+
10200+ /* At least (most) this many matches must be made. */
10201+ int lower_bound = -1, upper_bound = -1;
10202+
10203+ /* Place in the uncompiled pattern (i.e., just after
10204+ the '{') to go back to if the interval is invalid. */
10205+ const CHAR_T *beg_interval = p;
10206+
10207+ if (p == pend)
10208+ goto invalid_interval;
10209+
10210+ GET_UNSIGNED_NUMBER (lower_bound);
10211+
10212+ if (c == ',')
10213+ {
10214+ GET_UNSIGNED_NUMBER (upper_bound);
10215+ if (upper_bound < 0)
10216+ upper_bound = RE_DUP_MAX;
10217+ }
10218+ else
10219+ /* Interval such as `{1}' => match exactly once. */
10220+ upper_bound = lower_bound;
10221+
10222+ if (! (0 <= lower_bound && lower_bound <= upper_bound))
10223+ goto invalid_interval;
10224+
10225+ if (!(syntax & RE_NO_BK_BRACES))
10226+ {
10227+ if (c != '\\' || p == pend)
10228+ goto invalid_interval;
10229+ PATFETCH (c);
10230+ }
10231+
10232+ if (c != '}')
10233+ goto invalid_interval;
10234+
10235+ /* If it's invalid to have no preceding re. */
10236+ if (!laststart)
10237+ {
10238+ if (syntax & RE_CONTEXT_INVALID_OPS
10239+ && !(syntax & RE_INVALID_INTERVAL_ORD))
10240+ FREE_STACK_RETURN (REG_BADRPT);
10241+ else if (syntax & RE_CONTEXT_INDEP_OPS)
10242+ laststart = b;
10243+ else
10244+ goto unfetch_interval;
10245+ }
10246+
10247+ /* We just parsed a valid interval. */
10248+
10249+ if (RE_DUP_MAX < upper_bound)
10250+ FREE_STACK_RETURN (REG_BADBR);
10251+
10252+ /* If the upper bound is zero, don't want to succeed at
10253+ all; jump from `laststart' to `b + 3', which will be
10254+ the end of the buffer after we insert the jump. */
10255+ /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE'
10256+ instead of 'b + 3'. */
10257+ if (upper_bound == 0)
10258+ {
10259+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
10260+ INSERT_JUMP (jump, laststart, b + 1
10261+ + OFFSET_ADDRESS_SIZE);
10262+ b += 1 + OFFSET_ADDRESS_SIZE;
10263+ }
10264+
10265+ /* Otherwise, we have a nontrivial interval. When
10266+ we're all done, the pattern will look like:
10267+ set_number_at <jump count> <upper bound>
10268+ set_number_at <succeed_n count> <lower bound>
10269+ succeed_n <after jump addr> <succeed_n count>
10270+ <body of loop>
10271+ jump_n <succeed_n addr> <jump count>
10272+ (The upper bound and `jump_n' are omitted if
10273+ `upper_bound' is 1, though.) */
10274+ else
10275+ { /* If the upper bound is > 1, we need to insert
10276+ more at the end of the loop. */
10277+ unsigned nbytes = 2 + 4 * OFFSET_ADDRESS_SIZE +
10278+ (upper_bound > 1) * (2 + 4 * OFFSET_ADDRESS_SIZE);
10279+
10280+ GET_BUFFER_SPACE (nbytes);
10281+
10282+ /* Initialize lower bound of the `succeed_n', even
10283+ though it will be set during matching by its
10284+ attendant `set_number_at' (inserted next),
10285+ because `re_compile_fastmap' needs to know.
10286+ Jump to the `jump_n' we might insert below. */
10287+ INSERT_JUMP2 (succeed_n, laststart,
10288+ b + 1 + 2 * OFFSET_ADDRESS_SIZE
10289+ + (upper_bound > 1) * (1 + 2 * OFFSET_ADDRESS_SIZE)
10290+ , lower_bound);
10291+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
10292+
10293+ /* Code to initialize the lower bound. Insert
10294+ before the `succeed_n'. The `5' is the last two
10295+ bytes of this `set_number_at', plus 3 bytes of
10296+ the following `succeed_n'. */
10297+ /* ifdef WCHAR, The '1+2*OFFSET_ADDRESS_SIZE'
10298+ is the 'set_number_at', plus '1+OFFSET_ADDRESS_SIZE'
10299+ of the following `succeed_n'. */
10300+ PREFIX(insert_op2) (set_number_at, laststart, 1
10301+ + 2 * OFFSET_ADDRESS_SIZE, lower_bound, b);
10302+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
10303+
10304+ if (upper_bound > 1)
10305+ { /* More than one repetition is allowed, so
10306+ append a backward jump to the `succeed_n'
10307+ that starts this interval.
10308+
10309+ When we've reached this during matching,
10310+ we'll have matched the interval once, so
10311+ jump back only `upper_bound - 1' times. */
10312+ STORE_JUMP2 (jump_n, b, laststart
10313+ + 2 * OFFSET_ADDRESS_SIZE + 1,
10314+ upper_bound - 1);
10315+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
10316+
10317+ /* The location we want to set is the second
10318+ parameter of the `jump_n'; that is `b-2' as
10319+ an absolute address. `laststart' will be
10320+ the `set_number_at' we're about to insert;
10321+ `laststart+3' the number to set, the source
10322+ for the relative address. But we are
10323+ inserting into the middle of the pattern --
10324+ so everything is getting moved up by 5.
10325+ Conclusion: (b - 2) - (laststart + 3) + 5,
10326+ i.e., b - laststart.
10327+
10328+ We insert this at the beginning of the loop
10329+ so that if we fail during matching, we'll
10330+ reinitialize the bounds. */
10331+ PREFIX(insert_op2) (set_number_at, laststart,
10332+ b - laststart,
10333+ upper_bound - 1, b);
10334+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
10335+ }
10336+ }
10337+ pending_exact = 0;
10338+ break;
10339+
10340+ invalid_interval:
10341+ if (!(syntax & RE_INVALID_INTERVAL_ORD))
10342+ FREE_STACK_RETURN (p == pend ? REG_EBRACE : REG_BADBR);
10343+ unfetch_interval:
10344+ /* Match the characters as literals. */
10345+ p = beg_interval;
10346+ c = '{';
10347+ if (syntax & RE_NO_BK_BRACES)
10348+ goto normal_char;
10349+ else
10350+ goto normal_backslash;
10351+ }
10352+
10353+#ifdef emacs
10354+ /* There is no way to specify the before_dot and after_dot
10355+ operators. rms says this is ok. --karl */
10356+ case '=':
10357+ BUF_PUSH (at_dot);
10358+ break;
10359+
10360+ case 's':
10361+ laststart = b;
10362+ PATFETCH (c);
10363+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
10364+ break;
10365+
10366+ case 'S':
10367+ laststart = b;
10368+ PATFETCH (c);
10369+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
10370+ break;
10371+#endif /* emacs */
10372+
10373+
10374+ case 'w':
10375+ if (syntax & RE_NO_GNU_OPS)
10376+ goto normal_char;
10377+ laststart = b;
10378+ BUF_PUSH (wordchar);
10379+ break;
10380+
10381+
10382+ case 'W':
10383+ if (syntax & RE_NO_GNU_OPS)
10384+ goto normal_char;
10385+ laststart = b;
10386+ BUF_PUSH (notwordchar);
10387+ break;
10388+
10389+
10390+ case '<':
10391+ if (syntax & RE_NO_GNU_OPS)
10392+ goto normal_char;
10393+ BUF_PUSH (wordbeg);
10394+ break;
10395+
10396+ case '>':
10397+ if (syntax & RE_NO_GNU_OPS)
10398+ goto normal_char;
10399+ BUF_PUSH (wordend);
10400+ break;
10401+
10402+ case 'b':
10403+ if (syntax & RE_NO_GNU_OPS)
10404+ goto normal_char;
10405+ BUF_PUSH (wordbound);
10406+ break;
10407+
10408+ case 'B':
10409+ if (syntax & RE_NO_GNU_OPS)
10410+ goto normal_char;
10411+ BUF_PUSH (notwordbound);
10412+ break;
10413+
10414+ case '`':
10415+ if (syntax & RE_NO_GNU_OPS)
10416+ goto normal_char;
10417+ BUF_PUSH (begbuf);
10418+ break;
10419+
10420+ case '\'':
10421+ if (syntax & RE_NO_GNU_OPS)
10422+ goto normal_char;
10423+ BUF_PUSH (endbuf);
10424+ break;
10425+
10426+ case '1': case '2': case '3': case '4': case '5':
10427+ case '6': case '7': case '8': case '9':
10428+ if (syntax & RE_NO_BK_REFS)
10429+ goto normal_char;
10430+
10431+ c1 = c - '0';
10432+
10433+ if (c1 > regnum)
10434+ FREE_STACK_RETURN (REG_ESUBREG);
10435+
10436+ /* Can't back reference to a subexpression if inside of it. */
10437+ if (group_in_compile_stack (compile_stack, (regnum_t) c1))
10438+ goto normal_char;
10439+
10440+ laststart = b;
10441+ BUF_PUSH_2 (duplicate, c1);
10442+ break;
10443+
10444+
10445+ case '+':
10446+ case '?':
10447+ if (syntax & RE_BK_PLUS_QM)
10448+ goto handle_plus;
10449+ else
10450+ goto normal_backslash;
10451+
10452+ default:
10453+ normal_backslash:
10454+ /* You might think it would be useful for \ to mean
10455+ not to translate; but if we don't translate it
10456+ it will never match anything. */
10457+ c = TRANSLATE (c);
10458+ goto normal_char;
10459+ }
10460+ break;
10461+
10462+
10463+ default:
10464+ /* Expects the character in `c'. */
10465+ normal_char:
10466+ /* If no exactn currently being built. */
10467+ if (!pending_exact
10468+#ifdef WCHAR
10469+ /* If last exactn handle binary(or character) and
10470+ new exactn handle character(or binary). */
10471+ || is_exactn_bin != is_binary[p - 1 - pattern]
10472+#endif /* WCHAR */
10473+
10474+ /* If last exactn not at current position. */
10475+ || pending_exact + *pending_exact + 1 != b
10476+
10477+ /* We have only one byte following the exactn for the count. */
10478+ || *pending_exact == (1 << BYTEWIDTH) - 1
10479+
10480+ /* If followed by a repetition operator. */
10481+ || *p == '*' || *p == '^'
10482+ || ((syntax & RE_BK_PLUS_QM)
10483+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
10484+ : (*p == '+' || *p == '?'))
10485+ || ((syntax & RE_INTERVALS)
10486+ && ((syntax & RE_NO_BK_BRACES)
10487+ ? *p == '{'
10488+ : (p[0] == '\\' && p[1] == '{'))))
10489+ {
10490+ /* Start building a new exactn. */
10491+
10492+ laststart = b;
10493+
10494+#ifdef WCHAR
10495+ /* Is this exactn binary data or character? */
10496+ is_exactn_bin = is_binary[p - 1 - pattern];
10497+ if (is_exactn_bin)
10498+ BUF_PUSH_2 (exactn_bin, 0);
10499+ else
10500+ BUF_PUSH_2 (exactn, 0);
10501+#else
10502+ BUF_PUSH_2 (exactn, 0);
10503+#endif /* WCHAR */
10504+ pending_exact = b - 1;
10505+ }
10506+
10507+ BUF_PUSH (c);
10508+ (*pending_exact)++;
10509+ break;
10510+ } /* switch (c) */
10511+ } /* while p != pend */
10512+
10513+
10514+ /* Through the pattern now. */
10515+
10516+ if (fixup_alt_jump)
10517+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
10518+
10519+ if (!COMPILE_STACK_EMPTY)
10520+ FREE_STACK_RETURN (REG_EPAREN);
10521+
10522+ /* If we don't want backtracking, force success
10523+ the first time we reach the end of the compiled pattern. */
10524+ if (syntax & RE_NO_POSIX_BACKTRACKING)
10525+ BUF_PUSH (succeed);
10526+
10527+#ifdef WCHAR
10528+ free (pattern);
10529+ free (mbs_offset);
10530+ free (is_binary);
10531+#endif
10532+ free (compile_stack.stack);
10533+
10534+ /* We have succeeded; set the length of the buffer. */
10535+#ifdef WCHAR
10536+ bufp->used = (uintptr_t) b - (uintptr_t) COMPILED_BUFFER_VAR;
10537+#else
10538+ bufp->used = b - bufp->buffer;
10539+#endif
10540+
10541+#ifdef DEBUG
10542+ if (debug)
10543+ {
10544+ DEBUG_PRINT1 ("\nCompiled pattern: \n");
10545+ PREFIX(print_compiled_pattern) (bufp);
10546+ }
10547+#endif /* DEBUG */
10548+
10549+#ifndef MATCH_MAY_ALLOCATE
10550+ /* Initialize the failure stack to the largest possible stack. This
10551+ isn't necessary unless we're trying to avoid calling alloca in
10552+ the search and match routines. */
10553+ {
10554+ int num_regs = bufp->re_nsub + 1;
10555+
10556+ /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
10557+ is strictly greater than re_max_failures, the largest possible stack
10558+ is 2 * re_max_failures failure points. */
10559+ if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
10560+ {
10561+ fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
10562+
10563+# ifdef emacs
10564+ if (! fail_stack.stack)
10565+ fail_stack.stack
10566+ = (PREFIX(fail_stack_elt_t) *) xmalloc (fail_stack.size
10567+ * sizeof (PREFIX(fail_stack_elt_t)));
10568+ else
10569+ fail_stack.stack
10570+ = (PREFIX(fail_stack_elt_t) *) xrealloc (fail_stack.stack,
10571+ (fail_stack.size
10572+ * sizeof (PREFIX(fail_stack_elt_t))));
10573+# else /* not emacs */
10574+ if (! fail_stack.stack)
10575+ fail_stack.stack
10576+ = (PREFIX(fail_stack_elt_t) *) malloc (fail_stack.size
10577+ * sizeof (PREFIX(fail_stack_elt_t)));
10578+ else
10579+ fail_stack.stack
10580+ = (PREFIX(fail_stack_elt_t) *) realloc (fail_stack.stack,
10581+ (fail_stack.size
10582+ * sizeof (PREFIX(fail_stack_elt_t))));
10583+# endif /* not emacs */
10584+ }
10585+
10586+ PREFIX(regex_grow_registers) (num_regs);
10587+ }
10588+#endif /* not MATCH_MAY_ALLOCATE */
10589+
10590+ return REG_NOERROR;
10591+} /* regex_compile */
10592+
10593+/* Subroutines for `regex_compile'. */
10594+
10595+/* Store OP at LOC followed by two-byte integer parameter ARG. */
10596+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
10597+
10598+static void
10599+PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg)
10600+{
10601+ *loc = (UCHAR_T) op;
10602+ STORE_NUMBER (loc + 1, arg);
10603+}
10604+
10605+
10606+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
10607+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
10608+
10609+static void
10610+PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, int arg2)
10611+{
10612+ *loc = (UCHAR_T) op;
10613+ STORE_NUMBER (loc + 1, arg1);
10614+ STORE_NUMBER (loc + 1 + OFFSET_ADDRESS_SIZE, arg2);
10615+}
10616+
10617+
10618+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
10619+ for OP followed by two-byte integer parameter ARG. */
10620+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
10621+
10622+static void
10623+PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, int arg, UCHAR_T *end)
10624+{
10625+ register UCHAR_T *pfrom = end;
10626+ register UCHAR_T *pto = end + 1 + OFFSET_ADDRESS_SIZE;
10627+
10628+ while (pfrom != loc)
10629+ *--pto = *--pfrom;
10630+
10631+ PREFIX(store_op1) (op, loc, arg);
10632+}
10633+
10634+
10635+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
10636+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
10637+
10638+static void
10639+PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, int arg1,
10640+ int arg2, UCHAR_T *end)
10641+{
10642+ register UCHAR_T *pfrom = end;
10643+ register UCHAR_T *pto = end + 1 + 2 * OFFSET_ADDRESS_SIZE;
10644+
10645+ while (pfrom != loc)
10646+ *--pto = *--pfrom;
10647+
10648+ PREFIX(store_op2) (op, loc, arg1, arg2);
10649+}
10650+
10651+
10652+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
10653+ after an alternative or a begin-subexpression. We assume there is at
10654+ least one character before the ^. */
10655+
10656+static boolean
10657+PREFIX(at_begline_loc_p) (const CHAR_T *pattern, const CHAR_T *p,
10658+ reg_syntax_t syntax)
10659+{
10660+ const CHAR_T *prev = p - 2;
10661+ boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
10662+
10663+ return
10664+ /* After a subexpression? */
10665+ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
10666+ /* After an alternative? */
10667+ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
10668+}
10669+
10670+
10671+/* The dual of at_begline_loc_p. This one is for $. We assume there is
10672+ at least one character after the $, i.e., `P < PEND'. */
10673+
10674+static boolean
10675+PREFIX(at_endline_loc_p) (const CHAR_T *p, const CHAR_T *pend,
10676+ reg_syntax_t syntax)
10677+{
10678+ const CHAR_T *next = p;
10679+ boolean next_backslash = *next == '\\';
10680+ const CHAR_T *next_next = p + 1 < pend ? p + 1 : 0;
10681+
10682+ return
10683+ /* Before a subexpression? */
10684+ (syntax & RE_NO_BK_PARENS ? *next == ')'
10685+ : next_backslash && next_next && *next_next == ')')
10686+ /* Before an alternative? */
10687+ || (syntax & RE_NO_BK_VBAR ? *next == '|'
10688+ : next_backslash && next_next && *next_next == '|');
10689+}
10690+
10691+#else /* not INSIDE_RECURSION */
10692+
10693+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
10694+ false if it's not. */
10695+
10696+static boolean
10697+group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum)
10698+{
10699+ int this_element;
10700+
10701+ for (this_element = compile_stack.avail - 1;
10702+ this_element >= 0;
10703+ this_element--)
10704+ if (compile_stack.stack[this_element].regnum == regnum)
10705+ return true;
10706+
10707+ return false;
10708+}
10709+#endif /* not INSIDE_RECURSION */
10710+
10711+#ifdef INSIDE_RECURSION
10712+
10713+#ifdef WCHAR
10714+/* This insert space, which size is "num", into the pattern at "loc".
10715+ "end" must point the end of the allocated buffer. */
10716+static void
10717+insert_space (int num, CHAR_T *loc, CHAR_T *end)
10718+{
10719+ register CHAR_T *pto = end;
10720+ register CHAR_T *pfrom = end - num;
10721+
10722+ while (pfrom >= loc)
10723+ *pto-- = *pfrom--;
10724+}
10725+#endif /* WCHAR */
10726+
10727+#ifdef WCHAR
10728+static reg_errcode_t
10729+wcs_compile_range (CHAR_T range_start_char, const CHAR_T **p_ptr,
10730+ const CHAR_T *pend, RE_TRANSLATE_TYPE translate,
10731+ reg_syntax_t syntax, CHAR_T *b, CHAR_T *char_set)
10732+{
10733+ const CHAR_T *p = *p_ptr;
10734+ CHAR_T range_start, range_end;
10735+ reg_errcode_t ret;
10736+# ifdef _LIBC
10737+ uint32_t nrules;
10738+ uint32_t start_val, end_val;
10739+# endif
10740+ if (p == pend)
10741+ return REG_ERANGE;
10742+
10743+# ifdef _LIBC
10744+ nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
10745+ if (nrules != 0)
10746+ {
10747+ const char *collseq = (const char *) _NL_CURRENT(LC_COLLATE,
10748+ _NL_COLLATE_COLLSEQWC);
10749+ const unsigned char *extra = (const unsigned char *)
10750+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
10751+
10752+ if (range_start_char < -1)
10753+ {
10754+ /* range_start is a collating symbol. */
10755+ int32_t *wextra;
10756+ /* Retreive the index and get collation sequence value. */
10757+ wextra = (int32_t*)(extra + char_set[-range_start_char]);
10758+ start_val = wextra[1 + *wextra];
10759+ }
10760+ else
10761+ start_val = collseq_table_lookup(collseq, TRANSLATE(range_start_char));
10762+
10763+ end_val = collseq_table_lookup (collseq, TRANSLATE (p[0]));
10764+
10765+ /* Report an error if the range is empty and the syntax prohibits
10766+ this. */
10767+ ret = ((syntax & RE_NO_EMPTY_RANGES)
10768+ && (start_val > end_val))? REG_ERANGE : REG_NOERROR;
10769+
10770+ /* Insert space to the end of the char_ranges. */
10771+ insert_space(2, b - char_set[5] - 2, b - 1);
10772+ *(b - char_set[5] - 2) = (wchar_t)start_val;
10773+ *(b - char_set[5] - 1) = (wchar_t)end_val;
10774+ char_set[4]++; /* ranges_index */
10775+ }
10776+ else
10777+# endif
10778+ {
10779+ range_start = (range_start_char >= 0)? TRANSLATE (range_start_char):
10780+ range_start_char;
10781+ range_end = TRANSLATE (p[0]);
10782+ /* Report an error if the range is empty and the syntax prohibits
10783+ this. */
10784+ ret = ((syntax & RE_NO_EMPTY_RANGES)
10785+ && (range_start > range_end))? REG_ERANGE : REG_NOERROR;
10786+
10787+ /* Insert space to the end of the char_ranges. */
10788+ insert_space(2, b - char_set[5] - 2, b - 1);
10789+ *(b - char_set[5] - 2) = range_start;
10790+ *(b - char_set[5] - 1) = range_end;
10791+ char_set[4]++; /* ranges_index */
10792+ }
10793+ /* Have to increment the pointer into the pattern string, so the
10794+ caller isn't still at the ending character. */
10795+ (*p_ptr)++;
10796+
10797+ return ret;
10798+}
10799+#else /* BYTE */
10800+/* Read the ending character of a range (in a bracket expression) from the
10801+ uncompiled pattern *P_PTR (which ends at PEND). We assume the
10802+ starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
10803+ Then we set the translation of all bits between the starting and
10804+ ending characters (inclusive) in the compiled pattern B.
10805+
10806+ Return an error code.
10807+
10808+ We use these short variable names so we can use the same macros as
10809+ `regex_compile' itself. */
10810+
10811+static reg_errcode_t
10812+byte_compile_range (unsigned int range_start_char, const char **p_ptr,
10813+ const char *pend, RE_TRANSLATE_TYPE translate,
10814+ reg_syntax_t syntax, unsigned char *b)
10815+{
10816+ unsigned this_char;
10817+ const char *p = *p_ptr;
10818+ reg_errcode_t ret;
10819+# if _LIBC
10820+ const unsigned char *collseq;
10821+ unsigned int start_colseq;
10822+ unsigned int end_colseq;
10823+# else
10824+ unsigned end_char;
10825+# endif
10826+
10827+ if (p == pend)
10828+ return REG_ERANGE;
10829+
10830+ /* Have to increment the pointer into the pattern string, so the
10831+ caller isn't still at the ending character. */
10832+ (*p_ptr)++;
10833+
10834+ /* Report an error if the range is empty and the syntax prohibits this. */
10835+ ret = syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
10836+
10837+# if _LIBC
10838+ collseq = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
10839+ _NL_COLLATE_COLLSEQMB);
10840+
10841+ start_colseq = collseq[(unsigned char) TRANSLATE (range_start_char)];
10842+ end_colseq = collseq[(unsigned char) TRANSLATE (p[0])];
10843+ for (this_char = 0; this_char <= (unsigned char) -1; ++this_char)
10844+ {
10845+ unsigned int this_colseq = collseq[(unsigned char) TRANSLATE (this_char)];
10846+
10847+ if (start_colseq <= this_colseq && this_colseq <= end_colseq)
10848+ {
10849+ SET_LIST_BIT (TRANSLATE (this_char));
10850+ ret = REG_NOERROR;
10851+ }
10852+ }
10853+# else
10854+ /* Here we see why `this_char' has to be larger than an `unsigned
10855+ char' -- we would otherwise go into an infinite loop, since all
10856+ characters <= 0xff. */
10857+ range_start_char = TRANSLATE (range_start_char);
10858+ /* TRANSLATE(p[0]) is casted to char (not unsigned char) in TRANSLATE,
10859+ and some compilers cast it to int implicitly, so following for_loop
10860+ may fall to (almost) infinite loop.
10861+ e.g. If translate[p[0]] = 0xff, end_char may equals to 0xffffffff.
10862+ To avoid this, we cast p[0] to unsigned int and truncate it. */
10863+ end_char = ((unsigned)TRANSLATE(p[0]) & ((1 << BYTEWIDTH) - 1));
10864+
10865+ for (this_char = range_start_char; this_char <= end_char; ++this_char)
10866+ {
10867+ SET_LIST_BIT (TRANSLATE (this_char));
10868+ ret = REG_NOERROR;
10869+ }
10870+# endif
10871+
10872+ return ret;
10873+}
10874+#endif /* WCHAR */
10875+
10876+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
10877+ BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
10878+ characters can start a string that matches the pattern. This fastmap
10879+ is used by re_search to skip quickly over impossible starting points.
10880+
10881+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
10882+ area as BUFP->fastmap.
10883+
10884+ We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
10885+ the pattern buffer.
10886+
10887+ Returns 0 if we succeed, -2 if an internal error. */
10888+
10889+#ifdef WCHAR
10890+/* local function for re_compile_fastmap.
10891+ truncate wchar_t character to char. */
10892+static unsigned char truncate_wchar (CHAR_T c);
10893+
10894+static unsigned char
10895+truncate_wchar (CHAR_T c)
10896+{
10897+ unsigned char buf[MB_CUR_MAX];
10898+ mbstate_t state;
10899+ int retval;
10900+ memset (&state, '\0', sizeof (state));
10901+# ifdef _LIBC
10902+ retval = __wcrtomb (buf, c, &state);
10903+# else
10904+ retval = wcrtomb (buf, c, &state);
10905+# endif
10906+ return retval > 0 ? buf[0] : (unsigned char) c;
10907+}
10908+#endif /* WCHAR */
10909+
10910+static int
10911+PREFIX(re_compile_fastmap) (struct re_pattern_buffer *bufp)
10912+{
10913+ int j, k;
10914+#ifdef MATCH_MAY_ALLOCATE
10915+ PREFIX(fail_stack_type) fail_stack;
10916+#endif
10917+#ifndef REGEX_MALLOC
10918+ char *destination;
10919+#endif
10920+
10921+ register char *fastmap = bufp->fastmap;
10922+
10923+#ifdef WCHAR
10924+ /* We need to cast pattern to (wchar_t*), because we casted this compiled
10925+ pattern to (char*) in regex_compile. */
10926+ UCHAR_T *pattern = (UCHAR_T*)bufp->buffer;
10927+ register UCHAR_T *pend = (UCHAR_T*) (bufp->buffer + bufp->used);
10928+#else /* BYTE */
10929+ UCHAR_T *pattern = bufp->buffer;
10930+ register UCHAR_T *pend = pattern + bufp->used;
10931+#endif /* WCHAR */
10932+ UCHAR_T *p = pattern;
10933+
10934+#ifdef REL_ALLOC
10935+ /* This holds the pointer to the failure stack, when
10936+ it is allocated relocatably. */
10937+ fail_stack_elt_t *failure_stack_ptr;
10938+#endif
10939+
10940+ /* Assume that each path through the pattern can be null until
10941+ proven otherwise. We set this false at the bottom of switch
10942+ statement, to which we get only if a particular path doesn't
10943+ match the empty string. */
10944+ boolean path_can_be_null = true;
10945+
10946+ /* We aren't doing a `succeed_n' to begin with. */
10947+ boolean succeed_n_p = false;
10948+
10949+ assert (fastmap != NULL && p != NULL);
10950+
10951+ INIT_FAIL_STACK ();
10952+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
10953+ bufp->fastmap_accurate = 1; /* It will be when we're done. */
10954+ bufp->can_be_null = 0;
10955+
10956+ while (1)
10957+ {
10958+ if (p == pend || *p == (UCHAR_T) succeed)
10959+ {
10960+ /* We have reached the (effective) end of pattern. */
10961+ if (!FAIL_STACK_EMPTY ())
10962+ {
10963+ bufp->can_be_null |= path_can_be_null;
10964+
10965+ /* Reset for next path. */
10966+ path_can_be_null = true;
10967+
10968+ p = fail_stack.stack[--fail_stack.avail].pointer;
10969+
10970+ continue;
10971+ }
10972+ else
10973+ break;
10974+ }
10975+
10976+ /* We should never be about to go beyond the end of the pattern. */
10977+ assert (p < pend);
10978+
10979+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
10980+ {
10981+
10982+ /* I guess the idea here is to simply not bother with a fastmap
10983+ if a backreference is used, since it's too hard to figure out
10984+ the fastmap for the corresponding group. Setting
10985+ `can_be_null' stops `re_search_2' from using the fastmap, so
10986+ that is all we do. */
10987+ case duplicate:
10988+ bufp->can_be_null = 1;
10989+ goto done;
10990+
10991+
10992+ /* Following are the cases which match a character. These end
10993+ with `break'. */
10994+
10995+#ifdef WCHAR
10996+ case exactn:
10997+ fastmap[truncate_wchar(p[1])] = 1;
10998+ break;
10999+#else /* BYTE */
11000+ case exactn:
11001+ fastmap[p[1]] = 1;
11002+ break;
11003+#endif /* WCHAR */
11004+#ifdef MBS_SUPPORT
11005+ case exactn_bin:
11006+ fastmap[p[1]] = 1;
11007+ break;
11008+#endif
11009+
11010+#ifdef WCHAR
11011+ /* It is hard to distinguish fastmap from (multi byte) characters
11012+ which depends on current locale. */
11013+ case charset:
11014+ case charset_not:
11015+ case wordchar:
11016+ case notwordchar:
11017+ bufp->can_be_null = 1;
11018+ goto done;
11019+#else /* BYTE */
11020+ case charset:
11021+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
11022+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
11023+ fastmap[j] = 1;
11024+ break;
11025+
11026+
11027+ case charset_not:
11028+ /* Chars beyond end of map must be allowed. */
11029+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
11030+ fastmap[j] = 1;
11031+
11032+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
11033+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
11034+ fastmap[j] = 1;
11035+ break;
11036+
11037+
11038+ case wordchar:
11039+ for (j = 0; j < (1 << BYTEWIDTH); j++)
11040+ if (SYNTAX (j) == Sword)
11041+ fastmap[j] = 1;
11042+ break;
11043+
11044+
11045+ case notwordchar:
11046+ for (j = 0; j < (1 << BYTEWIDTH); j++)
11047+ if (SYNTAX (j) != Sword)
11048+ fastmap[j] = 1;
11049+ break;
11050+#endif /* WCHAR */
11051+
11052+ case anychar:
11053+ {
11054+ int fastmap_newline = fastmap['\n'];
11055+
11056+ /* `.' matches anything ... */
11057+ for (j = 0; j < (1 << BYTEWIDTH); j++)
11058+ fastmap[j] = 1;
11059+
11060+ /* ... except perhaps newline. */
11061+ if (!(bufp->syntax & RE_DOT_NEWLINE))
11062+ fastmap['\n'] = fastmap_newline;
11063+
11064+ /* Return if we have already set `can_be_null'; if we have,
11065+ then the fastmap is irrelevant. Something's wrong here. */
11066+ else if (bufp->can_be_null)
11067+ goto done;
11068+
11069+ /* Otherwise, have to check alternative paths. */
11070+ break;
11071+ }
11072+
11073+#ifdef emacs
11074+ case syntaxspec:
11075+ k = *p++;
11076+ for (j = 0; j < (1 << BYTEWIDTH); j++)
11077+ if (SYNTAX (j) == (enum syntaxcode) k)
11078+ fastmap[j] = 1;
11079+ break;
11080+
11081+
11082+ case notsyntaxspec:
11083+ k = *p++;
11084+ for (j = 0; j < (1 << BYTEWIDTH); j++)
11085+ if (SYNTAX (j) != (enum syntaxcode) k)
11086+ fastmap[j] = 1;
11087+ break;
11088+
11089+
11090+ /* All cases after this match the empty string. These end with
11091+ `continue'. */
11092+
11093+
11094+ case before_dot:
11095+ case at_dot:
11096+ case after_dot:
11097+ continue;
11098+#endif /* emacs */
11099+
11100+
11101+ case no_op:
11102+ case begline:
11103+ case endline:
11104+ case begbuf:
11105+ case endbuf:
11106+ case wordbound:
11107+ case notwordbound:
11108+ case wordbeg:
11109+ case wordend:
11110+ case push_dummy_failure:
11111+ continue;
11112+
11113+
11114+ case jump_n:
11115+ case pop_failure_jump:
11116+ case maybe_pop_jump:
11117+ case jump:
11118+ case jump_past_alt:
11119+ case dummy_failure_jump:
11120+ EXTRACT_NUMBER_AND_INCR (j, p);
11121+ p += j;
11122+ if (j > 0)
11123+ continue;
11124+
11125+ /* Jump backward implies we just went through the body of a
11126+ loop and matched nothing. Opcode jumped to should be
11127+ `on_failure_jump' or `succeed_n'. Just treat it like an
11128+ ordinary jump. For a * loop, it has pushed its failure
11129+ point already; if so, discard that as redundant. */
11130+ if ((re_opcode_t) *p != on_failure_jump
11131+ && (re_opcode_t) *p != succeed_n)
11132+ continue;
11133+
11134+ p++;
11135+ EXTRACT_NUMBER_AND_INCR (j, p);
11136+ p += j;
11137+
11138+ /* If what's on the stack is where we are now, pop it. */
11139+ if (!FAIL_STACK_EMPTY ()
11140+ && fail_stack.stack[fail_stack.avail - 1].pointer == p)
11141+ fail_stack.avail--;
11142+
11143+ continue;
11144+
11145+
11146+ case on_failure_jump:
11147+ case on_failure_keep_string_jump:
11148+ handle_on_failure_jump:
11149+ EXTRACT_NUMBER_AND_INCR (j, p);
11150+
11151+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
11152+ end of the pattern. We don't want to push such a point,
11153+ since when we restore it above, entering the switch will
11154+ increment `p' past the end of the pattern. We don't need
11155+ to push such a point since we obviously won't find any more
11156+ fastmap entries beyond `pend'. Such a pattern can match
11157+ the null string, though. */
11158+ if (p + j < pend)
11159+ {
11160+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
11161+ {
11162+ RESET_FAIL_STACK ();
11163+ return -2;
11164+ }
11165+ }
11166+ else
11167+ bufp->can_be_null = 1;
11168+
11169+ if (succeed_n_p)
11170+ {
11171+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
11172+ succeed_n_p = false;
11173+ }
11174+
11175+ continue;
11176+
11177+
11178+ case succeed_n:
11179+ /* Get to the number of times to succeed. */
11180+ p += OFFSET_ADDRESS_SIZE;
11181+
11182+ /* Increment p past the n for when k != 0. */
11183+ EXTRACT_NUMBER_AND_INCR (k, p);
11184+ if (k == 0)
11185+ {
11186+ p -= 2 * OFFSET_ADDRESS_SIZE;
11187+ succeed_n_p = true; /* Spaghetti code alert. */
11188+ goto handle_on_failure_jump;
11189+ }
11190+ continue;
11191+
11192+
11193+ case set_number_at:
11194+ p += 2 * OFFSET_ADDRESS_SIZE;
11195+ continue;
11196+
11197+
11198+ case start_memory:
11199+ case stop_memory:
11200+ p += 2;
11201+ continue;
11202+
11203+
11204+ default:
11205+ abort (); /* We have listed all the cases. */
11206+ } /* switch *p++ */
11207+
11208+ /* Getting here means we have found the possible starting
11209+ characters for one path of the pattern -- and that the empty
11210+ string does not match. We need not follow this path further.
11211+ Instead, look at the next alternative (remembered on the
11212+ stack), or quit if no more. The test at the top of the loop
11213+ does these things. */
11214+ path_can_be_null = false;
11215+ p = pend;
11216+ } /* while p */
11217+
11218+ /* Set `can_be_null' for the last path (also the first path, if the
11219+ pattern is empty). */
11220+ bufp->can_be_null |= path_can_be_null;
11221+
11222+ done:
11223+ RESET_FAIL_STACK ();
11224+ return 0;
11225+}
11226+
11227+#else /* not INSIDE_RECURSION */
11228+
11229+int
11230+re_compile_fastmap (struct re_pattern_buffer *bufp)
11231+{
11232+# ifdef MBS_SUPPORT
11233+ if (MB_CUR_MAX != 1)
11234+ return wcs_re_compile_fastmap(bufp);
11235+ else
11236+# endif
11237+ return byte_re_compile_fastmap(bufp);
11238+} /* re_compile_fastmap */
11239+#ifdef _LIBC
11240+weak_alias (__re_compile_fastmap, re_compile_fastmap)
11241+#endif
11242+
11243+
11244+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
11245+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
11246+ this memory for recording register information. STARTS and ENDS
11247+ must be allocated using the malloc library routine, and must each
11248+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
11249+
11250+ If NUM_REGS == 0, then subsequent matches should allocate their own
11251+ register data.
11252+
11253+ Unless this function is called, the first search or match using
11254+ PATTERN_BUFFER will allocate its own register data, without
11255+ freeing the old data. */
11256+
11257+void
11258+re_set_registers (struct re_pattern_buffer *bufp,
11259+ struct re_registers *regs, unsigned num_regs,
11260+ regoff_t *starts, regoff_t *ends)
11261+{
11262+ if (num_regs)
11263+ {
11264+ bufp->regs_allocated = REGS_REALLOCATE;
11265+ regs->num_regs = num_regs;
11266+ regs->start = starts;
11267+ regs->end = ends;
11268+ }
11269+ else
11270+ {
11271+ bufp->regs_allocated = REGS_UNALLOCATED;
11272+ regs->num_regs = 0;
11273+ regs->start = regs->end = (regoff_t *) 0;
11274+ }
11275+}
11276+#ifdef _LIBC
11277+weak_alias (__re_set_registers, re_set_registers)
11278+#endif
11279+
11280+/* Searching routines. */
11281+
11282+/* Like re_search_2, below, but only one string is specified, and
11283+ doesn't let you say where to stop matching. */
11284+
11285+int
11286+re_search (struct re_pattern_buffer *bufp, const char *string, int size,
11287+ int startpos, int range, struct re_registers *regs)
11288+{
11289+ return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
11290+ regs, size);
11291+}
11292+#ifdef _LIBC
11293+weak_alias (__re_search, re_search)
11294+#endif
11295+
11296+
11297+/* Using the compiled pattern in BUFP->buffer, first tries to match the
11298+ virtual concatenation of STRING1 and STRING2, starting first at index
11299+ STARTPOS, then at STARTPOS + 1, and so on.
11300+
11301+ STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
11302+
11303+ RANGE is how far to scan while trying to match. RANGE = 0 means try
11304+ only at STARTPOS; in general, the last start tried is STARTPOS +
11305+ RANGE.
11306+
11307+ In REGS, return the indices of the virtual concatenation of STRING1
11308+ and STRING2 that matched the entire BUFP->buffer and its contained
11309+ subexpressions.
11310+
11311+ Do not consider matching one past the index STOP in the virtual
11312+ concatenation of STRING1 and STRING2.
11313+
11314+ We return either the position in the strings at which the match was
11315+ found, -1 if no match, or -2 if error (such as failure
11316+ stack overflow). */
11317+
11318+int
11319+re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
11320+ const char *string2, int size2, int startpos, int range,
11321+ struct re_registers *regs, int stop)
11322+{
11323+# ifdef MBS_SUPPORT
11324+ if (MB_CUR_MAX != 1)
11325+ return wcs_re_search_2 (bufp, string1, size1, string2, size2, startpos,
11326+ range, regs, stop);
11327+ else
11328+# endif
11329+ return byte_re_search_2 (bufp, string1, size1, string2, size2, startpos,
11330+ range, regs, stop);
11331+} /* re_search_2 */
11332+#ifdef _LIBC
11333+weak_alias (__re_search_2, re_search_2)
11334+#endif
11335+
11336+#endif /* not INSIDE_RECURSION */
11337+
11338+#ifdef INSIDE_RECURSION
11339+
11340+#ifdef MATCH_MAY_ALLOCATE
11341+# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL
11342+#else
11343+# define FREE_VAR(var) if (var) free (var); var = NULL
11344+#endif
11345+
11346+#ifdef WCHAR
11347+# define MAX_ALLOCA_SIZE 2000
11348+
11349+# define FREE_WCS_BUFFERS() \
11350+ do { \
11351+ if (size1 > MAX_ALLOCA_SIZE) \
11352+ { \
11353+ free (wcs_string1); \
11354+ free (mbs_offset1); \
11355+ } \
11356+ else \
11357+ { \
11358+ FREE_VAR (wcs_string1); \
11359+ FREE_VAR (mbs_offset1); \
11360+ } \
11361+ if (size2 > MAX_ALLOCA_SIZE) \
11362+ { \
11363+ free (wcs_string2); \
11364+ free (mbs_offset2); \
11365+ } \
11366+ else \
11367+ { \
11368+ FREE_VAR (wcs_string2); \
11369+ FREE_VAR (mbs_offset2); \
11370+ } \
11371+ } while (0)
11372+
11373+#endif
11374+
11375+
11376+static int
11377+PREFIX(re_search_2) (struct re_pattern_buffer *bufp, const char *string1,
11378+ int size1, const char *string2, int size2,
11379+ int startpos, int range,
11380+ struct re_registers *regs, int stop)
11381+{
11382+ int val;
11383+ register char *fastmap = bufp->fastmap;
11384+ register RE_TRANSLATE_TYPE translate = bufp->translate;
11385+ int total_size = size1 + size2;
11386+ int endpos = startpos + range;
11387+#ifdef WCHAR
11388+ /* We need wchar_t* buffers correspond to cstring1, cstring2. */
11389+ wchar_t *wcs_string1 = NULL, *wcs_string2 = NULL;
11390+ /* We need the size of wchar_t buffers correspond to csize1, csize2. */
11391+ int wcs_size1 = 0, wcs_size2 = 0;
11392+ /* offset buffer for optimizatoin. See convert_mbs_to_wc. */
11393+ int *mbs_offset1 = NULL, *mbs_offset2 = NULL;
11394+ /* They hold whether each wchar_t is binary data or not. */
11395+ char *is_binary = NULL;
11396+#endif /* WCHAR */
11397+
11398+ /* Check for out-of-range STARTPOS. */
11399+ if (startpos < 0 || startpos > total_size)
11400+ return -1;
11401+
11402+ /* Fix up RANGE if it might eventually take us outside
11403+ the virtual concatenation of STRING1 and STRING2.
11404+ Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */
11405+ if (endpos < 0)
11406+ range = 0 - startpos;
11407+ else if (endpos > total_size)
11408+ range = total_size - startpos;
11409+
11410+ /* If the search isn't to be a backwards one, don't waste time in a
11411+ search for a pattern that must be anchored. */
11412+ if (bufp->used > 0 && range > 0
11413+ && ((re_opcode_t) bufp->buffer[0] == begbuf
11414+ /* `begline' is like `begbuf' if it cannot match at newlines. */
11415+ || ((re_opcode_t) bufp->buffer[0] == begline
11416+ && !bufp->newline_anchor)))
11417+ {
11418+ if (startpos > 0)
11419+ return -1;
11420+ else
11421+ range = 1;
11422+ }
11423+
11424+#ifdef emacs
11425+ /* In a forward search for something that starts with \=.
11426+ don't keep searching past point. */
11427+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
11428+ {
11429+ range = PT - startpos;
11430+ if (range <= 0)
11431+ return -1;
11432+ }
11433+#endif /* emacs */
11434+
11435+ /* Update the fastmap now if not correct already. */
11436+ if (fastmap && !bufp->fastmap_accurate)
11437+ if (re_compile_fastmap (bufp) == -2)
11438+ return -2;
11439+
11440+#ifdef WCHAR
11441+ /* Allocate wchar_t array for wcs_string1 and wcs_string2 and
11442+ fill them with converted string. */
11443+ if (size1 != 0)
11444+ {
11445+ if (size1 > MAX_ALLOCA_SIZE)
11446+ {
11447+ wcs_string1 = TALLOC (size1 + 1, CHAR_T);
11448+ mbs_offset1 = TALLOC (size1 + 1, int);
11449+ is_binary = TALLOC (size1 + 1, char);
11450+ }
11451+ else
11452+ {
11453+ wcs_string1 = REGEX_TALLOC (size1 + 1, CHAR_T);
11454+ mbs_offset1 = REGEX_TALLOC (size1 + 1, int);
11455+ is_binary = REGEX_TALLOC (size1 + 1, char);
11456+ }
11457+ if (!wcs_string1 || !mbs_offset1 || !is_binary)
11458+ {
11459+ if (size1 > MAX_ALLOCA_SIZE)
11460+ {
11461+ free (wcs_string1);
11462+ free (mbs_offset1);
11463+ free (is_binary);
11464+ }
11465+ else
11466+ {
11467+ FREE_VAR (wcs_string1);
11468+ FREE_VAR (mbs_offset1);
11469+ FREE_VAR (is_binary);
11470+ }
11471+ return -2;
11472+ }
11473+ wcs_size1 = convert_mbs_to_wcs(wcs_string1, string1, size1,
11474+ mbs_offset1, is_binary);
11475+ wcs_string1[wcs_size1] = L'\0'; /* for a sentinel */
11476+ if (size1 > MAX_ALLOCA_SIZE)
11477+ free (is_binary);
11478+ else
11479+ FREE_VAR (is_binary);
11480+ }
11481+ if (size2 != 0)
11482+ {
11483+ if (size2 > MAX_ALLOCA_SIZE)
11484+ {
11485+ wcs_string2 = TALLOC (size2 + 1, CHAR_T);
11486+ mbs_offset2 = TALLOC (size2 + 1, int);
11487+ is_binary = TALLOC (size2 + 1, char);
11488+ }
11489+ else
11490+ {
11491+ wcs_string2 = REGEX_TALLOC (size2 + 1, CHAR_T);
11492+ mbs_offset2 = REGEX_TALLOC (size2 + 1, int);
11493+ is_binary = REGEX_TALLOC (size2 + 1, char);
11494+ }
11495+ if (!wcs_string2 || !mbs_offset2 || !is_binary)
11496+ {
11497+ FREE_WCS_BUFFERS ();
11498+ if (size2 > MAX_ALLOCA_SIZE)
11499+ free (is_binary);
11500+ else
11501+ FREE_VAR (is_binary);
11502+ return -2;
11503+ }
11504+ wcs_size2 = convert_mbs_to_wcs(wcs_string2, string2, size2,
11505+ mbs_offset2, is_binary);
11506+ wcs_string2[wcs_size2] = L'\0'; /* for a sentinel */
11507+ if (size2 > MAX_ALLOCA_SIZE)
11508+ free (is_binary);
11509+ else
11510+ FREE_VAR (is_binary);
11511+ }
11512+#endif /* WCHAR */
11513+
11514+
11515+ /* Loop through the string, looking for a place to start matching. */
11516+ for (;;)
11517+ {
11518+ /* If a fastmap is supplied, skip quickly over characters that
11519+ cannot be the start of a match. If the pattern can match the
11520+ null string, however, we don't need to skip characters; we want
11521+ the first null string. */
11522+ if (fastmap && startpos < total_size && !bufp->can_be_null)
11523+ {
11524+ if (range > 0) /* Searching forwards. */
11525+ {
11526+ register const char *d;
11527+ register int lim = 0;
11528+ int irange = range;
11529+
11530+ if (startpos < size1 && startpos + range >= size1)
11531+ lim = range - (size1 - startpos);
11532+
11533+ d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
11534+
11535+ /* Written out as an if-else to avoid testing `translate'
11536+ inside the loop. */
11537+ if (translate)
11538+ while (range > lim
11539+ && !fastmap[(unsigned char)
11540+ translate[(unsigned char) *d++]])
11541+ range--;
11542+ else
11543+ while (range > lim && !fastmap[(unsigned char) *d++])
11544+ range--;
11545+
11546+ startpos += irange - range;
11547+ }
11548+ else /* Searching backwards. */
11549+ {
11550+ register CHAR_T c = (size1 == 0 || startpos >= size1
11551+ ? string2[startpos - size1]
11552+ : string1[startpos]);
11553+
11554+ if (!fastmap[(unsigned char) TRANSLATE (c)])
11555+ goto advance;
11556+ }
11557+ }
11558+
11559+ /* If can't match the null string, and that's all we have left, fail. */
11560+ if (range >= 0 && startpos == total_size && fastmap
11561+ && !bufp->can_be_null)
11562+ {
11563+#ifdef WCHAR
11564+ FREE_WCS_BUFFERS ();
11565+#endif
11566+ return -1;
11567+ }
11568+
11569+#ifdef WCHAR
11570+ val = wcs_re_match_2_internal (bufp, string1, size1, string2,
11571+ size2, startpos, regs, stop,
11572+ wcs_string1, wcs_size1,
11573+ wcs_string2, wcs_size2,
11574+ mbs_offset1, mbs_offset2);
11575+#else /* BYTE */
11576+ val = byte_re_match_2_internal (bufp, string1, size1, string2,
11577+ size2, startpos, regs, stop);
11578+#endif /* BYTE */
11579+
11580+#ifndef REGEX_MALLOC
11581+# ifdef C_ALLOCA
11582+ alloca (0);
11583+# endif
11584+#endif
11585+
11586+ if (val >= 0)
11587+ {
11588+#ifdef WCHAR
11589+ FREE_WCS_BUFFERS ();
11590+#endif
11591+ return startpos;
11592+ }
11593+
11594+ if (val == -2)
11595+ {
11596+#ifdef WCHAR
11597+ FREE_WCS_BUFFERS ();
11598+#endif
11599+ return -2;
11600+ }
11601+
11602+ advance:
11603+ if (!range)
11604+ break;
11605+ else if (range > 0)
11606+ {
11607+ range--;
11608+ startpos++;
11609+ }
11610+ else
11611+ {
11612+ range++;
11613+ startpos--;
11614+ }
11615+ }
11616+#ifdef WCHAR
11617+ FREE_WCS_BUFFERS ();
11618+#endif
11619+ return -1;
11620+}
11621+
11622+#ifdef WCHAR
11623+/* This converts PTR, a pointer into one of the search wchar_t strings
11624+ `string1' and `string2' into an multibyte string offset from the
11625+ beginning of that string. We use mbs_offset to optimize.
11626+ See convert_mbs_to_wcs. */
11627+# define POINTER_TO_OFFSET(ptr) \
11628+ (FIRST_STRING_P (ptr) \
11629+ ? ((regoff_t)(mbs_offset1 != NULL? mbs_offset1[(ptr)-string1] : 0)) \
11630+ : ((regoff_t)((mbs_offset2 != NULL? mbs_offset2[(ptr)-string2] : 0) \
11631+ + csize1)))
11632+#else /* BYTE */
11633+/* This converts PTR, a pointer into one of the search strings `string1'
11634+ and `string2' into an offset from the beginning of that string. */
11635+# define POINTER_TO_OFFSET(ptr) \
11636+ (FIRST_STRING_P (ptr) \
11637+ ? ((regoff_t) ((ptr) - string1)) \
11638+ : ((regoff_t) ((ptr) - string2 + size1)))
11639+#endif /* WCHAR */
11640+
11641+/* Macros for dealing with the split strings in re_match_2. */
11642+
11643+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
11644+
11645+/* Call before fetching a character with *d. This switches over to
11646+ string2 if necessary. */
11647+#define PREFETCH() \
11648+ while (d == dend) \
11649+ { \
11650+ /* End of string2 => fail. */ \
11651+ if (dend == end_match_2) \
11652+ goto fail; \
11653+ /* End of string1 => advance to string2. */ \
11654+ d = string2; \
11655+ dend = end_match_2; \
11656+ }
11657+
11658+/* Test if at very beginning or at very end of the virtual concatenation
11659+ of `string1' and `string2'. If only one string, it's `string2'. */
11660+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
11661+#define AT_STRINGS_END(d) ((d) == end2)
11662+
11663+
11664+/* Test if D points to a character which is word-constituent. We have
11665+ two special cases to check for: if past the end of string1, look at
11666+ the first character in string2; and if before the beginning of
11667+ string2, look at the last character in string1. */
11668+#ifdef WCHAR
11669+/* Use internationalized API instead of SYNTAX. */
11670+# define WORDCHAR_P(d) \
11671+ (iswalnum ((wint_t)((d) == end1 ? *string2 \
11672+ : (d) == string2 - 1 ? *(end1 - 1) : *(d))) != 0 \
11673+ || ((d) == end1 ? *string2 \
11674+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) == L'_')
11675+#else /* BYTE */
11676+# define WORDCHAR_P(d) \
11677+ (SYNTAX ((d) == end1 ? *string2 \
11678+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
11679+ == Sword)
11680+#endif /* WCHAR */
11681+
11682+/* Disabled due to a compiler bug -- see comment at case wordbound */
11683+#if 0
11684+/* Test if the character before D and the one at D differ with respect
11685+ to being word-constituent. */
11686+#define AT_WORD_BOUNDARY(d) \
11687+ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
11688+ || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
11689+#endif
11690+
11691+/* Free everything we malloc. */
11692+#ifdef MATCH_MAY_ALLOCATE
11693+# ifdef WCHAR
11694+# define FREE_VARIABLES() \
11695+ do { \
11696+ REGEX_FREE_STACK (fail_stack.stack); \
11697+ FREE_VAR (regstart); \
11698+ FREE_VAR (regend); \
11699+ FREE_VAR (old_regstart); \
11700+ FREE_VAR (old_regend); \
11701+ FREE_VAR (best_regstart); \
11702+ FREE_VAR (best_regend); \
11703+ FREE_VAR (reg_info); \
11704+ FREE_VAR (reg_dummy); \
11705+ FREE_VAR (reg_info_dummy); \
11706+ if (!cant_free_wcs_buf) \
11707+ { \
11708+ FREE_VAR (string1); \
11709+ FREE_VAR (string2); \
11710+ FREE_VAR (mbs_offset1); \
11711+ FREE_VAR (mbs_offset2); \
11712+ } \
11713+ } while (0)
11714+# else /* BYTE */
11715+# define FREE_VARIABLES() \
11716+ do { \
11717+ REGEX_FREE_STACK (fail_stack.stack); \
11718+ FREE_VAR (regstart); \
11719+ FREE_VAR (regend); \
11720+ FREE_VAR (old_regstart); \
11721+ FREE_VAR (old_regend); \
11722+ FREE_VAR (best_regstart); \
11723+ FREE_VAR (best_regend); \
11724+ FREE_VAR (reg_info); \
11725+ FREE_VAR (reg_dummy); \
11726+ FREE_VAR (reg_info_dummy); \
11727+ } while (0)
11728+# endif /* WCHAR */
11729+#else
11730+# ifdef WCHAR
11731+# define FREE_VARIABLES() \
11732+ do { \
11733+ if (!cant_free_wcs_buf) \
11734+ { \
11735+ FREE_VAR (string1); \
11736+ FREE_VAR (string2); \
11737+ FREE_VAR (mbs_offset1); \
11738+ FREE_VAR (mbs_offset2); \
11739+ } \
11740+ } while (0)
11741+# else /* BYTE */
11742+# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */
11743+# endif /* WCHAR */
11744+#endif /* not MATCH_MAY_ALLOCATE */
11745+
11746+/* These values must meet several constraints. They must not be valid
11747+ register values; since we have a limit of 255 registers (because
11748+ we use only one byte in the pattern for the register number), we can
11749+ use numbers larger than 255. They must differ by 1, because of
11750+ NUM_FAILURE_ITEMS above. And the value for the lowest register must
11751+ be larger than the value for the highest register, so we do not try
11752+ to actually save any registers when none are active. */
11753+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
11754+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
11755+
11756+#else /* not INSIDE_RECURSION */
11757+/* Matching routines. */
11758+
11759+#ifndef emacs /* Emacs never uses this. */
11760+/* re_match is like re_match_2 except it takes only a single string. */
11761+
11762+int
11763+re_match (struct re_pattern_buffer *bufp, const char *string,
11764+ int size, int pos, struct re_registers *regs)
11765+{
11766+ int result;
11767+# ifdef MBS_SUPPORT
11768+ if (MB_CUR_MAX != 1)
11769+ result = wcs_re_match_2_internal (bufp, NULL, 0, string, size,
11770+ pos, regs, size,
11771+ NULL, 0, NULL, 0, NULL, NULL);
11772+ else
11773+# endif
11774+ result = byte_re_match_2_internal (bufp, NULL, 0, string, size,
11775+ pos, regs, size);
11776+# ifndef REGEX_MALLOC
11777+# ifdef C_ALLOCA
11778+ alloca (0);
11779+# endif
11780+# endif
11781+ return result;
11782+}
11783+# ifdef _LIBC
11784+weak_alias (__re_match, re_match)
11785+# endif
11786+#endif /* not emacs */
11787+
11788+#endif /* not INSIDE_RECURSION */
11789+
11790+#ifdef INSIDE_RECURSION
11791+static boolean PREFIX(group_match_null_string_p) (UCHAR_T **p,
11792+ UCHAR_T *end,
11793+ PREFIX(register_info_type) *reg_info);
11794+static boolean PREFIX(alt_match_null_string_p) (UCHAR_T *p,
11795+ UCHAR_T *end,
11796+ PREFIX(register_info_type) *reg_info);
11797+static boolean PREFIX(common_op_match_null_string_p) (UCHAR_T **p,
11798+ UCHAR_T *end,
11799+ PREFIX(register_info_type) *reg_info);
11800+static int PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2,
11801+ register int len,
11802+ RE_TRANSLATE_TYPE translate);
11803+#else /* not INSIDE_RECURSION */
11804+
11805+/* re_match_2 matches the compiled pattern in BUFP against the
11806+ the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
11807+ and SIZE2, respectively). We start matching at POS, and stop
11808+ matching at STOP.
11809+
11810+ If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
11811+ store offsets for the substring each group matched in REGS. See the
11812+ documentation for exactly how many groups we fill.
11813+
11814+ We return -1 if no match, -2 if an internal error (such as the
11815+ failure stack overflowing). Otherwise, we return the length of the
11816+ matched substring. */
11817+
11818+int
11819+re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
11820+ const char *string2, int size2, int pos,
11821+ struct re_registers *regs, int stop)
11822+{
11823+ int result;
11824+# ifdef MBS_SUPPORT
11825+ if (MB_CUR_MAX != 1)
11826+ result = wcs_re_match_2_internal (bufp, string1, size1, string2, size2,
11827+ pos, regs, stop,
11828+ NULL, 0, NULL, 0, NULL, NULL);
11829+ else
11830+# endif
11831+ result = byte_re_match_2_internal (bufp, string1, size1, string2, size2,
11832+ pos, regs, stop);
11833+
11834+#ifndef REGEX_MALLOC
11835+# ifdef C_ALLOCA
11836+ alloca (0);
11837+# endif
11838+#endif
11839+ return result;
11840+}
11841+#ifdef _LIBC
11842+weak_alias (__re_match_2, re_match_2)
11843+#endif
11844+
11845+#endif /* not INSIDE_RECURSION */
11846+
11847+#ifdef INSIDE_RECURSION
11848+
11849+#ifdef WCHAR
11850+static int count_mbs_length (int *, int);
11851+
11852+/* This check the substring (from 0, to length) of the multibyte string,
11853+ to which offset_buffer correspond. And count how many wchar_t_characters
11854+ the substring occupy. We use offset_buffer to optimization.
11855+ See convert_mbs_to_wcs. */
11856+
11857+static int
11858+count_mbs_length(int *offset_buffer, int length)
11859+{
11860+ int upper, lower;
11861+
11862+ /* Check whether the size is valid. */
11863+ if (length < 0)
11864+ return -1;
11865+
11866+ if (offset_buffer == NULL)
11867+ return 0;
11868+
11869+ /* If there are no multibyte character, offset_buffer[i] == i.
11870+ Optmize for this case. */
11871+ if (offset_buffer[length] == length)
11872+ return length;
11873+
11874+ /* Set up upper with length. (because for all i, offset_buffer[i] >= i) */
11875+ upper = length;
11876+ lower = 0;
11877+
11878+ while (true)
11879+ {
11880+ int middle = (lower + upper) / 2;
11881+ if (middle == lower || middle == upper)
11882+ break;
11883+ if (offset_buffer[middle] > length)
11884+ upper = middle;
11885+ else if (offset_buffer[middle] < length)
11886+ lower = middle;
11887+ else
11888+ return middle;
11889+ }
11890+
11891+ return -1;
11892+}
11893+#endif /* WCHAR */
11894+
11895+/* This is a separate function so that we can force an alloca cleanup
11896+ afterwards. */
11897+#ifdef WCHAR
11898+static int
11899+wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
11900+ const char *cstring1, int csize1,
11901+ const char *cstring2, int csize2,
11902+ int pos,
11903+ struct re_registers *regs,
11904+ int stop,
11905+ /* string1 == string2 == NULL means string1/2, size1/2 and
11906+ mbs_offset1/2 need seting up in this function. */
11907+ /* We need wchar_t* buffers correspond to cstring1, cstring2. */
11908+ wchar_t *string1, int size1,
11909+ wchar_t *string2, int size2,
11910+ /* offset buffer for optimizatoin. See convert_mbs_to_wc. */
11911+ int *mbs_offset1, int *mbs_offset2)
11912+#else /* BYTE */
11913+static int
11914+byte_re_match_2_internal (struct re_pattern_buffer *bufp,
11915+ const char *string1, int size1,
11916+ const char *string2, int size2,
11917+ int pos,
11918+ struct re_registers *regs, int stop)
11919+#endif /* BYTE */
11920+{
11921+ /* General temporaries. */
11922+ int mcnt;
11923+ UCHAR_T *p1;
11924+#ifdef WCHAR
11925+ /* They hold whether each wchar_t is binary data or not. */
11926+ char *is_binary = NULL;
11927+ /* If true, we can't free string1/2, mbs_offset1/2. */
11928+ int cant_free_wcs_buf = 1;
11929+#endif /* WCHAR */
11930+
11931+ /* Just past the end of the corresponding string. */
11932+ const CHAR_T *end1, *end2;
11933+
11934+ /* Pointers into string1 and string2, just past the last characters in
11935+ each to consider matching. */
11936+ const CHAR_T *end_match_1, *end_match_2;
11937+
11938+ /* Where we are in the data, and the end of the current string. */
11939+ const CHAR_T *d, *dend;
11940+
11941+ /* Where we are in the pattern, and the end of the pattern. */
11942+#ifdef WCHAR
11943+ UCHAR_T *pattern, *p;
11944+ register UCHAR_T *pend;
11945+#else /* BYTE */
11946+ UCHAR_T *p = bufp->buffer;
11947+ register UCHAR_T *pend = p + bufp->used;
11948+#endif /* WCHAR */
11949+
11950+ /* Mark the opcode just after a start_memory, so we can test for an
11951+ empty subpattern when we get to the stop_memory. */
11952+ UCHAR_T *just_past_start_mem = 0;
11953+
11954+ /* We use this to map every character in the string. */
11955+ RE_TRANSLATE_TYPE translate = bufp->translate;
11956+
11957+ /* Failure point stack. Each place that can handle a failure further
11958+ down the line pushes a failure point on this stack. It consists of
11959+ restart, regend, and reg_info for all registers corresponding to
11960+ the subexpressions we're currently inside, plus the number of such
11961+ registers, and, finally, two char *'s. The first char * is where
11962+ to resume scanning the pattern; the second one is where to resume
11963+ scanning the strings. If the latter is zero, the failure point is
11964+ a ``dummy''; if a failure happens and the failure point is a dummy,
11965+ it gets discarded and the next next one is tried. */
11966+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
11967+ PREFIX(fail_stack_type) fail_stack;
11968+#endif
11969+#ifdef DEBUG
11970+ static unsigned failure_id;
11971+ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
11972+#endif
11973+
11974+#ifdef REL_ALLOC
11975+ /* This holds the pointer to the failure stack, when
11976+ it is allocated relocatably. */
11977+ fail_stack_elt_t *failure_stack_ptr;
11978+#endif
11979+
11980+ /* We fill all the registers internally, independent of what we
11981+ return, for use in backreferences. The number here includes
11982+ an element for register zero. */
11983+ size_t num_regs = bufp->re_nsub + 1;
11984+
11985+ /* The currently active registers. */
11986+ active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
11987+ active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
11988+
11989+ /* Information on the contents of registers. These are pointers into
11990+ the input strings; they record just what was matched (on this
11991+ attempt) by a subexpression part of the pattern, that is, the
11992+ regnum-th regstart pointer points to where in the pattern we began
11993+ matching and the regnum-th regend points to right after where we
11994+ stopped matching the regnum-th subexpression. (The zeroth register
11995+ keeps track of what the whole pattern matches.) */
11996+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
11997+ const CHAR_T **regstart, **regend;
11998+#endif
11999+
12000+ /* If a group that's operated upon by a repetition operator fails to
12001+ match anything, then the register for its start will need to be
12002+ restored because it will have been set to wherever in the string we
12003+ are when we last see its open-group operator. Similarly for a
12004+ register's end. */
12005+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
12006+ const CHAR_T **old_regstart, **old_regend;
12007+#endif
12008+
12009+ /* The is_active field of reg_info helps us keep track of which (possibly
12010+ nested) subexpressions we are currently in. The matched_something
12011+ field of reg_info[reg_num] helps us tell whether or not we have
12012+ matched any of the pattern so far this time through the reg_num-th
12013+ subexpression. These two fields get reset each time through any
12014+ loop their register is in. */
12015+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
12016+ PREFIX(register_info_type) *reg_info;
12017+#endif
12018+
12019+ /* The following record the register info as found in the above
12020+ variables when we find a match better than any we've seen before.
12021+ This happens as we backtrack through the failure points, which in
12022+ turn happens only if we have not yet matched the entire string. */
12023+ unsigned best_regs_set = false;
12024+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
12025+ const CHAR_T **best_regstart, **best_regend;
12026+#endif
12027+
12028+ /* Logically, this is `best_regend[0]'. But we don't want to have to
12029+ allocate space for that if we're not allocating space for anything
12030+ else (see below). Also, we never need info about register 0 for
12031+ any of the other register vectors, and it seems rather a kludge to
12032+ treat `best_regend' differently than the rest. So we keep track of
12033+ the end of the best match so far in a separate variable. We
12034+ initialize this to NULL so that when we backtrack the first time
12035+ and need to test it, it's not garbage. */
12036+ const CHAR_T *match_end = NULL;
12037+
12038+ /* This helps SET_REGS_MATCHED avoid doing redundant work. */
12039+ int set_regs_matched_done = 0;
12040+
12041+ /* Used when we pop values we don't care about. */
12042+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
12043+ const CHAR_T **reg_dummy;
12044+ PREFIX(register_info_type) *reg_info_dummy;
12045+#endif
12046+
12047+#ifdef DEBUG
12048+ /* Counts the total number of registers pushed. */
12049+ unsigned num_regs_pushed = 0;
12050+#endif
12051+
12052+ DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
12053+
12054+ INIT_FAIL_STACK ();
12055+
12056+#ifdef MATCH_MAY_ALLOCATE
12057+ /* Do not bother to initialize all the register variables if there are
12058+ no groups in the pattern, as it takes a fair amount of time. If
12059+ there are groups, we include space for register 0 (the whole
12060+ pattern), even though we never use it, since it simplifies the
12061+ array indexing. We should fix this. */
12062+ if (bufp->re_nsub)
12063+ {
12064+ regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
12065+ regend = REGEX_TALLOC (num_regs, const CHAR_T *);
12066+ old_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
12067+ old_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
12068+ best_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
12069+ best_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
12070+ reg_info = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
12071+ reg_dummy = REGEX_TALLOC (num_regs, const CHAR_T *);
12072+ reg_info_dummy = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
12073+
12074+ if (!(regstart && regend && old_regstart && old_regend && reg_info
12075+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
12076+ {
12077+ FREE_VARIABLES ();
12078+ return -2;
12079+ }
12080+ }
12081+ else
12082+ {
12083+ /* We must initialize all our variables to NULL, so that
12084+ `FREE_VARIABLES' doesn't try to free them. */
12085+ regstart = regend = old_regstart = old_regend = best_regstart
12086+ = best_regend = reg_dummy = NULL;
12087+ reg_info = reg_info_dummy = (PREFIX(register_info_type) *) NULL;
12088+ }
12089+#endif /* MATCH_MAY_ALLOCATE */
12090+
12091+ /* The starting position is bogus. */
12092+#ifdef WCHAR
12093+ if (pos < 0 || pos > csize1 + csize2)
12094+#else /* BYTE */
12095+ if (pos < 0 || pos > size1 + size2)
12096+#endif
12097+ {
12098+ FREE_VARIABLES ();
12099+ return -1;
12100+ }
12101+
12102+#ifdef WCHAR
12103+ /* Allocate wchar_t array for string1 and string2 and
12104+ fill them with converted string. */
12105+ if (string1 == NULL && string2 == NULL)
12106+ {
12107+ /* We need seting up buffers here. */
12108+
12109+ /* We must free wcs buffers in this function. */
12110+ cant_free_wcs_buf = 0;
12111+
12112+ if (csize1 != 0)
12113+ {
12114+ string1 = REGEX_TALLOC (csize1 + 1, CHAR_T);
12115+ mbs_offset1 = REGEX_TALLOC (csize1 + 1, int);
12116+ is_binary = REGEX_TALLOC (csize1 + 1, char);
12117+ if (!string1 || !mbs_offset1 || !is_binary)
12118+ {
12119+ FREE_VAR (string1);
12120+ FREE_VAR (mbs_offset1);
12121+ FREE_VAR (is_binary);
12122+ return -2;
12123+ }
12124+ }
12125+ if (csize2 != 0)
12126+ {
12127+ string2 = REGEX_TALLOC (csize2 + 1, CHAR_T);
12128+ mbs_offset2 = REGEX_TALLOC (csize2 + 1, int);
12129+ is_binary = REGEX_TALLOC (csize2 + 1, char);
12130+ if (!string2 || !mbs_offset2 || !is_binary)
12131+ {
12132+ FREE_VAR (string1);
12133+ FREE_VAR (mbs_offset1);
12134+ FREE_VAR (string2);
12135+ FREE_VAR (mbs_offset2);
12136+ FREE_VAR (is_binary);
12137+ return -2;
12138+ }
12139+ size2 = convert_mbs_to_wcs(string2, cstring2, csize2,
12140+ mbs_offset2, is_binary);
12141+ string2[size2] = L'\0'; /* for a sentinel */
12142+ FREE_VAR (is_binary);
12143+ }
12144+ }
12145+
12146+ /* We need to cast pattern to (wchar_t*), because we casted this compiled
12147+ pattern to (char*) in regex_compile. */
12148+ p = pattern = (CHAR_T*)bufp->buffer;
12149+ pend = (CHAR_T*)(bufp->buffer + bufp->used);
12150+
12151+#endif /* WCHAR */
12152+
12153+ /* Initialize subexpression text positions to -1 to mark ones that no
12154+ start_memory/stop_memory has been seen for. Also initialize the
12155+ register information struct. */
12156+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
12157+ {
12158+ regstart[mcnt] = regend[mcnt]
12159+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
12160+
12161+ REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
12162+ IS_ACTIVE (reg_info[mcnt]) = 0;
12163+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
12164+ EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
12165+ }
12166+
12167+ /* We move `string1' into `string2' if the latter's empty -- but not if
12168+ `string1' is null. */
12169+ if (size2 == 0 && string1 != NULL)
12170+ {
12171+ string2 = string1;
12172+ size2 = size1;
12173+ string1 = 0;
12174+ size1 = 0;
12175+#ifdef WCHAR
12176+ mbs_offset2 = mbs_offset1;
12177+ csize2 = csize1;
12178+ mbs_offset1 = NULL;
12179+ csize1 = 0;
12180+#endif
12181+ }
12182+ end1 = string1 + size1;
12183+ end2 = string2 + size2;
12184+
12185+ /* Compute where to stop matching, within the two strings. */
12186+#ifdef WCHAR
12187+ if (stop <= csize1)
12188+ {
12189+ mcnt = count_mbs_length(mbs_offset1, stop);
12190+ end_match_1 = string1 + mcnt;
12191+ end_match_2 = string2;
12192+ }
12193+ else
12194+ {
12195+ if (stop > csize1 + csize2)
12196+ stop = csize1 + csize2;
12197+ end_match_1 = end1;
12198+ mcnt = count_mbs_length(mbs_offset2, stop-csize1);
12199+ end_match_2 = string2 + mcnt;
12200+ }
12201+ if (mcnt < 0)
12202+ { /* count_mbs_length return error. */
12203+ FREE_VARIABLES ();
12204+ return -1;
12205+ }
12206+#else
12207+ if (stop <= size1)
12208+ {
12209+ end_match_1 = string1 + stop;
12210+ end_match_2 = string2;
12211+ }
12212+ else
12213+ {
12214+ end_match_1 = end1;
12215+ end_match_2 = string2 + stop - size1;
12216+ }
12217+#endif /* WCHAR */
12218+
12219+ /* `p' scans through the pattern as `d' scans through the data.
12220+ `dend' is the end of the input string that `d' points within. `d'
12221+ is advanced into the following input string whenever necessary, but
12222+ this happens before fetching; therefore, at the beginning of the
12223+ loop, `d' can be pointing at the end of a string, but it cannot
12224+ equal `string2'. */
12225+#ifdef WCHAR
12226+ if (size1 > 0 && pos <= csize1)
12227+ {
12228+ mcnt = count_mbs_length(mbs_offset1, pos);
12229+ d = string1 + mcnt;
12230+ dend = end_match_1;
12231+ }
12232+ else
12233+ {
12234+ mcnt = count_mbs_length(mbs_offset2, pos-csize1);
12235+ d = string2 + mcnt;
12236+ dend = end_match_2;
12237+ }
12238+
12239+ if (mcnt < 0)
12240+ { /* count_mbs_length return error. */
12241+ FREE_VARIABLES ();
12242+ return -1;
12243+ }
12244+#else
12245+ if (size1 > 0 && pos <= size1)
12246+ {
12247+ d = string1 + pos;
12248+ dend = end_match_1;
12249+ }
12250+ else
12251+ {
12252+ d = string2 + pos - size1;
12253+ dend = end_match_2;
12254+ }
12255+#endif /* WCHAR */
12256+
12257+ DEBUG_PRINT1 ("The compiled pattern is:\n");
12258+ DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
12259+ DEBUG_PRINT1 ("The string to match is: `");
12260+ DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
12261+ DEBUG_PRINT1 ("'\n");
12262+
12263+ /* This loops over pattern commands. It exits by returning from the
12264+ function if the match is complete, or it drops through if the match
12265+ fails at this starting point in the input data. */
12266+ for (;;)
12267+ {
12268+#ifdef _LIBC
12269+ DEBUG_PRINT2 ("\n%p: ", p);
12270+#else
12271+ DEBUG_PRINT2 ("\n0x%x: ", p);
12272+#endif
12273+
12274+ if (p == pend)
12275+ { /* End of pattern means we might have succeeded. */
12276+ DEBUG_PRINT1 ("end of pattern ... ");
12277+
12278+ /* If we haven't matched the entire string, and we want the
12279+ longest match, try backtracking. */
12280+ if (d != end_match_2)
12281+ {
12282+ /* 1 if this match ends in the same string (string1 or string2)
12283+ as the best previous match. */
12284+ boolean same_str_p = (FIRST_STRING_P (match_end)
12285+ == MATCHING_IN_FIRST_STRING);
12286+ /* 1 if this match is the best seen so far. */
12287+ boolean best_match_p;
12288+
12289+ /* AIX compiler got confused when this was combined
12290+ with the previous declaration. */
12291+ if (same_str_p)
12292+ best_match_p = d > match_end;
12293+ else
12294+ best_match_p = !MATCHING_IN_FIRST_STRING;
12295+
12296+ DEBUG_PRINT1 ("backtracking.\n");
12297+
12298+ if (!FAIL_STACK_EMPTY ())
12299+ { /* More failure points to try. */
12300+
12301+ /* If exceeds best match so far, save it. */
12302+ if (!best_regs_set || best_match_p)
12303+ {
12304+ best_regs_set = true;
12305+ match_end = d;
12306+
12307+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
12308+
12309+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
12310+ {
12311+ best_regstart[mcnt] = regstart[mcnt];
12312+ best_regend[mcnt] = regend[mcnt];
12313+ }
12314+ }
12315+ goto fail;
12316+ }
12317+
12318+ /* If no failure points, don't restore garbage. And if
12319+ last match is real best match, don't restore second
12320+ best one. */
12321+ else if (best_regs_set && !best_match_p)
12322+ {
12323+ restore_best_regs:
12324+ /* Restore best match. It may happen that `dend ==
12325+ end_match_1' while the restored d is in string2.
12326+ For example, the pattern `x.*y.*z' against the
12327+ strings `x-' and `y-z-', if the two strings are
12328+ not consecutive in memory. */
12329+ DEBUG_PRINT1 ("Restoring best registers.\n");
12330+
12331+ d = match_end;
12332+ dend = ((d >= string1 && d <= end1)
12333+ ? end_match_1 : end_match_2);
12334+
12335+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
12336+ {
12337+ regstart[mcnt] = best_regstart[mcnt];
12338+ regend[mcnt] = best_regend[mcnt];
12339+ }
12340+ }
12341+ } /* d != end_match_2 */
12342+
12343+ succeed_label:
12344+ DEBUG_PRINT1 ("Accepting match.\n");
12345+ /* If caller wants register contents data back, do it. */
12346+ if (regs && !bufp->no_sub)
12347+ {
12348+ /* Have the register data arrays been allocated? */
12349+ if (bufp->regs_allocated == REGS_UNALLOCATED)
12350+ { /* No. So allocate them with malloc. We need one
12351+ extra element beyond `num_regs' for the `-1' marker
12352+ GNU code uses. */
12353+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
12354+ regs->start = TALLOC (regs->num_regs, regoff_t);
12355+ regs->end = TALLOC (regs->num_regs, regoff_t);
12356+ if (regs->start == NULL || regs->end == NULL)
12357+ {
12358+ FREE_VARIABLES ();
12359+ return -2;
12360+ }
12361+ bufp->regs_allocated = REGS_REALLOCATE;
12362+ }
12363+ else if (bufp->regs_allocated == REGS_REALLOCATE)
12364+ { /* Yes. If we need more elements than were already
12365+ allocated, reallocate them. If we need fewer, just
12366+ leave it alone. */
12367+ if (regs->num_regs < num_regs + 1)
12368+ {
12369+ regs->num_regs = num_regs + 1;
12370+ RETALLOC (regs->start, regs->num_regs, regoff_t);
12371+ RETALLOC (regs->end, regs->num_regs, regoff_t);
12372+ if (regs->start == NULL || regs->end == NULL)
12373+ {
12374+ FREE_VARIABLES ();
12375+ return -2;
12376+ }
12377+ }
12378+ }
12379+ else
12380+ {
12381+ /* These braces fend off a "empty body in an else-statement"
12382+ warning under GCC when assert expands to nothing. */
12383+ assert (bufp->regs_allocated == REGS_FIXED);
12384+ }
12385+
12386+ /* Convert the pointer data in `regstart' and `regend' to
12387+ indices. Register zero has to be set differently,
12388+ since we haven't kept track of any info for it. */
12389+ if (regs->num_regs > 0)
12390+ {
12391+ regs->start[0] = pos;
12392+#ifdef WCHAR
12393+ if (MATCHING_IN_FIRST_STRING)
12394+ regs->end[0] = mbs_offset1 != NULL ?
12395+ mbs_offset1[d-string1] : 0;
12396+ else
12397+ regs->end[0] = csize1 + (mbs_offset2 != NULL ?
12398+ mbs_offset2[d-string2] : 0);
12399+#else
12400+ regs->end[0] = (MATCHING_IN_FIRST_STRING
12401+ ? ((regoff_t) (d - string1))
12402+ : ((regoff_t) (d - string2 + size1)));
12403+#endif /* WCHAR */
12404+ }
12405+
12406+ /* Go through the first `min (num_regs, regs->num_regs)'
12407+ registers, since that is all we initialized. */
12408+ for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs);
12409+ mcnt++)
12410+ {
12411+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
12412+ regs->start[mcnt] = regs->end[mcnt] = -1;
12413+ else
12414+ {
12415+ regs->start[mcnt]
12416+ = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
12417+ regs->end[mcnt]
12418+ = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
12419+ }
12420+ }
12421+
12422+ /* If the regs structure we return has more elements than
12423+ were in the pattern, set the extra elements to -1. If
12424+ we (re)allocated the registers, this is the case,
12425+ because we always allocate enough to have at least one
12426+ -1 at the end. */
12427+ for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++)
12428+ regs->start[mcnt] = regs->end[mcnt] = -1;
12429+ } /* regs && !bufp->no_sub */
12430+
12431+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
12432+ nfailure_points_pushed, nfailure_points_popped,
12433+ nfailure_points_pushed - nfailure_points_popped);
12434+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
12435+
12436+#ifdef WCHAR
12437+ if (MATCHING_IN_FIRST_STRING)
12438+ mcnt = mbs_offset1 != NULL ? mbs_offset1[d-string1] : 0;
12439+ else
12440+ mcnt = (mbs_offset2 != NULL ? mbs_offset2[d-string2] : 0) +
12441+ csize1;
12442+ mcnt -= pos;
12443+#else
12444+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
12445+ ? string1
12446+ : string2 - size1);
12447+#endif /* WCHAR */
12448+
12449+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
12450+
12451+ FREE_VARIABLES ();
12452+ return mcnt;
12453+ }
12454+
12455+ /* Otherwise match next pattern command. */
12456+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
12457+ {
12458+ /* Ignore these. Used to ignore the n of succeed_n's which
12459+ currently have n == 0. */
12460+ case no_op:
12461+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
12462+ break;
12463+
12464+ case succeed:
12465+ DEBUG_PRINT1 ("EXECUTING succeed.\n");
12466+ goto succeed_label;
12467+
12468+ /* Match the next n pattern characters exactly. The following
12469+ byte in the pattern defines n, and the n bytes after that
12470+ are the characters to match. */
12471+ case exactn:
12472+#ifdef MBS_SUPPORT
12473+ case exactn_bin:
12474+#endif
12475+ mcnt = *p++;
12476+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
12477+
12478+ /* This is written out as an if-else so we don't waste time
12479+ testing `translate' inside the loop. */
12480+ if (translate)
12481+ {
12482+ do
12483+ {
12484+ PREFETCH ();
12485+#ifdef WCHAR
12486+ if (*d <= 0xff)
12487+ {
12488+ if ((UCHAR_T) translate[(unsigned char) *d++]
12489+ != (UCHAR_T) *p++)
12490+ goto fail;
12491+ }
12492+ else
12493+ {
12494+ if (*d++ != (CHAR_T) *p++)
12495+ goto fail;
12496+ }
12497+#else
12498+ if ((UCHAR_T) translate[(unsigned char) *d++]
12499+ != (UCHAR_T) *p++)
12500+ goto fail;
12501+#endif /* WCHAR */
12502+ }
12503+ while (--mcnt);
12504+ }
12505+ else
12506+ {
12507+ do
12508+ {
12509+ PREFETCH ();
12510+ if (*d++ != (CHAR_T) *p++) goto fail;
12511+ }
12512+ while (--mcnt);
12513+ }
12514+ SET_REGS_MATCHED ();
12515+ break;
12516+
12517+
12518+ /* Match any character except possibly a newline or a null. */
12519+ case anychar:
12520+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
12521+
12522+ PREFETCH ();
12523+
12524+ if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
12525+ || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
12526+ goto fail;
12527+
12528+ SET_REGS_MATCHED ();
12529+ DEBUG_PRINT2 (" Matched `%ld'.\n", (long int) *d);
12530+ d++;
12531+ break;
12532+
12533+
12534+ case charset:
12535+ case charset_not:
12536+ {
12537+ register UCHAR_T c;
12538+#ifdef WCHAR
12539+ unsigned int i, char_class_length, coll_symbol_length,
12540+ equiv_class_length, ranges_length, chars_length, length;
12541+ CHAR_T *workp, *workp2, *charset_top;
12542+#define WORK_BUFFER_SIZE 128
12543+ CHAR_T str_buf[WORK_BUFFER_SIZE];
12544+# ifdef _LIBC
12545+ uint32_t nrules;
12546+# endif /* _LIBC */
12547+#endif /* WCHAR */
12548+ boolean negate = (re_opcode_t) *(p - 1) == charset_not;
12549+
12550+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", negate ? "_not" : "");
12551+ PREFETCH ();
12552+ c = TRANSLATE (*d); /* The character to match. */
12553+#ifdef WCHAR
12554+# ifdef _LIBC
12555+ nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
12556+# endif /* _LIBC */
12557+ charset_top = p - 1;
12558+ char_class_length = *p++;
12559+ coll_symbol_length = *p++;
12560+ equiv_class_length = *p++;
12561+ ranges_length = *p++;
12562+ chars_length = *p++;
12563+ /* p points charset[6], so the address of the next instruction
12564+ (charset[l+m+n+2o+k+p']) equals p[l+m+n+2*o+p'],
12565+ where l=length of char_classes, m=length of collating_symbol,
12566+ n=equivalence_class, o=length of char_range,
12567+ p'=length of character. */
12568+ workp = p;
12569+ /* Update p to indicate the next instruction. */
12570+ p += char_class_length + coll_symbol_length+ equiv_class_length +
12571+ 2*ranges_length + chars_length;
12572+
12573+ /* match with char_class? */
12574+ for (i = 0; i < char_class_length ; i += CHAR_CLASS_SIZE)
12575+ {
12576+ wctype_t wctype;
12577+ uintptr_t alignedp = ((uintptr_t)workp
12578+ + __alignof__(wctype_t) - 1)
12579+ & ~(uintptr_t)(__alignof__(wctype_t) - 1);
12580+ wctype = *((wctype_t*)alignedp);
12581+ workp += CHAR_CLASS_SIZE;
12582+# ifdef _LIBC
12583+ if (__iswctype((wint_t)c, wctype))
12584+ goto char_set_matched;
12585+# else
12586+ if (iswctype((wint_t)c, wctype))
12587+ goto char_set_matched;
12588+# endif
12589+ }
12590+
12591+ /* match with collating_symbol? */
12592+# ifdef _LIBC
12593+ if (nrules != 0)
12594+ {
12595+ const unsigned char *extra = (const unsigned char *)
12596+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
12597+
12598+ for (workp2 = workp + coll_symbol_length ; workp < workp2 ;
12599+ workp++)
12600+ {
12601+ int32_t *wextra;
12602+ wextra = (int32_t*)(extra + *workp++);
12603+ for (i = 0; i < *wextra; ++i)
12604+ if (TRANSLATE(d[i]) != wextra[1 + i])
12605+ break;
12606+
12607+ if (i == *wextra)
12608+ {
12609+ /* Update d, however d will be incremented at
12610+ char_set_matched:, we decrement d here. */
12611+ d += i - 1;
12612+ goto char_set_matched;
12613+ }
12614+ }
12615+ }
12616+ else /* (nrules == 0) */
12617+# endif
12618+ /* If we can't look up collation data, we use wcscoll
12619+ instead. */
12620+ {
12621+ for (workp2 = workp + coll_symbol_length ; workp < workp2 ;)
12622+ {
12623+ const CHAR_T *backup_d = d, *backup_dend = dend;
12624+# ifdef _LIBC
12625+ length = __wcslen (workp);
12626+# else
12627+ length = wcslen (workp);
12628+# endif
12629+
12630+ /* If wcscoll(the collating symbol, whole string) > 0,
12631+ any substring of the string never match with the
12632+ collating symbol. */
12633+# ifdef _LIBC
12634+ if (__wcscoll (workp, d) > 0)
12635+# else
12636+ if (wcscoll (workp, d) > 0)
12637+# endif
12638+ {
12639+ workp += length + 1;
12640+ continue;
12641+ }
12642+
12643+ /* First, we compare the collating symbol with
12644+ the first character of the string.
12645+ If it don't match, we add the next character to
12646+ the compare buffer in turn. */
12647+ for (i = 0 ; i < WORK_BUFFER_SIZE-1 ; i++, d++)
12648+ {
12649+ int match;
12650+ if (d == dend)
12651+ {
12652+ if (dend == end_match_2)
12653+ break;
12654+ d = string2;
12655+ dend = end_match_2;
12656+ }
12657+
12658+ /* add next character to the compare buffer. */
12659+ str_buf[i] = TRANSLATE(*d);
12660+ str_buf[i+1] = '\0';
12661+
12662+# ifdef _LIBC
12663+ match = __wcscoll (workp, str_buf);
12664+# else
12665+ match = wcscoll (workp, str_buf);
12666+# endif
12667+ if (match == 0)
12668+ goto char_set_matched;
12669+
12670+ if (match < 0)
12671+ /* (str_buf > workp) indicate (str_buf + X > workp),
12672+ because for all X (str_buf + X > str_buf).
12673+ So we don't need continue this loop. */
12674+ break;
12675+
12676+ /* Otherwise(str_buf < workp),
12677+ (str_buf+next_character) may equals (workp).
12678+ So we continue this loop. */
12679+ }
12680+ /* not matched */
12681+ d = backup_d;
12682+ dend = backup_dend;
12683+ workp += length + 1;
12684+ }
12685+ }
12686+ /* match with equivalence_class? */
12687+# ifdef _LIBC
12688+ if (nrules != 0)
12689+ {
12690+ const CHAR_T *backup_d = d, *backup_dend = dend;
12691+ /* Try to match the equivalence class against
12692+ those known to the collate implementation. */
12693+ const int32_t *table;
12694+ const int32_t *weights;
12695+ const int32_t *extra;
12696+ const int32_t *indirect;
12697+ int32_t idx, idx2;
12698+ wint_t *cp;
12699+ size_t len;
12700+
12701+ table = (const int32_t *)
12702+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
12703+ weights = (const wint_t *)
12704+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
12705+ extra = (const wint_t *)
12706+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
12707+ indirect = (const int32_t *)
12708+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
12709+
12710+ /* Write 1 collating element to str_buf, and
12711+ get its index. */
12712+ idx2 = 0;
12713+
12714+ for (i = 0 ; idx2 == 0 && i < WORK_BUFFER_SIZE - 1; i++)
12715+ {
12716+ cp = (wint_t*)str_buf;
12717+ if (d == dend)
12718+ {
12719+ if (dend == end_match_2)
12720+ break;
12721+ d = string2;
12722+ dend = end_match_2;
12723+ }
12724+ str_buf[i] = TRANSLATE(*(d+i));
12725+ str_buf[i+1] = '\0'; /* sentinel */
12726+ idx2 = FINDIDX (table, indirect, extra, &cp, 1);
12727+ }
12728+
12729+ /* Update d, however d will be incremented at
12730+ char_set_matched:, we decrement d here. */
12731+ d = backup_d + ((wchar_t*)cp - (wchar_t*)str_buf - 1);
12732+ if (d >= dend)
12733+ {
12734+ if (dend == end_match_2)
12735+ d = dend;
12736+ else
12737+ {
12738+ d = string2;
12739+ dend = end_match_2;
12740+ }
12741+ }
12742+
12743+ len = weights[idx2];
12744+
12745+ for (workp2 = workp + equiv_class_length ; workp < workp2 ;
12746+ workp++)
12747+ {
12748+ idx = (int32_t)*workp;
12749+ /* We already checked idx != 0 in regex_compile. */
12750+
12751+ if (idx2 != 0 && len == weights[idx])
12752+ {
12753+ int cnt = 0;
12754+ while (cnt < len && (weights[idx + 1 + cnt]
12755+ == weights[idx2 + 1 + cnt]))
12756+ ++cnt;
12757+
12758+ if (cnt == len)
12759+ goto char_set_matched;
12760+ }
12761+ }
12762+ /* not matched */
12763+ d = backup_d;
12764+ dend = backup_dend;
12765+ }
12766+ else /* (nrules == 0) */
12767+# endif
12768+ /* If we can't look up collation data, we use wcscoll
12769+ instead. */
12770+ {
12771+ for (workp2 = workp + equiv_class_length ; workp < workp2 ;)
12772+ {
12773+ const CHAR_T *backup_d = d, *backup_dend = dend;
12774+# ifdef _LIBC
12775+ length = __wcslen (workp);
12776+# else
12777+ length = wcslen (workp);
12778+# endif
12779+
12780+ /* If wcscoll(the collating symbol, whole string) > 0,
12781+ any substring of the string never match with the
12782+ collating symbol. */
12783+# ifdef _LIBC
12784+ if (__wcscoll (workp, d) > 0)
12785+# else
12786+ if (wcscoll (workp, d) > 0)
12787+# endif
12788+ {
12789+ workp += length + 1;
12790+ break;
12791+ }
12792+
12793+ /* First, we compare the equivalence class with
12794+ the first character of the string.
12795+ If it don't match, we add the next character to
12796+ the compare buffer in turn. */
12797+ for (i = 0 ; i < WORK_BUFFER_SIZE - 1 ; i++, d++)
12798+ {
12799+ int match;
12800+ if (d == dend)
12801+ {
12802+ if (dend == end_match_2)
12803+ break;
12804+ d = string2;
12805+ dend = end_match_2;
12806+ }
12807+
12808+ /* add next character to the compare buffer. */
12809+ str_buf[i] = TRANSLATE(*d);
12810+ str_buf[i+1] = '\0';
12811+
12812+# ifdef _LIBC
12813+ match = __wcscoll (workp, str_buf);
12814+# else
12815+ match = wcscoll (workp, str_buf);
12816+# endif
12817+
12818+ if (match == 0)
12819+ goto char_set_matched;
12820+
12821+ if (match < 0)
12822+ /* (str_buf > workp) indicate (str_buf + X > workp),
12823+ because for all X (str_buf + X > str_buf).
12824+ So we don't need continue this loop. */
12825+ break;
12826+
12827+ /* Otherwise(str_buf < workp),
12828+ (str_buf+next_character) may equals (workp).
12829+ So we continue this loop. */
12830+ }
12831+ /* not matched */
12832+ d = backup_d;
12833+ dend = backup_dend;
12834+ workp += length + 1;
12835+ }
12836+ }
12837+
12838+ /* match with char_range? */
12839+# ifdef _LIBC
12840+ if (nrules != 0)
12841+ {
12842+ uint32_t collseqval;
12843+ const char *collseq = (const char *)
12844+ _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
12845+
12846+ collseqval = collseq_table_lookup (collseq, c);
12847+
12848+ for (; workp < p - chars_length ;)
12849+ {
12850+ uint32_t start_val, end_val;
12851+
12852+ /* We already compute the collation sequence value
12853+ of the characters (or collating symbols). */
12854+ start_val = (uint32_t) *workp++; /* range_start */
12855+ end_val = (uint32_t) *workp++; /* range_end */
12856+
12857+ if (start_val <= collseqval && collseqval <= end_val)
12858+ goto char_set_matched;
12859+ }
12860+ }
12861+ else
12862+# endif
12863+ {
12864+ /* We set range_start_char at str_buf[0], range_end_char
12865+ at str_buf[4], and compared char at str_buf[2]. */
12866+ str_buf[1] = 0;
12867+ str_buf[2] = c;
12868+ str_buf[3] = 0;
12869+ str_buf[5] = 0;
12870+ for (; workp < p - chars_length ;)
12871+ {
12872+ wchar_t *range_start_char, *range_end_char;
12873+
12874+ /* match if (range_start_char <= c <= range_end_char). */
12875+
12876+ /* If range_start(or end) < 0, we assume -range_start(end)
12877+ is the offset of the collating symbol which is specified
12878+ as the character of the range start(end). */
12879+
12880+ /* range_start */
12881+ if (*workp < 0)
12882+ range_start_char = charset_top - (*workp++);
12883+ else
12884+ {
12885+ str_buf[0] = *workp++;
12886+ range_start_char = str_buf;
12887+ }
12888+
12889+ /* range_end */
12890+ if (*workp < 0)
12891+ range_end_char = charset_top - (*workp++);
12892+ else
12893+ {
12894+ str_buf[4] = *workp++;
12895+ range_end_char = str_buf + 4;
12896+ }
12897+
12898+# ifdef _LIBC
12899+ if (__wcscoll (range_start_char, str_buf+2) <= 0
12900+ && __wcscoll (str_buf+2, range_end_char) <= 0)
12901+# else
12902+ if (wcscoll (range_start_char, str_buf+2) <= 0
12903+ && wcscoll (str_buf+2, range_end_char) <= 0)
12904+# endif
12905+ goto char_set_matched;
12906+ }
12907+ }
12908+
12909+ /* match with char? */
12910+ for (; workp < p ; workp++)
12911+ if (c == *workp)
12912+ goto char_set_matched;
12913+
12914+ negate = !negate;
12915+
12916+ char_set_matched:
12917+ if (negate) goto fail;
12918+#else
12919+ /* Cast to `unsigned' instead of `unsigned char' in case the
12920+ bit list is a full 32 bytes long. */
12921+ if (c < (unsigned) (*p * BYTEWIDTH)
12922+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
12923+ negate = !negate;
12924+
12925+ p += 1 + *p;
12926+
12927+ if (!negate) goto fail;
12928+#undef WORK_BUFFER_SIZE
12929+#endif /* WCHAR */
12930+ SET_REGS_MATCHED ();
12931+ d++;
12932+ break;
12933+ }
12934+
12935+
12936+ /* The beginning of a group is represented by start_memory.
12937+ The arguments are the register number in the next byte, and the
12938+ number of groups inner to this one in the next. The text
12939+ matched within the group is recorded (in the internal
12940+ registers data structure) under the register number. */
12941+ case start_memory:
12942+ DEBUG_PRINT3 ("EXECUTING start_memory %ld (%ld):\n",
12943+ (long int) *p, (long int) p[1]);
12944+
12945+ /* Find out if this group can match the empty string. */
12946+ p1 = p; /* To send to group_match_null_string_p. */
12947+
12948+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
12949+ REG_MATCH_NULL_STRING_P (reg_info[*p])
12950+ = PREFIX(group_match_null_string_p) (&p1, pend, reg_info);
12951+
12952+ /* Save the position in the string where we were the last time
12953+ we were at this open-group operator in case the group is
12954+ operated upon by a repetition operator, e.g., with `(a*)*b'
12955+ against `ab'; then we want to ignore where we are now in
12956+ the string in case this attempt to match fails. */
12957+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
12958+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
12959+ : regstart[*p];
12960+ DEBUG_PRINT2 (" old_regstart: %d\n",
12961+ POINTER_TO_OFFSET (old_regstart[*p]));
12962+
12963+ regstart[*p] = d;
12964+ DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
12965+
12966+ IS_ACTIVE (reg_info[*p]) = 1;
12967+ MATCHED_SOMETHING (reg_info[*p]) = 0;
12968+
12969+ /* Clear this whenever we change the register activity status. */
12970+ set_regs_matched_done = 0;
12971+
12972+ /* This is the new highest active register. */
12973+ highest_active_reg = *p;
12974+
12975+ /* If nothing was active before, this is the new lowest active
12976+ register. */
12977+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
12978+ lowest_active_reg = *p;
12979+
12980+ /* Move past the register number and inner group count. */
12981+ p += 2;
12982+ just_past_start_mem = p;
12983+
12984+ break;
12985+
12986+
12987+ /* The stop_memory opcode represents the end of a group. Its
12988+ arguments are the same as start_memory's: the register
12989+ number, and the number of inner groups. */
12990+ case stop_memory:
12991+ DEBUG_PRINT3 ("EXECUTING stop_memory %ld (%ld):\n",
12992+ (long int) *p, (long int) p[1]);
12993+
12994+ /* We need to save the string position the last time we were at
12995+ this close-group operator in case the group is operated
12996+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
12997+ against `aba'; then we want to ignore where we are now in
12998+ the string in case this attempt to match fails. */
12999+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
13000+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
13001+ : regend[*p];
13002+ DEBUG_PRINT2 (" old_regend: %d\n",
13003+ POINTER_TO_OFFSET (old_regend[*p]));
13004+
13005+ regend[*p] = d;
13006+ DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
13007+
13008+ /* This register isn't active anymore. */
13009+ IS_ACTIVE (reg_info[*p]) = 0;
13010+
13011+ /* Clear this whenever we change the register activity status. */
13012+ set_regs_matched_done = 0;
13013+
13014+ /* If this was the only register active, nothing is active
13015+ anymore. */
13016+ if (lowest_active_reg == highest_active_reg)
13017+ {
13018+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
13019+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
13020+ }
13021+ else
13022+ { /* We must scan for the new highest active register, since
13023+ it isn't necessarily one less than now: consider
13024+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
13025+ new highest active register is 1. */
13026+ UCHAR_T r = *p - 1;
13027+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
13028+ r--;
13029+
13030+ /* If we end up at register zero, that means that we saved
13031+ the registers as the result of an `on_failure_jump', not
13032+ a `start_memory', and we jumped to past the innermost
13033+ `stop_memory'. For example, in ((.)*) we save
13034+ registers 1 and 2 as a result of the *, but when we pop
13035+ back to the second ), we are at the stop_memory 1.
13036+ Thus, nothing is active. */
13037+ if (r == 0)
13038+ {
13039+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
13040+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
13041+ }
13042+ else
13043+ highest_active_reg = r;
13044+ }
13045+
13046+ /* If just failed to match something this time around with a
13047+ group that's operated on by a repetition operator, try to
13048+ force exit from the ``loop'', and restore the register
13049+ information for this group that we had before trying this
13050+ last match. */
13051+ if ((!MATCHED_SOMETHING (reg_info[*p])
13052+ || just_past_start_mem == p - 1)
13053+ && (p + 2) < pend)
13054+ {
13055+ boolean is_a_jump_n = false;
13056+
13057+ p1 = p + 2;
13058+ mcnt = 0;
13059+ switch ((re_opcode_t) *p1++)
13060+ {
13061+ case jump_n:
13062+ is_a_jump_n = true;
13063+ case pop_failure_jump:
13064+ case maybe_pop_jump:
13065+ case jump:
13066+ case dummy_failure_jump:
13067+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13068+ if (is_a_jump_n)
13069+ p1 += OFFSET_ADDRESS_SIZE;
13070+ break;
13071+
13072+ default:
13073+ /* do nothing */ ;
13074+ }
13075+ p1 += mcnt;
13076+
13077+ /* If the next operation is a jump backwards in the pattern
13078+ to an on_failure_jump right before the start_memory
13079+ corresponding to this stop_memory, exit from the loop
13080+ by forcing a failure after pushing on the stack the
13081+ on_failure_jump's jump in the pattern, and d. */
13082+ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
13083+ && (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == start_memory
13084+ && p1[2+OFFSET_ADDRESS_SIZE] == *p)
13085+ {
13086+ /* If this group ever matched anything, then restore
13087+ what its registers were before trying this last
13088+ failed match, e.g., with `(a*)*b' against `ab' for
13089+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
13090+ against `aba' for regend[3].
13091+
13092+ Also restore the registers for inner groups for,
13093+ e.g., `((a*)(b*))*' against `aba' (register 3 would
13094+ otherwise get trashed). */
13095+
13096+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
13097+ {
13098+ unsigned r;
13099+
13100+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
13101+
13102+ /* Restore this and inner groups' (if any) registers. */
13103+ for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1);
13104+ r++)
13105+ {
13106+ regstart[r] = old_regstart[r];
13107+
13108+ /* xx why this test? */
13109+ if (old_regend[r] >= regstart[r])
13110+ regend[r] = old_regend[r];
13111+ }
13112+ }
13113+ p1++;
13114+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13115+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
13116+
13117+ goto fail;
13118+ }
13119+ }
13120+
13121+ /* Move past the register number and the inner group count. */
13122+ p += 2;
13123+ break;
13124+
13125+
13126+ /* \<digit> has been turned into a `duplicate' command which is
13127+ followed by the numeric value of <digit> as the register number. */
13128+ case duplicate:
13129+ {
13130+ register const CHAR_T *d2, *dend2;
13131+ int regno = *p++; /* Get which register to match against. */
13132+ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
13133+
13134+ /* Can't back reference a group which we've never matched. */
13135+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
13136+ goto fail;
13137+
13138+ /* Where in input to try to start matching. */
13139+ d2 = regstart[regno];
13140+
13141+ /* Where to stop matching; if both the place to start and
13142+ the place to stop matching are in the same string, then
13143+ set to the place to stop, otherwise, for now have to use
13144+ the end of the first string. */
13145+
13146+ dend2 = ((FIRST_STRING_P (regstart[regno])
13147+ == FIRST_STRING_P (regend[regno]))
13148+ ? regend[regno] : end_match_1);
13149+ for (;;)
13150+ {
13151+ /* If necessary, advance to next segment in register
13152+ contents. */
13153+ while (d2 == dend2)
13154+ {
13155+ if (dend2 == end_match_2) break;
13156+ if (dend2 == regend[regno]) break;
13157+
13158+ /* End of string1 => advance to string2. */
13159+ d2 = string2;
13160+ dend2 = regend[regno];
13161+ }
13162+ /* At end of register contents => success */
13163+ if (d2 == dend2) break;
13164+
13165+ /* If necessary, advance to next segment in data. */
13166+ PREFETCH ();
13167+
13168+ /* How many characters left in this segment to match. */
13169+ mcnt = dend - d;
13170+
13171+ /* Want how many consecutive characters we can match in
13172+ one shot, so, if necessary, adjust the count. */
13173+ if (mcnt > dend2 - d2)
13174+ mcnt = dend2 - d2;
13175+
13176+ /* Compare that many; failure if mismatch, else move
13177+ past them. */
13178+ if (translate
13179+ ? PREFIX(bcmp_translate) (d, d2, mcnt, translate)
13180+ : memcmp (d, d2, mcnt*sizeof(UCHAR_T)))
13181+ goto fail;
13182+ d += mcnt, d2 += mcnt;
13183+
13184+ /* Do this because we've match some characters. */
13185+ SET_REGS_MATCHED ();
13186+ }
13187+ }
13188+ break;
13189+
13190+
13191+ /* begline matches the empty string at the beginning of the string
13192+ (unless `not_bol' is set in `bufp'), and, if
13193+ `newline_anchor' is set, after newlines. */
13194+ case begline:
13195+ DEBUG_PRINT1 ("EXECUTING begline.\n");
13196+
13197+ if (AT_STRINGS_BEG (d))
13198+ {
13199+ if (!bufp->not_bol) break;
13200+ }
13201+ else if (d[-1] == '\n' && bufp->newline_anchor)
13202+ {
13203+ break;
13204+ }
13205+ /* In all other cases, we fail. */
13206+ goto fail;
13207+
13208+
13209+ /* endline is the dual of begline. */
13210+ case endline:
13211+ DEBUG_PRINT1 ("EXECUTING endline.\n");
13212+
13213+ if (AT_STRINGS_END (d))
13214+ {
13215+ if (!bufp->not_eol) break;
13216+ }
13217+
13218+ /* We have to ``prefetch'' the next character. */
13219+ else if ((d == end1 ? *string2 : *d) == '\n'
13220+ && bufp->newline_anchor)
13221+ {
13222+ break;
13223+ }
13224+ goto fail;
13225+
13226+
13227+ /* Match at the very beginning of the data. */
13228+ case begbuf:
13229+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
13230+ if (AT_STRINGS_BEG (d))
13231+ break;
13232+ goto fail;
13233+
13234+
13235+ /* Match at the very end of the data. */
13236+ case endbuf:
13237+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
13238+ if (AT_STRINGS_END (d))
13239+ break;
13240+ goto fail;
13241+
13242+
13243+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
13244+ pushes NULL as the value for the string on the stack. Then
13245+ `pop_failure_point' will keep the current value for the
13246+ string, instead of restoring it. To see why, consider
13247+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
13248+ then the . fails against the \n. But the next thing we want
13249+ to do is match the \n against the \n; if we restored the
13250+ string value, we would be back at the foo.
13251+
13252+ Because this is used only in specific cases, we don't need to
13253+ check all the things that `on_failure_jump' does, to make
13254+ sure the right things get saved on the stack. Hence we don't
13255+ share its code. The only reason to push anything on the
13256+ stack at all is that otherwise we would have to change
13257+ `anychar's code to do something besides goto fail in this
13258+ case; that seems worse than this. */
13259+ case on_failure_keep_string_jump:
13260+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
13261+
13262+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
13263+#ifdef _LIBC
13264+ DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt);
13265+#else
13266+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
13267+#endif
13268+
13269+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
13270+ break;
13271+
13272+
13273+ /* Uses of on_failure_jump:
13274+
13275+ Each alternative starts with an on_failure_jump that points
13276+ to the beginning of the next alternative. Each alternative
13277+ except the last ends with a jump that in effect jumps past
13278+ the rest of the alternatives. (They really jump to the
13279+ ending jump of the following alternative, because tensioning
13280+ these jumps is a hassle.)
13281+
13282+ Repeats start with an on_failure_jump that points past both
13283+ the repetition text and either the following jump or
13284+ pop_failure_jump back to this on_failure_jump. */
13285+ case on_failure_jump:
13286+ on_failure:
13287+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
13288+
13289+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
13290+#ifdef _LIBC
13291+ DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt);
13292+#else
13293+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
13294+#endif
13295+
13296+ /* If this on_failure_jump comes right before a group (i.e.,
13297+ the original * applied to a group), save the information
13298+ for that group and all inner ones, so that if we fail back
13299+ to this point, the group's information will be correct.
13300+ For example, in \(a*\)*\1, we need the preceding group,
13301+ and in \(zz\(a*\)b*\)\2, we need the inner group. */
13302+
13303+ /* We can't use `p' to check ahead because we push
13304+ a failure point to `p + mcnt' after we do this. */
13305+ p1 = p;
13306+
13307+ /* We need to skip no_op's before we look for the
13308+ start_memory in case this on_failure_jump is happening as
13309+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
13310+ against aba. */
13311+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
13312+ p1++;
13313+
13314+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
13315+ {
13316+ /* We have a new highest active register now. This will
13317+ get reset at the start_memory we are about to get to,
13318+ but we will have saved all the registers relevant to
13319+ this repetition op, as described above. */
13320+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
13321+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
13322+ lowest_active_reg = *(p1 + 1);
13323+ }
13324+
13325+ DEBUG_PRINT1 (":\n");
13326+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
13327+ break;
13328+
13329+
13330+ /* A smart repeat ends with `maybe_pop_jump'.
13331+ We change it to either `pop_failure_jump' or `jump'. */
13332+ case maybe_pop_jump:
13333+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
13334+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
13335+ {
13336+ register UCHAR_T *p2 = p;
13337+
13338+ /* Compare the beginning of the repeat with what in the
13339+ pattern follows its end. If we can establish that there
13340+ is nothing that they would both match, i.e., that we
13341+ would have to backtrack because of (as in, e.g., `a*a')
13342+ then we can change to pop_failure_jump, because we'll
13343+ never have to backtrack.
13344+
13345+ This is not true in the case of alternatives: in
13346+ `(a|ab)*' we do need to backtrack to the `ab' alternative
13347+ (e.g., if the string was `ab'). But instead of trying to
13348+ detect that here, the alternative has put on a dummy
13349+ failure point which is what we will end up popping. */
13350+
13351+ /* Skip over open/close-group commands.
13352+ If what follows this loop is a ...+ construct,
13353+ look at what begins its body, since we will have to
13354+ match at least one of that. */
13355+ while (1)
13356+ {
13357+ if (p2 + 2 < pend
13358+ && ((re_opcode_t) *p2 == stop_memory
13359+ || (re_opcode_t) *p2 == start_memory))
13360+ p2 += 3;
13361+ else if (p2 + 2 + 2 * OFFSET_ADDRESS_SIZE < pend
13362+ && (re_opcode_t) *p2 == dummy_failure_jump)
13363+ p2 += 2 + 2 * OFFSET_ADDRESS_SIZE;
13364+ else
13365+ break;
13366+ }
13367+
13368+ p1 = p + mcnt;
13369+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
13370+ to the `maybe_finalize_jump' of this case. Examine what
13371+ follows. */
13372+
13373+ /* If we're at the end of the pattern, we can change. */
13374+ if (p2 == pend)
13375+ {
13376+ /* Consider what happens when matching ":\(.*\)"
13377+ against ":/". I don't really understand this code
13378+ yet. */
13379+ p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
13380+ pop_failure_jump;
13381+ DEBUG_PRINT1
13382+ (" End of pattern: change to `pop_failure_jump'.\n");
13383+ }
13384+
13385+ else if ((re_opcode_t) *p2 == exactn
13386+#ifdef MBS_SUPPORT
13387+ || (re_opcode_t) *p2 == exactn_bin
13388+#endif
13389+ || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
13390+ {
13391+ register UCHAR_T c
13392+ = *p2 == (UCHAR_T) endline ? '\n' : p2[2];
13393+
13394+ if (((re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn
13395+#ifdef MBS_SUPPORT
13396+ || (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn_bin
13397+#endif
13398+ ) && p1[3+OFFSET_ADDRESS_SIZE] != c)
13399+ {
13400+ p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
13401+ pop_failure_jump;
13402+#ifdef WCHAR
13403+ DEBUG_PRINT3 (" %C != %C => pop_failure_jump.\n",
13404+ (wint_t) c,
13405+ (wint_t) p1[3+OFFSET_ADDRESS_SIZE]);
13406+#else
13407+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
13408+ (char) c,
13409+ (char) p1[3+OFFSET_ADDRESS_SIZE]);
13410+#endif
13411+ }
13412+
13413+#ifndef WCHAR
13414+ else if ((re_opcode_t) p1[3] == charset
13415+ || (re_opcode_t) p1[3] == charset_not)
13416+ {
13417+ int negate = (re_opcode_t) p1[3] == charset_not;
13418+
13419+ if (c < (unsigned) (p1[4] * BYTEWIDTH)
13420+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
13421+ negate = !negate;
13422+
13423+ /* `negate' is equal to 1 if c would match, which means
13424+ that we can't change to pop_failure_jump. */
13425+ if (!negate)
13426+ {
13427+ p[-3] = (unsigned char) pop_failure_jump;
13428+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
13429+ }
13430+ }
13431+#endif /* not WCHAR */
13432+ }
13433+#ifndef WCHAR
13434+ else if ((re_opcode_t) *p2 == charset)
13435+ {
13436+ /* We win if the first character of the loop is not part
13437+ of the charset. */
13438+ if ((re_opcode_t) p1[3] == exactn
13439+ && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
13440+ && (p2[2 + p1[5] / BYTEWIDTH]
13441+ & (1 << (p1[5] % BYTEWIDTH)))))
13442+ {
13443+ p[-3] = (unsigned char) pop_failure_jump;
13444+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
13445+ }
13446+
13447+ else if ((re_opcode_t) p1[3] == charset_not)
13448+ {
13449+ int idx;
13450+ /* We win if the charset_not inside the loop
13451+ lists every character listed in the charset after. */
13452+ for (idx = 0; idx < (int) p2[1]; idx++)
13453+ if (! (p2[2 + idx] == 0
13454+ || (idx < (int) p1[4]
13455+ && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
13456+ break;
13457+
13458+ if (idx == p2[1])
13459+ {
13460+ p[-3] = (unsigned char) pop_failure_jump;
13461+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
13462+ }
13463+ }
13464+ else if ((re_opcode_t) p1[3] == charset)
13465+ {
13466+ int idx;
13467+ /* We win if the charset inside the loop
13468+ has no overlap with the one after the loop. */
13469+ for (idx = 0;
13470+ idx < (int) p2[1] && idx < (int) p1[4];
13471+ idx++)
13472+ if ((p2[2 + idx] & p1[5 + idx]) != 0)
13473+ break;
13474+
13475+ if (idx == p2[1] || idx == p1[4])
13476+ {
13477+ p[-3] = (unsigned char) pop_failure_jump;
13478+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
13479+ }
13480+ }
13481+ }
13482+#endif /* not WCHAR */
13483+ }
13484+ p -= OFFSET_ADDRESS_SIZE; /* Point at relative address again. */
13485+ if ((re_opcode_t) p[-1] != pop_failure_jump)
13486+ {
13487+ p[-1] = (UCHAR_T) jump;
13488+ DEBUG_PRINT1 (" Match => jump.\n");
13489+ goto unconditional_jump;
13490+ }
13491+ /* Note fall through. */
13492+
13493+
13494+ /* The end of a simple repeat has a pop_failure_jump back to
13495+ its matching on_failure_jump, where the latter will push a
13496+ failure point. The pop_failure_jump takes off failure
13497+ points put on by this pop_failure_jump's matching
13498+ on_failure_jump; we got through the pattern to here from the
13499+ matching on_failure_jump, so didn't fail. */
13500+ case pop_failure_jump:
13501+ {
13502+ /* We need to pass separate storage for the lowest and
13503+ highest registers, even though we don't care about the
13504+ actual values. Otherwise, we will restore only one
13505+ register from the stack, since lowest will == highest in
13506+ `pop_failure_point'. */
13507+ active_reg_t dummy_low_reg, dummy_high_reg;
13508+ UCHAR_T *pdummy __attribute__ ((unused)) = NULL;
13509+ const CHAR_T *sdummy __attribute__ ((unused)) = NULL;
13510+
13511+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
13512+ POP_FAILURE_POINT (sdummy, pdummy,
13513+ dummy_low_reg, dummy_high_reg,
13514+ reg_dummy, reg_dummy, reg_info_dummy);
13515+ }
13516+ /* Note fall through. */
13517+
13518+ unconditional_jump:
13519+#ifdef _LIBC
13520+ DEBUG_PRINT2 ("\n%p: ", p);
13521+#else
13522+ DEBUG_PRINT2 ("\n0x%x: ", p);
13523+#endif
13524+ /* Note fall through. */
13525+
13526+ /* Unconditionally jump (without popping any failure points). */
13527+ case jump:
13528+ EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
13529+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
13530+ p += mcnt; /* Do the jump. */
13531+#ifdef _LIBC
13532+ DEBUG_PRINT2 ("(to %p).\n", p);
13533+#else
13534+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
13535+#endif
13536+ break;
13537+
13538+
13539+ /* We need this opcode so we can detect where alternatives end
13540+ in `group_match_null_string_p' et al. */
13541+ case jump_past_alt:
13542+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
13543+ goto unconditional_jump;
13544+
13545+
13546+ /* Normally, the on_failure_jump pushes a failure point, which
13547+ then gets popped at pop_failure_jump. We will end up at
13548+ pop_failure_jump, also, and with a pattern of, say, `a+', we
13549+ are skipping over the on_failure_jump, so we have to push
13550+ something meaningless for pop_failure_jump to pop. */
13551+ case dummy_failure_jump:
13552+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
13553+ /* It doesn't matter what we push for the string here. What
13554+ the code at `fail' tests is the value for the pattern. */
13555+ PUSH_FAILURE_POINT (NULL, NULL, -2);
13556+ goto unconditional_jump;
13557+
13558+
13559+ /* At the end of an alternative, we need to push a dummy failure
13560+ point in case we are followed by a `pop_failure_jump', because
13561+ we don't want the failure point for the alternative to be
13562+ popped. For example, matching `(a|ab)*' against `aab'
13563+ requires that we match the `ab' alternative. */
13564+ case push_dummy_failure:
13565+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
13566+ /* See comments just above at `dummy_failure_jump' about the
13567+ two zeroes. */
13568+ PUSH_FAILURE_POINT (NULL, NULL, -2);
13569+ break;
13570+
13571+ /* Have to succeed matching what follows at least n times.
13572+ After that, handle like `on_failure_jump'. */
13573+ case succeed_n:
13574+ EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
13575+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
13576+
13577+ assert (mcnt >= 0);
13578+ /* Originally, this is how many times we HAVE to succeed. */
13579+ if (mcnt > 0)
13580+ {
13581+ mcnt--;
13582+ p += OFFSET_ADDRESS_SIZE;
13583+ STORE_NUMBER_AND_INCR (p, mcnt);
13584+#ifdef _LIBC
13585+ DEBUG_PRINT3 (" Setting %p to %d.\n", p - OFFSET_ADDRESS_SIZE
13586+ , mcnt);
13587+#else
13588+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - OFFSET_ADDRESS_SIZE
13589+ , mcnt);
13590+#endif
13591+ }
13592+ else if (mcnt == 0)
13593+ {
13594+#ifdef _LIBC
13595+ DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n",
13596+ p + OFFSET_ADDRESS_SIZE);
13597+#else
13598+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n",
13599+ p + OFFSET_ADDRESS_SIZE);
13600+#endif /* _LIBC */
13601+
13602+#ifdef WCHAR
13603+ p[1] = (UCHAR_T) no_op;
13604+#else
13605+ p[2] = (UCHAR_T) no_op;
13606+ p[3] = (UCHAR_T) no_op;
13607+#endif /* WCHAR */
13608+ goto on_failure;
13609+ }
13610+ break;
13611+
13612+ case jump_n:
13613+ EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
13614+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
13615+
13616+ /* Originally, this is how many times we CAN jump. */
13617+ if (mcnt)
13618+ {
13619+ mcnt--;
13620+ STORE_NUMBER (p + OFFSET_ADDRESS_SIZE, mcnt);
13621+
13622+#ifdef _LIBC
13623+ DEBUG_PRINT3 (" Setting %p to %d.\n", p + OFFSET_ADDRESS_SIZE,
13624+ mcnt);
13625+#else
13626+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + OFFSET_ADDRESS_SIZE,
13627+ mcnt);
13628+#endif /* _LIBC */
13629+ goto unconditional_jump;
13630+ }
13631+ /* If don't have to jump any more, skip over the rest of command. */
13632+ else
13633+ p += 2 * OFFSET_ADDRESS_SIZE;
13634+ break;
13635+
13636+ case set_number_at:
13637+ {
13638+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
13639+
13640+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
13641+ p1 = p + mcnt;
13642+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
13643+#ifdef _LIBC
13644+ DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt);
13645+#else
13646+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
13647+#endif
13648+ STORE_NUMBER (p1, mcnt);
13649+ break;
13650+ }
13651+
13652+#if 0
13653+ /* The DEC Alpha C compiler 3.x generates incorrect code for the
13654+ test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of
13655+ AT_WORD_BOUNDARY, so this code is disabled. Expanding the
13656+ macro and introducing temporary variables works around the bug. */
13657+
13658+ case wordbound:
13659+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
13660+ if (AT_WORD_BOUNDARY (d))
13661+ break;
13662+ goto fail;
13663+
13664+ case notwordbound:
13665+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
13666+ if (AT_WORD_BOUNDARY (d))
13667+ goto fail;
13668+ break;
13669+#else
13670+ case wordbound:
13671+ {
13672+ boolean prevchar, thischar;
13673+
13674+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
13675+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
13676+ break;
13677+
13678+ prevchar = WORDCHAR_P (d - 1);
13679+ thischar = WORDCHAR_P (d);
13680+ if (prevchar != thischar)
13681+ break;
13682+ goto fail;
13683+ }
13684+
13685+ case notwordbound:
13686+ {
13687+ boolean prevchar, thischar;
13688+
13689+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
13690+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
13691+ goto fail;
13692+
13693+ prevchar = WORDCHAR_P (d - 1);
13694+ thischar = WORDCHAR_P (d);
13695+ if (prevchar != thischar)
13696+ goto fail;
13697+ break;
13698+ }
13699+#endif
13700+
13701+ case wordbeg:
13702+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
13703+ if (!AT_STRINGS_END (d) && WORDCHAR_P (d)
13704+ && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
13705+ break;
13706+ goto fail;
13707+
13708+ case wordend:
13709+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
13710+ if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
13711+ && (AT_STRINGS_END (d) || !WORDCHAR_P (d)))
13712+ break;
13713+ goto fail;
13714+
13715+#ifdef emacs
13716+ case before_dot:
13717+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
13718+ if (PTR_CHAR_POS ((unsigned char *) d) >= point)
13719+ goto fail;
13720+ break;
13721+
13722+ case at_dot:
13723+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
13724+ if (PTR_CHAR_POS ((unsigned char *) d) != point)
13725+ goto fail;
13726+ break;
13727+
13728+ case after_dot:
13729+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
13730+ if (PTR_CHAR_POS ((unsigned char *) d) <= point)
13731+ goto fail;
13732+ break;
13733+
13734+ case syntaxspec:
13735+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
13736+ mcnt = *p++;
13737+ goto matchsyntax;
13738+
13739+ case wordchar:
13740+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
13741+ mcnt = (int) Sword;
13742+ matchsyntax:
13743+ PREFETCH ();
13744+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
13745+ d++;
13746+ if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
13747+ goto fail;
13748+ SET_REGS_MATCHED ();
13749+ break;
13750+
13751+ case notsyntaxspec:
13752+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
13753+ mcnt = *p++;
13754+ goto matchnotsyntax;
13755+
13756+ case notwordchar:
13757+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
13758+ mcnt = (int) Sword;
13759+ matchnotsyntax:
13760+ PREFETCH ();
13761+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
13762+ d++;
13763+ if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
13764+ goto fail;
13765+ SET_REGS_MATCHED ();
13766+ break;
13767+
13768+#else /* not emacs */
13769+ case wordchar:
13770+ DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
13771+ PREFETCH ();
13772+ if (!WORDCHAR_P (d))
13773+ goto fail;
13774+ SET_REGS_MATCHED ();
13775+ d++;
13776+ break;
13777+
13778+ case notwordchar:
13779+ DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
13780+ PREFETCH ();
13781+ if (WORDCHAR_P (d))
13782+ goto fail;
13783+ SET_REGS_MATCHED ();
13784+ d++;
13785+ break;
13786+#endif /* not emacs */
13787+
13788+ default:
13789+ abort ();
13790+ }
13791+ continue; /* Successfully executed one pattern command; keep going. */
13792+
13793+
13794+ /* We goto here if a matching operation fails. */
13795+ fail:
13796+ if (!FAIL_STACK_EMPTY ())
13797+ { /* A restart point is known. Restore to that state. */
13798+ DEBUG_PRINT1 ("\nFAIL:\n");
13799+ POP_FAILURE_POINT (d, p,
13800+ lowest_active_reg, highest_active_reg,
13801+ regstart, regend, reg_info);
13802+
13803+ /* If this failure point is a dummy, try the next one. */
13804+ if (!p)
13805+ goto fail;
13806+
13807+ /* If we failed to the end of the pattern, don't examine *p. */
13808+ assert (p <= pend);
13809+ if (p < pend)
13810+ {
13811+ boolean is_a_jump_n = false;
13812+
13813+ /* If failed to a backwards jump that's part of a repetition
13814+ loop, need to pop this failure point and use the next one. */
13815+ switch ((re_opcode_t) *p)
13816+ {
13817+ case jump_n:
13818+ is_a_jump_n = true;
13819+ case maybe_pop_jump:
13820+ case pop_failure_jump:
13821+ case jump:
13822+ p1 = p + 1;
13823+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13824+ p1 += mcnt;
13825+
13826+ if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
13827+ || (!is_a_jump_n
13828+ && (re_opcode_t) *p1 == on_failure_jump))
13829+ goto fail;
13830+ break;
13831+ default:
13832+ /* do nothing */ ;
13833+ }
13834+ }
13835+
13836+ if (d >= string1 && d <= end1)
13837+ dend = end_match_1;
13838+ }
13839+ else
13840+ break; /* Matching at this starting point really fails. */
13841+ } /* for (;;) */
13842+
13843+ if (best_regs_set)
13844+ goto restore_best_regs;
13845+
13846+ FREE_VARIABLES ();
13847+
13848+ return -1; /* Failure to match. */
13849+} /* re_match_2 */
13850+
13851+/* Subroutine definitions for re_match_2. */
13852+
13853+
13854+/* We are passed P pointing to a register number after a start_memory.
13855+
13856+ Return true if the pattern up to the corresponding stop_memory can
13857+ match the empty string, and false otherwise.
13858+
13859+ If we find the matching stop_memory, sets P to point to one past its number.
13860+ Otherwise, sets P to an undefined byte less than or equal to END.
13861+
13862+ We don't handle duplicates properly (yet). */
13863+
13864+static boolean
13865+PREFIX(group_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
13866+ PREFIX(register_info_type) *reg_info)
13867+{
13868+ int mcnt;
13869+ /* Point to after the args to the start_memory. */
13870+ UCHAR_T *p1 = *p + 2;
13871+
13872+ while (p1 < end)
13873+ {
13874+ /* Skip over opcodes that can match nothing, and return true or
13875+ false, as appropriate, when we get to one that can't, or to the
13876+ matching stop_memory. */
13877+
13878+ switch ((re_opcode_t) *p1)
13879+ {
13880+ /* Could be either a loop or a series of alternatives. */
13881+ case on_failure_jump:
13882+ p1++;
13883+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13884+
13885+ /* If the next operation is not a jump backwards in the
13886+ pattern. */
13887+
13888+ if (mcnt >= 0)
13889+ {
13890+ /* Go through the on_failure_jumps of the alternatives,
13891+ seeing if any of the alternatives cannot match nothing.
13892+ The last alternative starts with only a jump,
13893+ whereas the rest start with on_failure_jump and end
13894+ with a jump, e.g., here is the pattern for `a|b|c':
13895+
13896+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
13897+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
13898+ /exactn/1/c
13899+
13900+ So, we have to first go through the first (n-1)
13901+ alternatives and then deal with the last one separately. */
13902+
13903+
13904+ /* Deal with the first (n-1) alternatives, which start
13905+ with an on_failure_jump (see above) that jumps to right
13906+ past a jump_past_alt. */
13907+
13908+ while ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] ==
13909+ jump_past_alt)
13910+ {
13911+ /* `mcnt' holds how many bytes long the alternative
13912+ is, including the ending `jump_past_alt' and
13913+ its number. */
13914+
13915+ if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt -
13916+ (1 + OFFSET_ADDRESS_SIZE),
13917+ reg_info))
13918+ return false;
13919+
13920+ /* Move to right after this alternative, including the
13921+ jump_past_alt. */
13922+ p1 += mcnt;
13923+
13924+ /* Break if it's the beginning of an n-th alternative
13925+ that doesn't begin with an on_failure_jump. */
13926+ if ((re_opcode_t) *p1 != on_failure_jump)
13927+ break;
13928+
13929+ /* Still have to check that it's not an n-th
13930+ alternative that starts with an on_failure_jump. */
13931+ p1++;
13932+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13933+ if ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] !=
13934+ jump_past_alt)
13935+ {
13936+ /* Get to the beginning of the n-th alternative. */
13937+ p1 -= 1 + OFFSET_ADDRESS_SIZE;
13938+ break;
13939+ }
13940+ }
13941+
13942+ /* Deal with the last alternative: go back and get number
13943+ of the `jump_past_alt' just before it. `mcnt' contains
13944+ the length of the alternative. */
13945+ EXTRACT_NUMBER (mcnt, p1 - OFFSET_ADDRESS_SIZE);
13946+
13947+ if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt, reg_info))
13948+ return false;
13949+
13950+ p1 += mcnt; /* Get past the n-th alternative. */
13951+ } /* if mcnt > 0 */
13952+ break;
13953+
13954+
13955+ case stop_memory:
13956+ assert (p1[1] == **p);
13957+ *p = p1 + 2;
13958+ return true;
13959+
13960+
13961+ default:
13962+ if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
13963+ return false;
13964+ }
13965+ } /* while p1 < end */
13966+
13967+ return false;
13968+} /* group_match_null_string_p */
13969+
13970+
13971+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
13972+ It expects P to be the first byte of a single alternative and END one
13973+ byte past the last. The alternative can contain groups. */
13974+
13975+static boolean
13976+PREFIX(alt_match_null_string_p) (UCHAR_T *p, UCHAR_T *end,
13977+ PREFIX(register_info_type) *reg_info)
13978+{
13979+ int mcnt;
13980+ UCHAR_T *p1 = p;
13981+
13982+ while (p1 < end)
13983+ {
13984+ /* Skip over opcodes that can match nothing, and break when we get
13985+ to one that can't. */
13986+
13987+ switch ((re_opcode_t) *p1)
13988+ {
13989+ /* It's a loop. */
13990+ case on_failure_jump:
13991+ p1++;
13992+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13993+ p1 += mcnt;
13994+ break;
13995+
13996+ default:
13997+ if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
13998+ return false;
13999+ }
14000+ } /* while p1 < end */
14001+
14002+ return true;
14003+} /* alt_match_null_string_p */
14004+
14005+
14006+/* Deals with the ops common to group_match_null_string_p and
14007+ alt_match_null_string_p.
14008+
14009+ Sets P to one after the op and its arguments, if any. */
14010+
14011+static boolean
14012+PREFIX(common_op_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
14013+ PREFIX(register_info_type) *reg_info)
14014+{
14015+ int mcnt;
14016+ boolean ret;
14017+ int reg_no;
14018+ UCHAR_T *p1 = *p;
14019+
14020+ switch ((re_opcode_t) *p1++)
14021+ {
14022+ case no_op:
14023+ case begline:
14024+ case endline:
14025+ case begbuf:
14026+ case endbuf:
14027+ case wordbeg:
14028+ case wordend:
14029+ case wordbound:
14030+ case notwordbound:
14031+#ifdef emacs
14032+ case before_dot:
14033+ case at_dot:
14034+ case after_dot:
14035+#endif
14036+ break;
14037+
14038+ case start_memory:
14039+ reg_no = *p1;
14040+ assert (reg_no > 0 && reg_no <= MAX_REGNUM);
14041+ ret = PREFIX(group_match_null_string_p) (&p1, end, reg_info);
14042+
14043+ /* Have to set this here in case we're checking a group which
14044+ contains a group and a back reference to it. */
14045+
14046+ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
14047+ REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
14048+
14049+ if (!ret)
14050+ return false;
14051+ break;
14052+
14053+ /* If this is an optimized succeed_n for zero times, make the jump. */
14054+ case jump:
14055+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
14056+ if (mcnt >= 0)
14057+ p1 += mcnt;
14058+ else
14059+ return false;
14060+ break;
14061+
14062+ case succeed_n:
14063+ /* Get to the number of times to succeed. */
14064+ p1 += OFFSET_ADDRESS_SIZE;
14065+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
14066+
14067+ if (mcnt == 0)
14068+ {
14069+ p1 -= 2 * OFFSET_ADDRESS_SIZE;
14070+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
14071+ p1 += mcnt;
14072+ }
14073+ else
14074+ return false;
14075+ break;
14076+
14077+ case duplicate:
14078+ if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
14079+ return false;
14080+ break;
14081+
14082+ case set_number_at:
14083+ p1 += 2 * OFFSET_ADDRESS_SIZE;
14084+
14085+ default:
14086+ /* All other opcodes mean we cannot match the empty string. */
14087+ return false;
14088+ }
14089+
14090+ *p = p1;
14091+ return true;
14092+} /* common_op_match_null_string_p */
14093+
14094+
14095+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
14096+ bytes; nonzero otherwise. */
14097+
14098+static int
14099+PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, register int len,
14100+ RE_TRANSLATE_TYPE translate)
14101+{
14102+ register const UCHAR_T *p1 = (const UCHAR_T *) s1;
14103+ register const UCHAR_T *p2 = (const UCHAR_T *) s2;
14104+ while (len)
14105+ {
14106+#ifdef WCHAR
14107+ if (((*p1<=0xff)?translate[*p1++]:*p1++)
14108+ != ((*p2<=0xff)?translate[*p2++]:*p2++))
14109+ return 1;
14110+#else /* BYTE */
14111+ if (translate[*p1++] != translate[*p2++]) return 1;
14112+#endif /* WCHAR */
14113+ len--;
14114+ }
14115+ return 0;
14116+}
14117+
14118+
14119+#else /* not INSIDE_RECURSION */
14120+
14121+/* Entry points for GNU code. */
14122+
14123+/* re_compile_pattern is the GNU regular expression compiler: it
14124+ compiles PATTERN (of length SIZE) and puts the result in BUFP.
14125+ Returns 0 if the pattern was valid, otherwise an error string.
14126+
14127+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields
14128+ are set in BUFP on entry.
14129+
14130+ We call regex_compile to do the actual compilation. */
14131+
14132+const char *
14133+re_compile_pattern (const char *pattern, size_t length,
14134+ struct re_pattern_buffer *bufp)
14135+{
14136+ reg_errcode_t ret;
14137+
14138+ /* GNU code is written to assume at least RE_NREGS registers will be set
14139+ (and at least one extra will be -1). */
14140+ bufp->regs_allocated = REGS_UNALLOCATED;
14141+
14142+ /* And GNU code determines whether or not to get register information
14143+ by passing null for the REGS argument to re_match, etc., not by
14144+ setting no_sub. */
14145+ bufp->no_sub = 0;
14146+
14147+ /* Match anchors at newline. */
14148+ bufp->newline_anchor = 1;
14149+
14150+# ifdef MBS_SUPPORT
14151+ if (MB_CUR_MAX != 1)
14152+ ret = wcs_regex_compile (pattern, length, re_syntax_options, bufp);
14153+ else
14154+# endif
14155+ ret = byte_regex_compile (pattern, length, re_syntax_options, bufp);
14156+
14157+ if (!ret)
14158+ return NULL;
14159+ return gettext (re_error_msgid[(int) ret]);
14160+}
14161+#ifdef _LIBC
14162+weak_alias (__re_compile_pattern, re_compile_pattern)
14163+#endif
14164+
14165+/* Entry points compatible with 4.2 BSD regex library. We don't define
14166+ them unless specifically requested. */
14167+
14168+#if defined _REGEX_RE_COMP || defined _LIBC
14169+
14170+/* BSD has one and only one pattern buffer. */
14171+static struct re_pattern_buffer re_comp_buf;
14172+
14173+char *
14174+#ifdef _LIBC
14175+/* Make these definitions weak in libc, so POSIX programs can redefine
14176+ these names if they don't use our functions, and still use
14177+ regcomp/regexec below without link errors. */
14178+weak_function
14179+#endif
14180+re_comp (const char *s)
14181+{
14182+ reg_errcode_t ret;
14183+
14184+ if (!s)
14185+ {
14186+ if (!re_comp_buf.buffer)
14187+ return (char *) gettext ("No previous regular expression");
14188+ return 0;
14189+ }
14190+
14191+ if (!re_comp_buf.buffer)
14192+ {
14193+ re_comp_buf.buffer = (unsigned char *) malloc (200);
14194+ if (re_comp_buf.buffer == NULL)
14195+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
14196+ re_comp_buf.allocated = 200;
14197+
14198+ re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
14199+ if (re_comp_buf.fastmap == NULL)
14200+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
14201+ }
14202+
14203+ /* Since `re_exec' always passes NULL for the `regs' argument, we
14204+ don't need to initialize the pattern buffer fields which affect it. */
14205+
14206+ /* Match anchors at newlines. */
14207+ re_comp_buf.newline_anchor = 1;
14208+
14209+# ifdef MBS_SUPPORT
14210+ if (MB_CUR_MAX != 1)
14211+ ret = wcs_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
14212+ else
14213+# endif
14214+ ret = byte_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
14215+
14216+ if (!ret)
14217+ return NULL;
14218+
14219+ /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */
14220+ return (char *) gettext (re_error_msgid[(int) ret]);
14221+}
14222+
14223+
14224+int
14225+#ifdef _LIBC
14226+weak_function
14227+#endif
14228+re_exec (const char *s)
14229+{
14230+ const int len = strlen (s);
14231+ return
14232+ 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
14233+}
14234+
14235+#endif /* _REGEX_RE_COMP */
14236+
14237+/* POSIX.2 functions. Don't define these for Emacs. */
14238+
14239+#ifndef emacs
14240+
14241+/* regcomp takes a regular expression as a string and compiles it.
14242+
14243+ PREG is a regex_t *. We do not expect any fields to be initialized,
14244+ since POSIX says we shouldn't. Thus, we set
14245+
14246+ `buffer' to the compiled pattern;
14247+ `used' to the length of the compiled pattern;
14248+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
14249+ REG_EXTENDED bit in CFLAGS is set; otherwise, to
14250+ RE_SYNTAX_POSIX_BASIC;
14251+ `newline_anchor' to REG_NEWLINE being set in CFLAGS;
14252+ `fastmap' to an allocated space for the fastmap;
14253+ `fastmap_accurate' to zero;
14254+ `re_nsub' to the number of subexpressions in PATTERN.
14255+
14256+ PATTERN is the address of the pattern string.
14257+
14258+ CFLAGS is a series of bits which affect compilation.
14259+
14260+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
14261+ use POSIX basic syntax.
14262+
14263+ If REG_NEWLINE is set, then . and [^...] don't match newline.
14264+ Also, regexec will try a match beginning after every newline.
14265+
14266+ If REG_ICASE is set, then we considers upper- and lowercase
14267+ versions of letters to be equivalent when matching.
14268+
14269+ If REG_NOSUB is set, then when PREG is passed to regexec, that
14270+ routine will report only success or failure, and nothing about the
14271+ registers.
14272+
14273+ It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
14274+ the return codes and their meanings.) */
14275+
14276+int
14277+regcomp (regex_t *preg, const char *pattern, int cflags)
14278+{
14279+ reg_errcode_t ret;
14280+ reg_syntax_t syntax
14281+ = (cflags & REG_EXTENDED) ?
14282+ RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
14283+
14284+ /* regex_compile will allocate the space for the compiled pattern. */
14285+ preg->buffer = 0;
14286+ preg->allocated = 0;
14287+ preg->used = 0;
14288+
14289+ /* Try to allocate space for the fastmap. */
14290+ preg->fastmap = (char *) malloc (1 << BYTEWIDTH);
14291+
14292+ if (cflags & REG_ICASE)
14293+ {
14294+ int i;
14295+
14296+ preg->translate
14297+ = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
14298+ * sizeof (*(RE_TRANSLATE_TYPE)0));
14299+ if (preg->translate == NULL)
14300+ return (int) REG_ESPACE;
14301+
14302+ /* Map uppercase characters to corresponding lowercase ones. */
14303+ for (i = 0; i < CHAR_SET_SIZE; i++)
14304+ preg->translate[i] = ISUPPER (i) ? TOLOWER (i) : i;
14305+ }
14306+ else
14307+ preg->translate = NULL;
14308+
14309+ /* If REG_NEWLINE is set, newlines are treated differently. */
14310+ if (cflags & REG_NEWLINE)
14311+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */
14312+ syntax &= ~RE_DOT_NEWLINE;
14313+ syntax |= RE_HAT_LISTS_NOT_NEWLINE;
14314+ /* It also changes the matching behavior. */
14315+ preg->newline_anchor = 1;
14316+ }
14317+ else
14318+ preg->newline_anchor = 0;
14319+
14320+ preg->no_sub = !!(cflags & REG_NOSUB);
14321+
14322+ /* POSIX says a null character in the pattern terminates it, so we
14323+ can use strlen here in compiling the pattern. */
14324+# ifdef MBS_SUPPORT
14325+ if (MB_CUR_MAX != 1)
14326+ ret = wcs_regex_compile (pattern, strlen (pattern), syntax, preg);
14327+ else
14328+# endif
14329+ ret = byte_regex_compile (pattern, strlen (pattern), syntax, preg);
14330+
14331+ /* POSIX doesn't distinguish between an unmatched open-group and an
14332+ unmatched close-group: both are REG_EPAREN. */
14333+ if (ret == REG_ERPAREN) ret = REG_EPAREN;
14334+
14335+ if (ret == REG_NOERROR && preg->fastmap)
14336+ {
14337+ /* Compute the fastmap now, since regexec cannot modify the pattern
14338+ buffer. */
14339+ if (re_compile_fastmap (preg) == -2)
14340+ {
14341+ /* Some error occurred while computing the fastmap, just forget
14342+ about it. */
14343+ free (preg->fastmap);
14344+ preg->fastmap = NULL;
14345+ }
14346+ }
14347+
14348+ return (int) ret;
14349+}
14350+#ifdef _LIBC
14351+weak_alias (__regcomp, regcomp)
14352+#endif
14353+
14354+
14355+/* regexec searches for a given pattern, specified by PREG, in the
14356+ string STRING.
14357+
14358+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to
14359+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
14360+ least NMATCH elements, and we set them to the offsets of the
14361+ corresponding matched substrings.
14362+
14363+ EFLAGS specifies `execution flags' which affect matching: if
14364+ REG_NOTBOL is set, then ^ does not match at the beginning of the
14365+ string; if REG_NOTEOL is set, then $ does not match at the end.
14366+
14367+ We return 0 if we find a match and REG_NOMATCH if not. */
14368+
14369+int
14370+regexec (const regex_t *preg, const char *string, size_t nmatch,
14371+ regmatch_t pmatch[], int eflags)
14372+{
14373+ int ret;
14374+ struct re_registers regs;
14375+ regex_t private_preg;
14376+ int len = strlen (string);
14377+ boolean want_reg_info = !preg->no_sub && nmatch > 0;
14378+
14379+ private_preg = *preg;
14380+
14381+ private_preg.not_bol = !!(eflags & REG_NOTBOL);
14382+ private_preg.not_eol = !!(eflags & REG_NOTEOL);
14383+
14384+ /* The user has told us exactly how many registers to return
14385+ information about, via `nmatch'. We have to pass that on to the
14386+ matching routines. */
14387+ private_preg.regs_allocated = REGS_FIXED;
14388+
14389+ if (want_reg_info)
14390+ {
14391+ regs.num_regs = nmatch;
14392+ regs.start = TALLOC (nmatch * 2, regoff_t);
14393+ if (regs.start == NULL)
14394+ return (int) REG_NOMATCH;
14395+ regs.end = regs.start + nmatch;
14396+ }
14397+
14398+ /* Perform the searching operation. */
14399+ ret = re_search (&private_preg, string, len,
14400+ /* start: */ 0, /* range: */ len,
14401+ want_reg_info ? &regs : (struct re_registers *) 0);
14402+
14403+ /* Copy the register information to the POSIX structure. */
14404+ if (want_reg_info)
14405+ {
14406+ if (ret >= 0)
14407+ {
14408+ unsigned r;
14409+
14410+ for (r = 0; r < nmatch; r++)
14411+ {
14412+ pmatch[r].rm_so = regs.start[r];
14413+ pmatch[r].rm_eo = regs.end[r];
14414+ }
14415+ }
14416+
14417+ /* If we needed the temporary register info, free the space now. */
14418+ free (regs.start);
14419+ }
14420+
14421+ /* We want zero return to mean success, unlike `re_search'. */
14422+ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
14423+}
14424+#ifdef _LIBC
14425+/* EGLIBC: This is handled in regexec-compat.c. */
14426+/*weak_alias (__regexec, regexec)*/
14427+#include "regexec-compat.c"
14428+#endif
14429+
14430+
14431+/* Returns a message corresponding to an error code, ERRCODE, returned
14432+ from either regcomp or regexec. We don't use PREG here. */
14433+
14434+size_t
14435+regerror (int errcode, const regex_t *preg __attribute__ ((unused)),
14436+ char *errbuf, size_t errbuf_size)
14437+{
14438+ const char *msg;
14439+ size_t msg_size;
14440+
14441+ if (errcode < 0
14442+ || errcode >= (int) (sizeof (re_error_msgid)
14443+ / sizeof (re_error_msgid[0])))
14444+ /* Only error codes returned by the rest of the code should be passed
14445+ to this routine. If we are given anything else, or if other regex
14446+ code generates an invalid error code, then the program has a bug.
14447+ Dump core so we can fix it. */
14448+ abort ();
14449+
14450+ msg = gettext (re_error_msgid[errcode]);
14451+
14452+ msg_size = strlen (msg) + 1; /* Includes the null. */
14453+
14454+ if (errbuf_size != 0)
14455+ {
14456+ if (msg_size > errbuf_size)
14457+ {
14458+#if defined HAVE_MEMPCPY || defined _LIBC
14459+ *((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
14460+#else
14461+ memcpy (errbuf, msg, errbuf_size - 1);
14462+ errbuf[errbuf_size - 1] = 0;
14463+#endif
14464+ }
14465+ else
14466+ memcpy (errbuf, msg, msg_size);
14467+ }
14468+
14469+ return msg_size;
14470+}
14471+#ifdef _LIBC
14472+weak_alias (__regerror, regerror)
14473+#endif
14474+
14475+
14476+/* Free dynamically allocated space used by PREG. */
14477+
14478+void
14479+regfree (regex_t *preg)
14480+{
14481+ if (preg->buffer != NULL)
14482+ free (preg->buffer);
14483+ preg->buffer = NULL;
14484+
14485+ preg->allocated = 0;
14486+ preg->used = 0;
14487+
14488+ if (preg->fastmap != NULL)
14489+ free (preg->fastmap);
14490+ preg->fastmap = NULL;
14491+ preg->fastmap_accurate = 0;
14492+
14493+ if (preg->translate != NULL)
14494+ free (preg->translate);
14495+ preg->translate = NULL;
14496+}
14497+#ifdef _LIBC
14498+weak_alias (__regfree, regfree)
14499+#endif
14500+
14501+#endif /* not emacs */
14502+
14503+#endif /* not INSIDE_RECURSION */
14504+
14505+
14506+#undef STORE_NUMBER
14507+#undef STORE_NUMBER_AND_INCR
14508+#undef EXTRACT_NUMBER
14509+#undef EXTRACT_NUMBER_AND_INCR
14510+
14511+#undef DEBUG_PRINT_COMPILED_PATTERN
14512+#undef DEBUG_PRINT_DOUBLE_STRING
14513+
14514+#undef INIT_FAIL_STACK
14515+#undef RESET_FAIL_STACK
14516+#undef DOUBLE_FAIL_STACK
14517+#undef PUSH_PATTERN_OP
14518+#undef PUSH_FAILURE_POINTER
14519+#undef PUSH_FAILURE_INT
14520+#undef PUSH_FAILURE_ELT
14521+#undef POP_FAILURE_POINTER
14522+#undef POP_FAILURE_INT
14523+#undef POP_FAILURE_ELT
14524+#undef DEBUG_PUSH
14525+#undef DEBUG_POP
14526+#undef PUSH_FAILURE_POINT
14527+#undef POP_FAILURE_POINT
14528+
14529+#undef REG_UNSET_VALUE
14530+#undef REG_UNSET
14531+
14532+#undef PATFETCH
14533+#undef PATFETCH_RAW
14534+#undef PATUNFETCH
14535+#undef TRANSLATE
14536+
14537+#undef INIT_BUF_SIZE
14538+#undef GET_BUFFER_SPACE
14539+#undef BUF_PUSH
14540+#undef BUF_PUSH_2
14541+#undef BUF_PUSH_3
14542+#undef STORE_JUMP
14543+#undef STORE_JUMP2
14544+#undef INSERT_JUMP
14545+#undef INSERT_JUMP2
14546+#undef EXTEND_BUFFER
14547+#undef GET_UNSIGNED_NUMBER
14548+#undef FREE_STACK_RETURN
14549+
14550+# undef POINTER_TO_OFFSET
14551+# undef MATCHING_IN_FRST_STRING
14552+# undef PREFETCH
14553+# undef AT_STRINGS_BEG
14554+# undef AT_STRINGS_END
14555+# undef WORDCHAR_P
14556+# undef FREE_VAR
14557+# undef FREE_VARIABLES
14558+# undef NO_HIGHEST_ACTIVE_REG
14559+# undef NO_LOWEST_ACTIVE_REG
14560+
14561+# undef CHAR_T
14562+# undef UCHAR_T
14563+# undef COMPILED_BUFFER_VAR
14564+# undef OFFSET_ADDRESS_SIZE
14565+# undef CHAR_CLASS_SIZE
14566+# undef PREFIX
14567+# undef ARG_PREFIX
14568+# undef PUT_CHAR
14569+# undef BYTE
14570+# undef WCHAR
14571+
14572+# define DEFINED_ONCE
14573diff --git a/pwd/Makefile b/pwd/Makefile
14574index 7f6de03..916d546 100644
14575--- a/pwd/Makefile
14576+++ b/pwd/Makefile
14577@@ -18,6 +18,8 @@
14578 #
14579 # Sub-makefile for pwd portion of the library.
14580 #
14581+include ../option-groups.mak
14582+
14583 subdir := pwd
14584
14585 include ../Makeconfig
14586diff --git a/resolv/Makefile b/resolv/Makefile
14587index 1dcb75f..2e4b630 100644
14588--- a/resolv/Makefile
14589+++ b/resolv/Makefile
14590@@ -18,6 +18,8 @@
14591 #
14592 # Sub-makefile for resolv portion of the library.
14593 #
14594+include ../option-groups.mak
14595+
14596 subdir := resolv
14597
14598 include ../Makeconfig
14599@@ -27,21 +29,22 @@ headers := resolv.h \
14600 arpa/nameser.h arpa/nameser_compat.h \
14601 sys/bitypes.h
14602
14603-routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
14604- res_hconf res_libc res-state
14605+routines-$(OPTION_EGLIBC_INET) \
14606+ += herror inet_addr inet_ntop inet_pton nsap_addr res_init \
14607+ res_hconf res_libc res-state
14608
14609-tests = tst-aton tst-leaks tst-inet_ntop
14610-xtests = tst-leaks2
14611+tests-$(OPTION_EGLIBC_INET) += tst-aton tst-leaks tst-inet_ntop
14612+xtests-$(OPTION_EGLIBC_INET) += tst-leaks2
14613
14614 generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
14615
14616-extra-libs := libresolv libnss_dns
14617+extra-libs-$(OPTION_EGLIBC_INET) += libresolv libnss_dns
14618 ifeq ($(have-thread-library),yes)
14619-extra-libs += libanl
14620-routines += gai_sigqueue
14621+extra-libs-$(OPTION_EGLIBC_INET_ANL) += libanl
14622+routines-$(OPTION_EGLIBC_INET) += gai_sigqueue
14623 tests += tst-res_hconf_reorder
14624 endif
14625-extra-libs-others = $(extra-libs)
14626+extra-libs-others-y += $(extra-libs-y)
14627 libresolv-routines := gethnamaddr res_comp res_debug \
14628 res_data res_mkquery res_query res_send \
14629 inet_net_ntop inet_net_pton inet_neta base64 \
14630@@ -61,7 +64,7 @@ routines += $(libnss_dns-routines) $(libresolv-routines)
14631 static-only-routines += $(libnss_dns-routines) $(libresolv-routines)
14632 endif
14633
14634-ifeq (yesyes,$(build-shared)$(have-thread-library))
14635+ifeq (yesyesy,$(build-shared)$(have-thread-library)$(OPTION_EGLIBC_INET_ANL))
14636 tests: $(objpfx)ga_test
14637 endif
14638
14639diff --git a/stdio-common/Makefile b/stdio-common/Makefile
14640index d0bf0e1..8655801 100644
14641--- a/stdio-common/Makefile
14642+++ b/stdio-common/Makefile
14643@@ -18,6 +18,8 @@
14644 #
14645 # Specific makefile for stdio-common.
14646 #
14647+include ../option-groups.mak
14648+
14649 subdir := stdio-common
14650
14651 include ../Makeconfig
14652@@ -30,7 +32,7 @@ routines := \
14653 vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex \
14654 reg-modifier reg-type \
14655 printf_size fprintf printf snprintf sprintf asprintf dprintf \
14656- vfwprintf vfscanf vfwscanf \
14657+ vfscanf \
14658 fscanf scanf sscanf \
14659 perror psignal \
14660 tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \
14661@@ -41,23 +43,36 @@ routines := \
14662 isoc99_vsscanf \
14663 psiginfo
14664
14665-aux := errlist siglist printf-parsemb printf-parsewc fxprintf
14666+# Ideally, _itowa and itowa-digits would be in this option group as
14667+# well, but it is used unconditionally by printf_fp and printf_fphex,
14668+# and it didn't seem straightforward to disentangle it.
14669+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
14670+ += vfwprintf vfwscanf
14671+
14672+aux := errlist siglist printf-parsemb fxprintf
14673+aux-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += printf-parsewc
14674
14675 tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
14676 temptest tst-fileno test-fwrite tst-ungetc tst-ferror \
14677 xbug errnobug \
14678 bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \
14679- tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \
14680+ tfformat tiformat tllformat tstdiomisc tst-printfsz \
14681 scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \
14682- scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \
14683- tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
14684- tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \
14685+ scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \
14686+ tst-fseek tst-fmemopen tst-gets \
14687+ tst-sprintf tst-rndseek tst-fdopen tst-fphex \
14688 tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
14689- tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
14690- bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
14691- scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
14692- bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \
14693+ tst-fwrite bug16 bug17 tst-sprintf2 bug18 \
14694+ bug19 tst-popen2 scanf14 scanf15 bug21 bug22 \
14695+ scanf16 scanf17 tst-setvbuf1 bug23 bug24 \
14696+ bug-vfprintf-nargs tst-sprintf3 \
14697 bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3
14698+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
14699+ += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping
14700+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
14701+ += tst-perror bug19a bug20 tst-long-dbl-fphex tst-fphex-wide
14702+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
14703+ += bug18a tst-swscanf tst-wc-printf
14704
14705 test-srcs = tst-unbputc tst-printf
14706
14707diff --git a/stdio-common/_i18n_number.h b/stdio-common/_i18n_number.h
14708index 3c73044..ac62b3a 100644
14709--- a/stdio-common/_i18n_number.h
14710+++ b/stdio-common/_i18n_number.h
14711@@ -19,10 +19,13 @@
14712 #include <stdbool.h>
14713 #include <wchar.h>
14714 #include <wctype.h>
14715+#include <gnu/option-groups.h>
14716
14717 #include "../locale/outdigits.h"
14718 #include "../locale/outdigitswc.h"
14719
14720+#if __OPTION_EGLIBC_LOCALE_CODE
14721+
14722 static CHAR_T *
14723 _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
14724 {
14725@@ -115,3 +118,13 @@ _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
14726
14727 return w;
14728 }
14729+
14730+#else
14731+
14732+static CHAR_T *
14733+_i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
14734+{
14735+ return w;
14736+}
14737+
14738+#endif
14739diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c
14740index 7b2eb94..8476076 100644
14741--- a/stdio-common/fxprintf.c
14742+++ b/stdio-common/fxprintf.c
14743@@ -23,6 +23,7 @@
14744 #include <wchar.h>
14745 #include <string.h>
14746 #include <libioP.h>
14747+#include <gnu/option-groups.h>
14748
14749
14750 int
14751@@ -37,6 +38,7 @@ __fxprintf (FILE *fp, const char *fmt, ...)
14752 int res;
14753 if (_IO_fwide (fp, 0) > 0)
14754 {
14755+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
14756 size_t len = strlen (fmt) + 1;
14757 wchar_t wfmt[len];
14758 for (size_t i = 0; i < len; ++i)
14759@@ -45,6 +47,9 @@ __fxprintf (FILE *fp, const char *fmt, ...)
14760 wfmt[i] = fmt[i];
14761 }
14762 res = __vfwprintf (fp, wfmt, ap);
14763+#else
14764+ abort();
14765+#endif
14766 }
14767 else
14768 res = _IO_vfprintf (fp, fmt, ap);
14769diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
14770index 3023b20..bd0df66 100644
14771--- a/stdio-common/printf_fp.c
14772+++ b/stdio-common/printf_fp.c
14773@@ -39,6 +39,7 @@
14774 #include <unistd.h>
14775 #include <stdlib.h>
14776 #include <wchar.h>
14777+#include <gnu/option-groups.h>
14778 #include <stdbool.h>
14779 #include <rounding-mode.h>
14780
14781@@ -142,6 +143,10 @@ extern mp_size_t __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
14782 extern unsigned int __guess_grouping (unsigned int intdig_max,
14783 const char *grouping);
14784
14785+/* Ideally, when OPTION_EGLIBC_LOCALE_CODE is disabled, this should do
14786+ all its work in ordinary characters, rather than doing it in wide
14787+ characters and then converting at the end. But that is a challenge
14788+ for another day. */
14789
14790 static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
14791 unsigned int intdig_no, const char *grouping,
14792@@ -251,7 +256,14 @@ ___printf_fp (FILE *fp,
14793 mp_limb_t cy;
14794
14795 /* Nonzero if this is output on a wide character stream. */
14796+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14797 int wide = info->wide;
14798+#else
14799+ /* This should never be called on a wide-oriented stream when
14800+ OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
14801+ be trusted to figure that out. */
14802+ const int wide = 0;
14803+#endif
14804
14805 /* Buffer in which we produce the output. */
14806 wchar_t *wbuffer = NULL;
14807@@ -261,6 +273,7 @@ ___printf_fp (FILE *fp,
14808 p.expsign = 0;
14809
14810 /* Figure out the decimal point character. */
14811+#if __OPTION_EGLIBC_LOCALE_CODE
14812 if (info->extra == 0)
14813 {
14814 decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
14815@@ -280,7 +293,13 @@ ___printf_fp (FILE *fp,
14816 /* The decimal point character must not be zero. */
14817 assert (*decimal != '\0');
14818 assert (decimalwc != L'\0');
14819+#else
14820+ /* Hard-code values from 'C' locale. */
14821+ decimal = ".";
14822+ decimalwc = L'.';
14823+#endif
14824
14825+#if __OPTION_EGLIBC_LOCALE_CODE
14826 if (info->group)
14827 {
14828 if (info->extra == 0)
14829@@ -324,6 +343,9 @@ ___printf_fp (FILE *fp,
14830 }
14831 else
14832 grouping = NULL;
14833+#else
14834+ grouping = NULL;
14835+#endif
14836
14837 /* Fetch the argument value. */
14838 #ifndef __NO_LONG_DOUBLE_MATH
14839diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c
14840index 6c3b5e9..f660ce0 100644
14841--- a/stdio-common/printf_fphex.c
14842+++ b/stdio-common/printf_fphex.c
14843@@ -28,6 +28,7 @@
14844 #include <_itoa.h>
14845 #include <_itowa.h>
14846 #include <locale/localeinfo.h>
14847+#include <gnu/option-groups.h>
14848 #include <stdbool.h>
14849 #include <rounding-mode.h>
14850
14851@@ -139,10 +140,18 @@ __printf_fphex (FILE *fp,
14852 int done = 0;
14853
14854 /* Nonzero if this is output on a wide character stream. */
14855+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14856 int wide = info->wide;
14857+#else
14858+ /* This should never be called on a wide-oriented stream when
14859+ OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
14860+ be trusted to figure that out. */
14861+ const int wide = 0;
14862+#endif
14863
14864
14865 /* Figure out the decimal point character. */
14866+#if __OPTION_EGLIBC_LOCALE_CODE
14867 if (info->extra == 0)
14868 {
14869 decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
14870@@ -156,6 +165,10 @@ __printf_fphex (FILE *fp,
14871 }
14872 /* The decimal point character must never be zero. */
14873 assert (*decimal != '\0' && decimalwc != L'\0');
14874+#else
14875+ decimal = ".";
14876+ decimalwc = L'.';
14877+#endif
14878
14879
14880 /* Fetch the argument value. */
14881diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c
14882index 7dcd58e..6fb7491 100644
14883--- a/stdio-common/printf_size.c
14884+++ b/stdio-common/printf_size.c
14885@@ -23,6 +23,7 @@
14886 #include <math.h>
14887 #include <printf.h>
14888 #include <libioP.h>
14889+#include <gnu/option-groups.h>
14890
14891
14892 /* This defines make it possible to use the same code for GNU C library and
14893@@ -116,7 +117,14 @@ __printf_size (FILE *fp, const struct printf_info *info,
14894
14895 struct printf_info fp_info;
14896 int done = 0;
14897+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14898 int wide = info->wide;
14899+#else
14900+ /* This should never be called on a wide-oriented stream when
14901+ OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
14902+ be trusted to figure that out. */
14903+ const int wide = 0;
14904+#endif
14905 int res;
14906
14907 /* Fetch the argument value. */
14908diff --git a/stdio-common/scanf14.c b/stdio-common/scanf14.c
14909index cffccb0..6cc260a 100644
14910--- a/stdio-common/scanf14.c
14911+++ b/stdio-common/scanf14.c
14912@@ -3,6 +3,7 @@
14913 #include <string.h>
14914 #include <wchar.h>
14915 #include <libc-internal.h>
14916+#include <gnu/option-groups.h>
14917
14918 #define FAIL() \
14919 do { \
14920@@ -48,6 +49,7 @@ main (void)
14921 /* See explanation above. */
14922 DIAG_PUSH_NEEDS_COMMENT;
14923 DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat");
14924+#if __OPTION_EGLIBC_LOCALE_CODE
14925 if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2)
14926 FAIL ();
14927 else
14928@@ -57,6 +59,7 @@ main (void)
14929 memset (lsp, 'x', sizeof L"3.25");
14930 free (lsp);
14931 }
14932+#endif
14933 if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2)
14934 FAIL ();
14935 else
14936diff --git a/stdio-common/tst-popen.c b/stdio-common/tst-popen.c
14937index 5def27f..7c9b91e 100644
14938--- a/stdio-common/tst-popen.c
14939+++ b/stdio-common/tst-popen.c
14940@@ -19,6 +19,7 @@
14941 #include <stdio.h>
14942 #include <string.h>
14943 #include <wchar.h>
14944+#include <gnu/option-groups.h>
14945
14946 static int
14947 do_test (void)
14948@@ -34,12 +35,14 @@ do_test (void)
14949 return 1;
14950 }
14951
14952+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
14953 /* POSIX says that pipe streams are byte-oriented. */
14954 if (fwide (f, 0) >= 0)
14955 {
14956 puts ("popen did not return byte-oriented stream");
14957 result = 1;
14958 }
14959+#endif
14960
14961 if (getline (&line, &len, f) != 5)
14962 {
14963diff --git a/stdio-common/tst-sprintf.c b/stdio-common/tst-sprintf.c
14964index d5284b9..f1e3d21 100644
14965--- a/stdio-common/tst-sprintf.c
14966+++ b/stdio-common/tst-sprintf.c
14967@@ -3,7 +3,7 @@
14968 #include <locale.h>
14969 #include <string.h>
14970 #include <libc-internal.h>
14971-
14972+#include <gnu/option-groups.h>
14973
14974 static int
14975 do_test (void)
14976@@ -11,12 +11,14 @@ do_test (void)
14977 char buf[100];
14978 int result = 0;
14979
14980+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14981 if (sprintf (buf, "%.0ls", L"foo") != 0
14982 || strlen (buf) != 0)
14983 {
14984 puts ("sprintf (buf, \"%.0ls\", L\"foo\") produced some output");
14985 result = 1;
14986 }
14987+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
14988
14989 #define SIZE (1024*70000)
14990 #define STR(x) #x
14991diff --git a/stdio-common/tstdiomisc.c b/stdio-common/tstdiomisc.c
14992index 5548a71..31ed024 100644
14993--- a/stdio-common/tstdiomisc.c
14994+++ b/stdio-common/tstdiomisc.c
14995@@ -4,6 +4,7 @@
14996 #include <string.h>
14997 #include <wchar.h>
14998 #include <libc-internal.h>
14999+#include <gnu/option-groups.h>
15000
15001 static int
15002 t1 (void)
15003@@ -134,6 +135,7 @@ F (void)
15004 printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
15005 buf);
15006
15007+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
15008 swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G",
15009 qnanval, qnanval, qnanval, qnanval,
15010 qnanval, qnanval, qnanval, qnanval);
15011@@ -171,6 +173,7 @@ F (void)
15012 result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
15013 printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
15014 wbuf);
15015+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
15016
15017 lqnanval = NAN;
15018
15019@@ -215,6 +218,7 @@ F (void)
15020 printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
15021 buf);
15022
15023+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
15024 swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]),
15025 L"%La %LA %Le %LE %Lf %LF %Lg %LG",
15026 lqnanval, lqnanval, lqnanval, lqnanval,
15027@@ -259,6 +263,7 @@ F (void)
15028 result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
15029 printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
15030 wbuf);
15031+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
15032
15033 return result;
15034 }
15035diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
15036index 0592e70..f21d973 100644
15037--- a/stdio-common/vfprintf.c
15038+++ b/stdio-common/vfprintf.c
15039@@ -29,6 +29,7 @@
15040 #include <_itoa.h>
15041 #include <locale/localeinfo.h>
15042 #include <stdio.h>
15043+#include <gnu/option-groups.h>
15044
15045 /* This code is shared between the standard stdio implementation found
15046 in GNU C library and the libio implementation originally found in
15047@@ -140,6 +141,18 @@ typedef wchar_t THOUSANDS_SEP_T;
15048 # define EOF WEOF
15049 #endif
15050
15051+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
15052+# define MULTIBYTE_SUPPORT (1)
15053+#else
15054+# define MULTIBYTE_SUPPORT (0)
15055+#endif
15056+
15057+#if __OPTION_EGLIBC_LOCALE_CODE
15058+# define LOCALE_SUPPORT (1)
15059+#else
15060+# define LOCALE_SUPPORT (0)
15061+#endif
15062+
15063 #include "_i18n_number.h"
15064
15065 /* Include the shared code for parsing the format string. */
15066@@ -1065,8 +1078,11 @@ static const uint8_t jump_table[] =
15067 # define process_string_arg(fspec) \
15068 LABEL (form_character): \
15069 /* Character. */ \
15070- if (is_long) \
15071- goto LABEL (form_wcharacter); \
15072+ if (is_long) \
15073+ { \
15074+ assert (MULTIBYTE_SUPPORT); \
15075+ goto LABEL (form_wcharacter); \
15076+ } \
15077 --width; /* Account for the character itself. */ \
15078 if (!left) \
15079 PAD (' '); \
15080@@ -1079,6 +1095,7 @@ static const uint8_t jump_table[] =
15081 break; \
15082 \
15083 LABEL (form_wcharacter): \
15084+ assert (MULTIBYTE_SUPPORT); \
15085 { \
15086 /* Wide character. */ \
15087 char buf[MB_CUR_MAX]; \
15088@@ -1145,6 +1162,7 @@ static const uint8_t jump_table[] =
15089 } \
15090 else \
15091 { \
15092+ assert (MULTIBYTE_SUPPORT); \
15093 const wchar_t *s2 = (const wchar_t *) string; \
15094 mbstate_t mbstate; \
15095 \
15096@@ -1399,7 +1417,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
15097 LABEL (flag_quote):
15098 group = 1;
15099
15100- if (grouping == (const char *) -1)
15101+ if (! LOCALE_SUPPORT)
15102+ grouping = NULL;
15103+ else if (grouping == (const char *) -1)
15104 {
15105 #ifdef COMPILE_WPRINTF
15106 thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
15107@@ -1728,8 +1748,9 @@ printf_positional (_IO_FILE *s, const CHAR_T *format, int readonly_format,
15108 size_t cnt;
15109
15110 CHAR_T *workstart = NULL;
15111-
15112- if (grouping == (const char *) -1)
15113+ if (! LOCALE_SUPPORT)
15114+ grouping = NULL;
15115+ else if (grouping == (const char *) -1)
15116 {
15117 #ifdef COMPILE_WPRINTF
15118 thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
15119diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
15120index 0e204e7..66cc0af 100644
15121--- a/stdio-common/vfscanf.c
15122+++ b/stdio-common/vfscanf.c
15123@@ -29,6 +29,7 @@
15124 #include <wctype.h>
15125 #include <bits/libc-lock.h>
15126 #include <locale/localeinfo.h>
15127+#include <gnu/option-groups.h>
15128
15129 #ifdef __GNUC__
15130 # define HAVE_LONGLONG
15131@@ -133,6 +134,12 @@
15132 # define WINT_T int
15133 #endif
15134
15135+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
15136+# define MULTIBYTE_SUPPORT (1)
15137+#else
15138+# define MULTIBYTE_SUPPORT (0)
15139+#endif
15140+
15141 #define encode_error() do { \
15142 errval = 4; \
15143 __set_errno (EILSEQ); \
15144@@ -316,24 +323,35 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
15145 ARGCHECK (s, format);
15146
15147 {
15148-#ifndef COMPILE_WSCANF
15149+#if __OPTION_EGLIBC_LOCALE_CODE && !defined (COMPILE_WSCANF)
15150 struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
15151 #endif
15152
15153+#if __OPTION_EGLIBC_LOCALE_CODE
15154 /* Figure out the decimal point character. */
15155-#ifdef COMPILE_WSCANF
15156+# ifdef COMPILE_WSCANF
15157 decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
15158-#else
15159+# else
15160 decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
15161-#endif
15162+# endif
15163 /* Figure out the thousands separator character. */
15164-#ifdef COMPILE_WSCANF
15165+# ifdef COMPILE_WSCANF
15166 thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
15167-#else
15168+# else
15169 thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
15170 if (*thousands == '\0')
15171 thousands = NULL;
15172-#endif
15173+# endif
15174+#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
15175+ /* Hard-code values from the C locale. */
15176+# ifdef COMPILE_WSCANF
15177+ decimal = L'.';
15178+ thousands = L'\0';
15179+# else
15180+ decimal = ".";
15181+ thousands = NULL;
15182+# endif
15183+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
15184 }
15185
15186 /* Lock the stream. */
15187@@ -385,6 +403,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
15188 #ifndef COMPILE_WSCANF
15189 if (!isascii ((unsigned char) *f))
15190 {
15191+ assert (MULTIBYTE_SUPPORT);
15192+
15193 /* Non-ASCII, may be a multibyte. */
15194 int len = __mbrlen (f, strlen (f), &state);
15195 if (len > 0)
15196@@ -830,6 +850,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
15197 }
15198 /* FALLTHROUGH */
15199 case L_('C'):
15200+ assert (MULTIBYTE_SUPPORT);
15201+
15202 if (width == -1)
15203 width = 1;
15204
15205@@ -1172,6 +1194,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
15206 /* FALLTHROUGH */
15207
15208 case L_('S'):
15209+ assert (MULTIBYTE_SUPPORT);
15210+
15211 {
15212 #ifndef COMPILE_WSCANF
15213 mbstate_t cstate;
15214@@ -1419,10 +1443,17 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
15215 const char *mbdigits[10];
15216 const char *mbdigits_extended[10];
15217 #endif
15218+#if __OPTION_EGLIBC_LOCALE_CODE
15219 /* "to_inpunct" is a map from ASCII digits to their
15220 equivalent in locale. This is defined for locales
15221 which use an extra digits set. */
15222 wctrans_t map = __wctrans ("to_inpunct");
15223+#else
15224+ /* This will always be the case when
15225+ OPTION_EGLIBC_LOCALE_CODE is disabled, but the
15226+ compiler can't figure that out. */
15227+ wctrans_t map = NULL;
15228+#endif
15229 int n;
15230
15231 from_level = 0;
15232@@ -2088,6 +2119,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
15233 --width;
15234 }
15235
15236+#if __OPTION_EGLIBC_LOCALE_CODE
15237 wctrans_t map;
15238 if (__builtin_expect ((flags & I18N) != 0, 0)
15239 /* Hexadecimal floats make no sense, fixing localized
15240@@ -2304,6 +2336,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
15241 ;
15242 #endif
15243 }
15244+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
15245
15246 /* Have we read any character? If we try to read a number
15247 in hexadecimal notation and we have read only the `0x'
15248@@ -2343,7 +2376,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
15249
15250 case L_('['): /* Character class. */
15251 if (flags & LONG)
15252- STRING_ARG (wstr, wchar_t, 100);
15253+ {
15254+ assert (MULTIBYTE_SUPPORT);
15255+ STRING_ARG (wstr, wchar_t, 100);
15256+ }
15257 else
15258 STRING_ARG (str, char, 100);
15259
15260@@ -2417,6 +2453,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
15261 if (flags & LONG)
15262 {
15263 size_t now = read_in;
15264+ assert (MULTIBYTE_SUPPORT);
15265 #ifdef COMPILE_WSCANF
15266 if (__glibc_unlikely (inchar () == WEOF))
15267 input_error ();
15268diff --git a/stdlib/Makefile b/stdlib/Makefile
15269index 402466a..7e7e304 100644
15270--- a/stdlib/Makefile
15271+++ b/stdlib/Makefile
15272@@ -18,6 +18,8 @@
15273 #
15274 # Makefile for stdlib routines
15275 #
15276+include ../option-groups.mak
15277+
15278 subdir := stdlib
15279
15280 include ../Makeconfig
15281@@ -30,7 +32,7 @@ headers := stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h \
15282 alloca.h fmtmsg.h \
15283 bits/stdlib-bsearch.h
15284
15285-routines := \
15286+routines-y := \
15287 atof atoi atol atoll \
15288 abort \
15289 bsearch qsort msort \
15290@@ -39,7 +41,6 @@ routines := \
15291 quick_exit at_quick_exit cxa_at_quick_exit cxa_thread_atexit_impl \
15292 abs labs llabs \
15293 div ldiv lldiv \
15294- mblen mbstowcs mbtowc wcstombs wctomb \
15295 random random_r rand rand_r \
15296 drand48 erand48 lrand48 nrand48 mrand48 jrand48 \
15297 srand48 seed48 lcong48 \
15298@@ -52,9 +53,18 @@ routines := \
15299 strtof_l strtod_l strtold_l \
15300 system canonicalize \
15301 a64l l64a \
15302- rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg \
15303- strtoimax strtoumax wcstoimax wcstoumax \
15304+ getsubopt xpg_basename \
15305+ strtoimax strtoumax \
15306 getcontext setcontext makecontext swapcontext
15307+routines-$(OPTION_EGLIBC_LOCALE_CODE) += \
15308+ strfmon strfmon_l
15309+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += \
15310+ mblen mbstowcs mbtowc wcstombs wctomb \
15311+ wcstoimax wcstoumax
15312+ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP))
15313+routines-y += rpmatch
15314+endif
15315+routines-$(OPTION_EGLIBC_FMTMSG) += fmtmsg
15316 aux = grouping groupingwc tens_in_limb
15317
15318 # These routines will be omitted from the libc shared object.
15319@@ -62,20 +72,24 @@ aux = grouping groupingwc tens_in_limb
15320 # linked against when the shared library will be used.
15321 static-only-routines = atexit at_quick_exit
15322
15323-test-srcs := tst-fmtmsg
15324-tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
15325+test-srcs-$(OPTION_EGLIBC_FMTMSG) := tst-fmtmsg
15326+tests := tst-strtol tst-strtod testrand testsort testdiv \
15327 test-canon test-canon2 tst-strtoll tst-environ \
15328 tst-xpg-basename tst-random tst-random2 tst-bsearch \
15329 tst-limits tst-rand48 bug-strtod tst-setcontext \
15330- tst-setcontext2 test-a64l tst-qsort tst-system testmb2 \
15331- bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 \
15332- tst-rand48-2 tst-makecontext tst-strtod4 tst-strtod5 \
15333+ tst-setcontext2 test-a64l tst-qsort tst-system \
15334+ bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 \
15335+ tst-rand48-2 tst-makecontext \
15336 tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \
15337 tst-makecontext3 bug-getcontext bug-fmtmsg1 \
15338 tst-secure-getenv tst-strtod-overflow tst-strtod-round \
15339 tst-tininess tst-strtod-underflow tst-tls-atexit \
15340 tst-setcontext3 tst-tls-atexit-nodelete
15341 tests-static := tst-secure-getenv
15342+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
15343+ += tst-strtod3 tst-strtod4 tst-strtod5 testmb2
15344+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
15345+ += testmb
15346
15347 modules-names = tst-tls-atexit-lib
15348
15349@@ -116,8 +130,10 @@ CFLAGS-tst-makecontext2.c = $(stack-align-test-flags)
15350 tests-special += $(objpfx)isomac.out
15351
15352 ifeq ($(run-built-tests),yes)
15353+ifeq (y,$(OPTION_EGLIBC_FMTMSG))
15354 tests-special += $(objpfx)tst-fmtmsg.out
15355 endif
15356+endif
15357
15358 include ../Rules
15359
15360diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
15361index e13ab1e..63efe41 100644
15362--- a/stdlib/strtod_l.c
15363+++ b/stdlib/strtod_l.c
15364@@ -17,6 +17,7 @@
15365 License along with the GNU C Library; if not, see
15366 <http://www.gnu.org/licenses/>. */
15367
15368+#include <gnu/option-groups.h>
15369 #include <xlocale.h>
15370
15371 extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
15372@@ -548,6 +549,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
15373 /* Used in several places. */
15374 int cnt;
15375
15376+#if __OPTION_EGLIBC_LOCALE_CODE
15377 struct __locale_data *current = loc->__locales[LC_NUMERIC];
15378
15379 if (__glibc_unlikely (group))
15380@@ -586,6 +588,17 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
15381 decimal_len = strlen (decimal);
15382 assert (decimal_len > 0);
15383 #endif
15384+#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
15385+ /* Hard-code values from the 'C' locale. */
15386+ grouping = NULL;
15387+#ifdef USE_WIDE_CHAR
15388+ decimal = L'.';
15389+# define decimal_len 1
15390+#else
15391+ decimal = ".";
15392+ decimal_len = 1;
15393+#endif
15394+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
15395
15396 /* Prepare number representation. */
15397 exponent = 0;
15398diff --git a/stdlib/tst-strtod.c b/stdlib/tst-strtod.c
15399index a469208..28fb423 100644
15400--- a/stdlib/tst-strtod.c
15401+++ b/stdlib/tst-strtod.c
15402@@ -23,6 +23,7 @@
15403 #include <errno.h>
15404 #include <string.h>
15405 #include <math.h>
15406+#include <gnu/option-groups.h>
15407
15408 struct ltest
15409 {
15410@@ -176,7 +177,9 @@ main (int argc, char ** argv)
15411
15412 status |= long_dbl ();
15413
15414+#if __OPTION_EGLIBC_LOCALE_CODE
15415 status |= locale_test ();
15416+#endif
15417
15418 return status ? EXIT_FAILURE : EXIT_SUCCESS;
15419 }
15420@@ -219,6 +222,7 @@ long_dbl (void)
15421 return 0;
15422 }
15423
15424+#if __OPTION_EGLIBC_LOCALE_CODE
15425 /* Perform a few tests in a locale with thousands separators. */
15426 static int
15427 locale_test (void)
15428@@ -276,3 +280,4 @@ locale_test (void)
15429
15430 return result;
15431 }
15432+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
15433diff --git a/streams/Makefile b/streams/Makefile
15434index a8a6162..ceb423f 100644
15435--- a/streams/Makefile
15436+++ b/streams/Makefile
15437@@ -18,11 +18,14 @@
15438 #
15439 # Makefile for streams.
15440 #
15441+include ../option-groups.mak
15442+
15443 subdir := streams
15444
15445 include ../Makeconfig
15446
15447 headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
15448-routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach
15449+routines-$(OPTION_EGLIBC_STREAMS) \
15450+ += isastream getmsg getpmsg putmsg putpmsg fattach fdetach
15451
15452 include ../Rules
15453diff --git a/string/Makefile b/string/Makefile
15454index 8424a61..5988834 100644
15455--- a/string/Makefile
15456+++ b/string/Makefile
15457@@ -18,6 +18,8 @@
15458 #
15459 # Sub-makefile for string portion of library.
15460 #
15461+include ../option-groups.mak
15462+
15463 subdir := string
15464
15465 include ../Makeconfig
15466@@ -39,10 +41,12 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \
15467 $(addprefix argz-,append count create ctsep next \
15468 delete extract insert stringify \
15469 addsep replace) \
15470- envz basename \
15471+ basename \
15472 strcoll_l strxfrm_l string-inlines memrchr \
15473 xpg-strerror strerror_l
15474
15475+routines-$(OPTION_EGLIBC_ENVZ) += envz
15476+
15477 strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \
15478 stpcpy stpncpy strcat strchr strcmp strcpy strcspn \
15479 strlen strncmp strncpy strpbrk strrchr strspn memmem \
15480@@ -51,10 +55,12 @@ strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \
15481 tests := tester inl-tester noinl-tester testcopy test-ffs \
15482 tst-strlen stratcliff tst-svc tst-inlcall \
15483 bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \
15484- tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \
15485+ tst-strtok tst-strfry \
15486 bug-strtok1 $(addprefix test-,$(strop-tests)) \
15487- bug-envz1 tst-strxfrm2 tst-endian tst-svc2 \
15488- tst-strtok_r
15489+ tst-strxfrm2 tst-endian tst-svc2 tst-strtok_r
15490+tests-$(OPTION_EGLIBC_ENVZ) += bug-envz1
15491+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
15492+ += tst-strxfrm bug-strcoll1
15493
15494 xtests = tst-strcoll-overflow
15495
15496diff --git a/string/strcoll_l.c b/string/strcoll_l.c
15497index 8f1225f..b36b18c 100644
15498--- a/string/strcoll_l.c
15499+++ b/string/strcoll_l.c
15500@@ -24,6 +24,7 @@
15501 #include <stdint.h>
15502 #include <string.h>
15503 #include <sys/param.h>
15504+#include <gnu/option-groups.h>
15505
15506 #ifndef STRING_TYPE
15507 # define STRING_TYPE char
15508@@ -260,7 +261,11 @@ int
15509 STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
15510 {
15511 struct __locale_data *current = l->__locales[LC_COLLATE];
15512+#if __OPTION_EGLIBC_LOCALE_CODE
15513 uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
15514+#else
15515+ const uint_fast32_t nrules = 0;
15516+#endif
15517 /* We don't assign the following values right away since it might be
15518 unnecessary in case there are no rules. */
15519 const unsigned char *rulesets;
15520diff --git a/string/strerror_l.c b/string/strerror_l.c
15521index 2ed78b5..6584813 100644
15522--- a/string/strerror_l.c
15523+++ b/string/strerror_l.c
15524@@ -21,6 +21,7 @@
15525 #include <stdlib.h>
15526 #include <string.h>
15527 #include <sys/param.h>
15528+#include <gnu/option-groups.h>
15529
15530
15531 static __thread char *last_value;
15532@@ -29,10 +30,14 @@ static __thread char *last_value;
15533 static const char *
15534 translate (const char *str, locale_t loc)
15535 {
15536+#if __OPTION_EGLIBC_LOCALE_CODE
15537 locale_t oldloc = __uselocale (loc);
15538 const char *res = _(str);
15539 __uselocale (oldloc);
15540 return res;
15541+#else
15542+ return str;
15543+#endif
15544 }
15545
15546
15547diff --git a/string/strxfrm_l.c b/string/strxfrm_l.c
15548index 8b61ea2..41fdc22 100644
15549--- a/string/strxfrm_l.c
15550+++ b/string/strxfrm_l.c
15551@@ -24,6 +24,7 @@
15552 #include <stdlib.h>
15553 #include <string.h>
15554 #include <sys/param.h>
15555+#include <gnu/option-groups.h>
15556
15557 #ifndef STRING_TYPE
15558 # define STRING_TYPE char
15559@@ -669,7 +670,11 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
15560 {
15561 locale_data_t l_data;
15562 struct __locale_data *current = l->__locales[LC_COLLATE];
15563+#if __OPTION_EGLIBC_LOCALE_CODE
15564 l_data.nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
15565+#else
15566+ l_data.nrules = 0;
15567+#endif
15568
15569 /* Handle byte comparison case. */
15570 if (l_data.nrules == 0)
15571diff --git a/string/test-strcmp.c b/string/test-strcmp.c
15572index dc4ba6f..a978656 100644
15573--- a/string/test-strcmp.c
15574+++ b/string/test-strcmp.c
15575@@ -329,34 +329,6 @@ check (void)
15576 FOR_EACH_IMPL (impl, 0)
15577 check_result (impl, s1 + i1, s2 + i2, exp_result);
15578 }
15579-
15580- /* Test cases where there are multiple zero bytes after the first. */
15581-
15582- for (size_t i = 0; i < 16 + 1; i++)
15583- {
15584- s1[i] = 0x00;
15585- s2[i] = 0x00;
15586- }
15587-
15588- for (size_t i = 0; i < 16; i++)
15589- {
15590- int exp_result;
15591-
15592- for (int val = 0x01; val < 0x100; val++)
15593- {
15594- for (size_t j = 0; j < i; j++)
15595- {
15596- s1[j] = val;
15597- s2[j] = val;
15598- }
15599-
15600- s2[i] = val;
15601-
15602- exp_result = SIMPLE_STRCMP (s1, s2);
15603- FOR_EACH_IMPL (impl, 0)
15604- check_result (impl, s1, s2, exp_result);
15605- }
15606- }
15607 }
15608
15609
15610diff --git a/string/tst-strxfrm.c b/string/tst-strxfrm.c
15611index f48cfc0..c3a51f9 100644
15612--- a/string/tst-strxfrm.c
15613+++ b/string/tst-strxfrm.c
15614@@ -3,6 +3,7 @@
15615 #include <stdio.h>
15616 #include <stdlib.h>
15617 #include <string.h>
15618+#include <gnu/option-groups.h>
15619
15620
15621 char const string[] = "";
15622@@ -64,8 +65,10 @@ do_test (void)
15623 int result = 0;
15624
15625 result |= test ("C");
15626+#if __OPTION_EGLIBC_LOCALE_CODE
15627 result |= test ("en_US.ISO-8859-1");
15628 result |= test ("de_DE.UTF-8");
15629+#endif
15630
15631 return result;
15632 }
15633diff --git a/string/tst-strxfrm2.c b/string/tst-strxfrm2.c
15634index d5a1115..19c7f30 100644
15635--- a/string/tst-strxfrm2.c
15636+++ b/string/tst-strxfrm2.c
15637@@ -1,6 +1,7 @@
15638 #include <locale.h>
15639 #include <stdio.h>
15640 #include <string.h>
15641+#include <gnu/option-groups.h>
15642
15643 static int
15644 do_test (void)
15645@@ -38,6 +39,7 @@ do_test (void)
15646 res = 1;
15647 }
15648
15649+#if __OPTION_EGLIBC_LOCALE_CODE
15650 if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL)
15651 {
15652 puts ("setlocale failed");
15653@@ -75,6 +77,7 @@ do_test (void)
15654 res = 1;
15655 }
15656 }
15657+#endif
15658
15659 return res;
15660 }
15661diff --git a/sunrpc/Makefile b/sunrpc/Makefile
15662index 60caa0a..5bc70ab 100644
15663--- a/sunrpc/Makefile
15664+++ b/sunrpc/Makefile
15665@@ -18,6 +18,8 @@
15666 #
15667 # Sub-makefile for sunrpc portion of the library.
15668 #
15669+include ../option-groups.mak
15670+
15671 subdir := sunrpc
15672
15673 include ../Makeconfig
15674@@ -55,7 +57,6 @@ headers-in-tirpc = $(addprefix rpc/,auth.h auth_unix.h clnt.h pmap_clnt.h \
15675 headers-not-in-tirpc = $(addprefix rpc/,key_prot.h rpc_des.h) \
15676 $(rpcsvc:%=rpcsvc/%) rpcsvc/bootparam.h
15677 headers = rpc/netdb.h
15678-install-others = $(inst_sysconfdir)/rpc
15679 generated += $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) $(rpcsvc:%.x=x%.stmp) \
15680 $(rpcsvc:%.x=rpcsvc/%.stmp) rpcgen
15681 generated-dirs += rpcsvc
15682@@ -65,20 +66,28 @@ headers += $(headers-in-tirpc) $(headers-not-in-tirpc)
15683 endif
15684
15685 ifeq ($(build-shared),yes)
15686-need-export-routines := auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
15687+need-export-routines-$(OPTION_EGLIBC_SUNRPC) := \
15688+ auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
15689 clnt_udp get_myaddr key_call netname pm_getport \
15690- rpc_thread svc svc_tcp svc_udp xcrypt xdr_array xdr \
15691+ rpc_thread svc svc_tcp svc_udp xdr_array xdr \
15692 xdr_intXX_t xdr_mem xdr_ref xdr_sizeof xdr_stdio \
15693 svc_run
15694+need-export-routines-y += xcrypt
15695+need-export-routines := $(need-export-routines-y)
15696
15697-routines := auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
15698+routines-$(OPTION_EGLIBC_SUNRPC) := \
15699+ auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
15700 rpc_dtable getrpcport pmap_clnt pm_getmaps pmap_prot pmap_prot2 \
15701 pmap_rmt rpc_prot rpc_common rpc_cmsg svc_auth svc_authux svc_raw \
15702 svc_simple xdr_float xdr_rec publickey authdes_prot \
15703- des_crypt des_impl des_soft key_prot openchild rtime svcauth_des \
15704+ key_prot openchild rtime svcauth_des \
15705 getrpcent getrpcbyname getrpcbynumber \
15706 getrpcent_r getrpcbyname_r getrpcbynumber_r \
15707- clnt_unix svc_unix create_xid $(need-export-routines)
15708+ clnt_unix svc_unix create_xid
15709+
15710+# xdecrypt is also used by nss/nss_files/files-key.c.
15711+routines-y += des_crypt des_impl des_soft $(need-export-routines)
15712+
15713 ifneq ($(link-obsolete-rpc),yes)
15714 # We only add the RPC for compatibility to libc.so.
15715 shared-only-routines = $(routines)
15716@@ -87,25 +96,28 @@ endif
15717
15718 # We do not build rpcinfo anymore. It is not needed for a bootstrap
15719 # and not wanted on complete systems.
15720-# others := rpcinfo
15721-# install-sbin := rpcinfo
15722-install-bin := rpcgen
15723+# others-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
15724+# install-sbin-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
15725+install-bin-$(OPTION_EGLIBC_SUNRPC) += rpcgen
15726 rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \
15727 rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \
15728 rpc_tblout.o rpc_sample.o
15729-extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
15730-others += rpcgen
15731+extra-objs-$(OPTION_EGLIBC_SUNRPC) = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
15732+others-$(OPTION_EGLIBC_SUNRPC) += rpcgen
15733+
15734+install-others-$(OPTION_EGLIBC_SUNRPC) += $(inst_sysconfdir)/rpc
15735
15736-tests = tst-xdrmem tst-xdrmem2 test-rpcent
15737-xtests := tst-getmyaddr
15738+tests-$(OPTION_EGLIBC_SUNRPC) = tst-xdrmem tst-xdrmem2 test-rpcent
15739+xtests-$(OPTION_EGLIBC_SUNRPC) := tst-getmyaddr
15740
15741 ifeq ($(have-thread-library),yes)
15742-xtests += thrsvc
15743+xtests-$(OPTION_EGLIBC_SUNRPC) += thrsvc
15744 endif
15745
15746 headers += $(rpcsvc:%.x=rpcsvc/%.h)
15747-extra-libs := librpcsvc
15748-extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass.
15749+extra-libs-$(OPTION_EGLIBC_SUNRPC) += librpcsvc
15750+# Make it in `others' pass, not `lib' pass.
15751+extra-libs-others-y += $(extra-libs-y)
15752 librpcsvc-routines = $(rpcsvc:%.x=x%)
15753 librpcsvc-inhibit-o = .os # Build no shared rpcsvc library.
15754 omit-deps = $(librpcsvc-routines)
15755diff --git a/sysdeps/arm/Makefile b/sysdeps/arm/Makefile
15756index 17c129b..543791a 100644
15757--- a/sysdeps/arm/Makefile
15758+++ b/sysdeps/arm/Makefile
15759@@ -37,10 +37,13 @@ ifeq ($(subdir),csu)
15760 # get offset to rtld_global._dl_hwcap
15761 gen-as-const-headers += rtld-global-offsets.sym tlsdesc.sym
15762 aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math
15763-aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \
15764+aeabi_routines = aeabi_assert aeabi_errno_addr \
15765 aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \
15766 aeabi_memmove aeabi_memset \
15767 aeabi_read_tp libc-aeabi_read_tp
15768+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
15769+aeabi_routines += aeabi_localeconv
15770+endif
15771
15772 sysdep_routines += $(aeabi_constants) $(aeabi_routines)
15773 static-only-routines += $(aeabi_constants) aeabi_read_tp
15774diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
15775index 7a0fe8d..a3e2c0a 100644
15776--- a/sysdeps/generic/ldsodefs.h
15777+++ b/sysdeps/generic/ldsodefs.h
15778@@ -435,6 +435,12 @@ extern struct rtld_global _rtld_global __rtld_global_attribute__;
15779 # undef __rtld_global_attribute__
15780 #endif
15781
15782+#if __OPTION_EGLIBC_RTLD_DEBUG
15783+# define GLRO_dl_debug_mask GLRO(dl_debug_mask)
15784+#else
15785+# define GLRO_dl_debug_mask 0
15786+#endif
15787+
15788 #ifndef SHARED
15789 # define GLRO(name) _##name
15790 #else
15791@@ -447,8 +453,10 @@ struct rtld_global_ro
15792 {
15793 #endif
15794
15795+#if __OPTION_EGLIBC_RTLD_DEBUG
15796 /* If nonzero the appropriate debug information is printed. */
15797 EXTERN int _dl_debug_mask;
15798+#endif
15799 #define DL_DEBUG_LIBS (1 << 0)
15800 #define DL_DEBUG_IMPCALLS (1 << 1)
15801 #define DL_DEBUG_BINDINGS (1 << 2)
15802diff --git a/sysdeps/gnu/Makefile b/sysdeps/gnu/Makefile
15803index ea68037..3175cc3 100644
15804--- a/sysdeps/gnu/Makefile
15805+++ b/sysdeps/gnu/Makefile
15806@@ -59,7 +59,8 @@ $(foreach o,$(object-suffixes) $(object-suffixes:=.d),\
15807 endif
15808
15809 ifeq ($(subdir),login)
15810-sysdep_routines += setutxent getutxent endutxent getutxid getutxline \
15811+sysdep_routines-$(OPTION_EGLIBC_UTMPX) \
15812+ += setutxent getutxent endutxent getutxid getutxline \
15813 pututxline utmpxname updwtmpx getutmpx getutmp
15814
15815 sysdep_headers += utmpx.h bits/utmpx.h
15816diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile
15817index 222122d..4509357 100644
15818--- a/sysdeps/ieee754/ldbl-opt/Makefile
15819+++ b/sysdeps/ieee754/ldbl-opt/Makefile
15820@@ -11,19 +11,18 @@ libm-routines += s_nexttowardfd
15821 routines += math_ldbl_opt nldbl-compat
15822
15823 extra-libs += libnldbl
15824-libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
15825+libnldbl-calls = asprintf dprintf fprintf fscanf iovfscanf \
15826 obstack_printf obstack_vprintf printf scanf snprintf \
15827- sprintf sscanf swprintf swscanf vasprintf vdprintf vfprintf \
15828- vfscanf vfwprintf vfwscanf vprintf vscanf vsnprintf \
15829- vsprintf vsscanf vswprintf vswscanf vwprintf vwscanf \
15830- wprintf wscanf printf_fp printf_size \
15831- fprintf_chk fwprintf_chk printf_chk snprintf_chk sprintf_chk \
15832- swprintf_chk vfprintf_chk vfwprintf_chk vprintf_chk \
15833- vsnprintf_chk vsprintf_chk vswprintf_chk vwprintf_chk \
15834- wprintf_chk asprintf_chk vasprintf_chk dprintf_chk \
15835+ sprintf sscanf vasprintf vdprintf vfprintf \
15836+ vfscanf vprintf vscanf vsnprintf \
15837+ vsprintf vsscanf \
15838+ printf_fp printf_size \
15839+ fprintf_chk printf_chk snprintf_chk sprintf_chk \
15840+ vfprintf_chk vprintf_chk \
15841+ vsnprintf_chk vsprintf_chk \
15842+ asprintf_chk vasprintf_chk dprintf_chk \
15843 vdprintf_chk obstack_printf_chk obstack_vprintf_chk \
15844 syslog syslog_chk vsyslog vsyslog_chk \
15845- strfmon strfmon_l \
15846 strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \
15847 qecvt qfcvt qgcvt qecvt_r qfcvt_r \
15848 isinf isnan finite signbit scalb log2 lgamma_r ceil \
15849@@ -38,9 +37,15 @@ libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
15850 casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \
15851 cabs carg cimag creal clog10 \
15852 isoc99_scanf isoc99_fscanf isoc99_sscanf \
15853- isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
15854+ isoc99_vscanf isoc99_vfscanf isoc99_vsscanf
15855+libnldbl-calls-$(OPTION_EGLIBC_LOCALE_CODE) += strfmon strfmon_l
15856+libnldbl-calls-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += fwprintf fwscanf \
15857+ swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf \
15858+ vwprintf vwscanf wprintf wscanf fwprintf_chk swprintf_chk \
15859+ vfwprintf_chk vswprintf_chk vwprintf_chk wprintf_chk \
15860 isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
15861 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf
15862+libnldbl-calls += $(libnldbl-calls-y)
15863 libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
15864 libnldbl-inhibit-o = $(object-suffixes)
15865 libnldbl-static-only-routines = $(libnldbl-routines)
15866diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
15867index 0198886..55501cd 100644
15868--- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
15869+++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
15870@@ -26,6 +26,7 @@
15871 #include <locale/localeinfo.h>
15872 #include <sys/syslog.h>
15873 #include <bits/libc-lock.h>
15874+#include <gnu/option-groups.h>
15875
15876 #include "nldbl-compat.h"
15877
15878@@ -33,20 +34,14 @@ libc_hidden_proto (__nldbl_vfprintf)
15879 libc_hidden_proto (__nldbl_vsscanf)
15880 libc_hidden_proto (__nldbl_vsprintf)
15881 libc_hidden_proto (__nldbl_vfscanf)
15882-libc_hidden_proto (__nldbl_vfwscanf)
15883 libc_hidden_proto (__nldbl_vdprintf)
15884-libc_hidden_proto (__nldbl_vswscanf)
15885-libc_hidden_proto (__nldbl_vfwprintf)
15886-libc_hidden_proto (__nldbl_vswprintf)
15887 libc_hidden_proto (__nldbl_vsnprintf)
15888 libc_hidden_proto (__nldbl_vasprintf)
15889 libc_hidden_proto (__nldbl_obstack_vprintf)
15890-libc_hidden_proto (__nldbl___vfwprintf_chk)
15891 libc_hidden_proto (__nldbl___vsnprintf_chk)
15892 libc_hidden_proto (__nldbl___vfprintf_chk)
15893 libc_hidden_proto (__nldbl___vsyslog_chk)
15894 libc_hidden_proto (__nldbl___vsprintf_chk)
15895-libc_hidden_proto (__nldbl___vswprintf_chk)
15896 libc_hidden_proto (__nldbl___vasprintf_chk)
15897 libc_hidden_proto (__nldbl___vdprintf_chk)
15898 libc_hidden_proto (__nldbl___obstack_vprintf_chk)
15899@@ -54,8 +49,17 @@ libc_hidden_proto (__nldbl___vstrfmon)
15900 libc_hidden_proto (__nldbl___vstrfmon_l)
15901 libc_hidden_proto (__nldbl___isoc99_vsscanf)
15902 libc_hidden_proto (__nldbl___isoc99_vfscanf)
15903+
15904+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15905+libc_hidden_proto (__nldbl_vfwscanf)
15906+libc_hidden_proto (__nldbl_vswscanf)
15907+libc_hidden_proto (__nldbl_vfwprintf)
15908+libc_hidden_proto (__nldbl_vswprintf)
15909+libc_hidden_proto (__nldbl___vfwprintf_chk)
15910+libc_hidden_proto (__nldbl___vswprintf_chk)
15911 libc_hidden_proto (__nldbl___isoc99_vswscanf)
15912 libc_hidden_proto (__nldbl___isoc99_vfwscanf)
15913+#endif
15914
15915 static void
15916 __nldbl_cleanup (void *arg)
15917@@ -117,6 +121,7 @@ __nldbl_fprintf (FILE *stream, const char *fmt, ...)
15918 }
15919 weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf)
15920
15921+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15922 int
15923 attribute_compat_text_section weak_function
15924 __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...)
15925@@ -130,6 +135,7 @@ __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...)
15926
15927 return done;
15928 }
15929+#endif
15930
15931 int
15932 attribute_compat_text_section
15933@@ -226,6 +232,7 @@ __nldbl_snprintf (char *s, size_t maxlen, const char *fmt, ...)
15934 return done;
15935 }
15936
15937+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15938 int
15939 attribute_compat_text_section
15940 __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
15941@@ -239,6 +246,7 @@ __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
15942
15943 return done;
15944 }
15945+#endif
15946
15947 int
15948 attribute_compat_text_section weak_function
15949@@ -264,6 +272,7 @@ __nldbl_vdprintf (int d, const char *fmt, va_list arg)
15950 }
15951 libc_hidden_def (__nldbl_vdprintf)
15952
15953+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15954 int
15955 attribute_compat_text_section weak_function
15956 __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
15957@@ -275,6 +284,7 @@ __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
15958 return res;
15959 }
15960 libc_hidden_def (__nldbl_vfwprintf)
15961+#endif
15962
15963 int
15964 attribute_compat_text_section
15965@@ -297,6 +307,7 @@ __nldbl_vsnprintf (char *string, size_t maxlen, const char *fmt,
15966 libc_hidden_def (__nldbl_vsnprintf)
15967 weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf)
15968
15969+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15970 int
15971 attribute_compat_text_section weak_function
15972 __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt,
15973@@ -330,6 +341,7 @@ __nldbl_wprintf (const wchar_t *fmt, ...)
15974
15975 return done;
15976 }
15977+#endif
15978
15979 int
15980 attribute_compat_text_section
15981@@ -419,6 +431,7 @@ __nldbl_scanf (const char *fmt, ...)
15982 return done;
15983 }
15984
15985+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15986 int
15987 attribute_compat_text_section
15988 __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
15989@@ -491,6 +504,7 @@ __nldbl_wscanf (const wchar_t *fmt, ...)
15990
15991 return done;
15992 }
15993+#endif
15994
15995 int
15996 attribute_compat_text_section
15997@@ -506,6 +520,7 @@ __nldbl___fprintf_chk (FILE *stream, int flag, const char *fmt, ...)
15998 return done;
15999 }
16000
16001+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
16002 int
16003 attribute_compat_text_section
16004 __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
16005@@ -519,6 +534,7 @@ __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
16006
16007 return done;
16008 }
16009+#endif
16010
16011 int
16012 attribute_compat_text_section
16013@@ -563,6 +579,7 @@ __nldbl___sprintf_chk (char *s, int flag, size_t slen, const char *fmt, ...)
16014 return done;
16015 }
16016
16017+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
16018 int
16019 attribute_compat_text_section
16020 __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
16021@@ -577,6 +594,7 @@ __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
16022
16023 return done;
16024 }
16025+#endif
16026
16027 int
16028 attribute_compat_text_section
16029@@ -590,6 +608,7 @@ __nldbl___vfprintf_chk (FILE *s, int flag, const char *fmt, va_list ap)
16030 }
16031 libc_hidden_def (__nldbl___vfprintf_chk)
16032
16033+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
16034 int
16035 attribute_compat_text_section
16036 __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
16037@@ -601,6 +620,7 @@ __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
16038 return res;
16039 }
16040 libc_hidden_def (__nldbl___vfwprintf_chk)
16041+#endif
16042
16043 int
16044 attribute_compat_text_section
16045@@ -635,6 +655,7 @@ __nldbl___vsprintf_chk (char *string, int flag, size_t slen, const char *fmt,
16046 }
16047 libc_hidden_def (__nldbl___vsprintf_chk)
16048
16049+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
16050 int
16051 attribute_compat_text_section
16052 __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen,
16053@@ -668,6 +689,7 @@ __nldbl___wprintf_chk (int flag, const wchar_t *fmt, ...)
16054
16055 return done;
16056 }
16057+#endif
16058
16059 int
16060 attribute_compat_text_section
16061@@ -775,6 +797,7 @@ __nldbl___printf_fp (FILE *fp, const struct printf_info *info,
16062 return ___printf_fp (fp, &info_no_ldbl, args);
16063 }
16064
16065+#if __OPTION_EGLIBC_LOCALE_CODE
16066 ssize_t
16067 attribute_compat_text_section
16068 __nldbl_strfmon (char *s, size_t maxsize, const char *format, ...)
16069@@ -829,6 +852,7 @@ __nldbl___vstrfmon_l (char *s, size_t maxsize, __locale_t loc,
16070 return res;
16071 }
16072 libc_hidden_def (__nldbl___vstrfmon_l)
16073+#endif
16074
16075 void
16076 attribute_compat_text_section
16077@@ -941,6 +965,7 @@ __nldbl___isoc99_scanf (const char *fmt, ...)
16078 return done;
16079 }
16080
16081+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
16082 int
16083 attribute_compat_text_section
16084 __nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
16085@@ -1014,6 +1039,7 @@ __nldbl___isoc99_wscanf (const wchar_t *fmt, ...)
16086
16087 return done;
16088 }
16089+#endif
16090
16091 #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
16092 compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0);
16093@@ -1057,6 +1083,7 @@ compat_symbol (libc, __nldbl_printf_size, printf_size, GLIBC_2_1);
16094 compat_symbol (libc, __nldbl___strfmon_l, __strfmon_l, GLIBC_2_1);
16095 #endif
16096 #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_2)
16097+# if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
16098 compat_symbol (libc, __nldbl_swprintf, swprintf, GLIBC_2_2);
16099 compat_symbol (libc, __nldbl_vwprintf, vwprintf, GLIBC_2_2);
16100 compat_symbol (libc, __nldbl_wprintf, wprintf, GLIBC_2_2);
16101@@ -1069,6 +1096,7 @@ compat_symbol (libc, __nldbl_vfwscanf, vfwscanf, GLIBC_2_2);
16102 compat_symbol (libc, __nldbl_vswscanf, vswscanf, GLIBC_2_2);
16103 compat_symbol (libc, __nldbl_vwscanf, vwscanf, GLIBC_2_2);
16104 compat_symbol (libc, __nldbl_wscanf, wscanf, GLIBC_2_2);
16105+# endif
16106 #endif
16107 #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3)
16108 compat_symbol (libc, __nldbl_strfmon_l, strfmon_l, GLIBC_2_3);
16109diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
16110index 0d2c8af..f4cea50 100644
16111--- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
16112+++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
16113@@ -30,6 +30,7 @@
16114 #include <math.h>
16115 #include <monetary.h>
16116 #include <sys/syslog.h>
16117+#include <gnu/option-groups.h>
16118
16119
16120 /* Declare the __nldbl_NAME function the wrappers call that's in libc.so. */
16121@@ -37,19 +38,15 @@
16122
16123 NLDBL_DECL (_IO_vfscanf);
16124 NLDBL_DECL (vfscanf);
16125-NLDBL_DECL (vfwscanf);
16126 NLDBL_DECL (obstack_vprintf);
16127 NLDBL_DECL (vasprintf);
16128 NLDBL_DECL (dprintf);
16129 NLDBL_DECL (vdprintf);
16130 NLDBL_DECL (fprintf);
16131 NLDBL_DECL (vfprintf);
16132-NLDBL_DECL (vfwprintf);
16133 NLDBL_DECL (vsnprintf);
16134 NLDBL_DECL (vsprintf);
16135 NLDBL_DECL (vsscanf);
16136-NLDBL_DECL (vswprintf);
16137-NLDBL_DECL (vswscanf);
16138 NLDBL_DECL (__asprintf);
16139 NLDBL_DECL (asprintf);
16140 NLDBL_DECL (__printf_fp);
16141@@ -66,12 +63,18 @@ NLDBL_DECL (__isoc99_sscanf);
16142 NLDBL_DECL (__isoc99_vscanf);
16143 NLDBL_DECL (__isoc99_vfscanf);
16144 NLDBL_DECL (__isoc99_vsscanf);
16145+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
16146+NLDBL_DECL (vfwscanf);
16147+NLDBL_DECL (vfwprintf);
16148+NLDBL_DECL (vswprintf);
16149+NLDBL_DECL (vswscanf);
16150 NLDBL_DECL (__isoc99_wscanf);
16151 NLDBL_DECL (__isoc99_fwscanf);
16152 NLDBL_DECL (__isoc99_swscanf);
16153 NLDBL_DECL (__isoc99_vwscanf);
16154 NLDBL_DECL (__isoc99_vfwscanf);
16155 NLDBL_DECL (__isoc99_vswscanf);
16156+#endif
16157
16158 /* This one does not exist in the normal interface, only
16159 __nldbl___vstrfmon really exists. */
16160@@ -82,22 +85,23 @@ extern ssize_t __nldbl___vstrfmon (char *, size_t, const char *, va_list)
16161 since we don't compile with _FORTIFY_SOURCE. */
16162 extern int __nldbl___vfprintf_chk (FILE *__restrict, int,
16163 const char *__restrict, _G_va_list);
16164-extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
16165- const wchar_t *__restrict, __gnuc_va_list);
16166 extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t,
16167 const char *__restrict, _G_va_list) __THROW;
16168 extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t,
16169 const char *__restrict, _G_va_list)
16170 __THROW;
16171-extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
16172- const wchar_t *__restrict, __gnuc_va_list)
16173- __THROW;
16174 extern int __nldbl___vasprintf_chk (char **, int, const char *, _G_va_list)
16175 __THROW;
16176 extern int __nldbl___vdprintf_chk (int, int, const char *, _G_va_list);
16177 extern int __nldbl___obstack_vprintf_chk (struct obstack *, int, const char *,
16178 _G_va_list) __THROW;
16179 extern void __nldbl___vsyslog_chk (int, int, const char *, va_list);
16180-
16181+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
16182+extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
16183+ const wchar_t *__restrict, __gnuc_va_list);
16184+extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
16185+ const wchar_t *__restrict, __gnuc_va_list)
16186+ __THROW;
16187+#endif
16188
16189 #endif /* __NLDBL_COMPAT_H */
16190diff --git a/sysdeps/nptl/Makefile b/sysdeps/nptl/Makefile
16191index e9339a3..782009b 100644
16192--- a/sysdeps/nptl/Makefile
16193+++ b/sysdeps/nptl/Makefile
16194@@ -18,6 +18,9 @@
16195
16196 ifeq ($(subdir),nptl)
16197 libpthread-sysdep_routines += errno-loc
16198+ifeq ($(OPTION_EGLIBC_BIG_MACROS),n)
16199+sysdep_routines += small-macros-fns
16200+endif
16201 endif
16202
16203 ifeq ($(subdir),rt)
16204diff --git a/sysdeps/nptl/bits/libc-lock.h b/sysdeps/nptl/bits/libc-lock.h
16205index 5599cf1..b839378 100644
16206--- a/sysdeps/nptl/bits/libc-lock.h
16207+++ b/sysdeps/nptl/bits/libc-lock.h
16208@@ -24,6 +24,14 @@
16209 #include <stddef.h>
16210
16211
16212+#ifdef _LIBC
16213+# include <lowlevellock.h>
16214+# include <tls.h>
16215+# include <pthread-functions.h>
16216+# include <errno.h> /* For EBUSY. */
16217+# include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */
16218+#endif
16219+
16220 /* Mutex type. */
16221 #if defined _LIBC || defined _IO_MTSAFE_IO
16222 # if (!IS_IN (libc) && !IS_IN (libpthread)) || !defined _LIBC
16223@@ -87,6 +95,15 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
16224
16225 /* Lock the recursive named lock variable. */
16226 #if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
16227+# if __OPTION_EGLIBC_BIG_MACROS != 1
16228+/* EGLIBC: Declare wrapper function for a big macro if either
16229+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16230+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16231+extern void __libc_lock_lock_recursive_fn (__libc_lock_recursive_t *);
16232+libc_hidden_proto (__libc_lock_lock_recursive_fn);
16233+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16234+# if __OPTION_EGLIBC_BIG_MACROS
16235+
16236 # define __libc_lock_lock_recursive(NAME) \
16237 do { \
16238 void *self = THREAD_SELF; \
16239@@ -97,6 +114,10 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
16240 } \
16241 ++(NAME).cnt; \
16242 } while (0)
16243+# else
16244+# define __libc_lock_lock_recursive(NAME) \
16245+ __libc_lock_lock_recursive_fn (&(NAME))
16246+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16247 #else
16248 # define __libc_lock_lock_recursive(NAME) \
16249 __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
16250@@ -104,6 +125,14 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
16251
16252 /* Try to lock the recursive named lock variable. */
16253 #if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
16254+# if __OPTION_EGLIBC_BIG_MACROS != 1
16255+/* EGLIBC: Declare wrapper function for a big macro if either
16256+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16257+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16258+extern int __libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *);
16259+libc_hidden_proto (__libc_lock_trylock_recursive_fn);
16260+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16261+# if __OPTION_EGLIBC_BIG_MACROS
16262 # define __libc_lock_trylock_recursive(NAME) \
16263 ({ \
16264 int result = 0; \
16265@@ -122,6 +151,10 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
16266 ++(NAME).cnt; \
16267 result; \
16268 })
16269+# else
16270+# define __libc_lock_trylock_recursive(NAME) \
16271+ __libc_lock_trylock_recursive_fn (&(NAME))
16272+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16273 #else
16274 # define __libc_lock_trylock_recursive(NAME) \
16275 __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0)
16276@@ -129,6 +162,14 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
16277
16278 /* Unlock the recursive named lock variable. */
16279 #if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
16280+# if __OPTION_EGLIBC_BIG_MACROS != 1
16281+/* EGLIBC: Declare wrapper function for a big macro if either
16282+ !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
16283+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16284+extern void __libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *);
16285+libc_hidden_proto (__libc_lock_unlock_recursive_fn);
16286+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16287+# if __OPTION_EGLIBC_BIG_MACROS
16288 /* We do no error checking here. */
16289 # define __libc_lock_unlock_recursive(NAME) \
16290 do { \
16291@@ -138,6 +179,10 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
16292 lll_unlock ((NAME).lock, LLL_PRIVATE); \
16293 } \
16294 } while (0)
16295+# else
16296+# define __libc_lock_unlock_recursive(NAME) \
16297+ __libc_lock_unlock_recursive_fn (&(NAME))
16298+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16299 #else
16300 # define __libc_lock_unlock_recursive(NAME) \
16301 __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
16302diff --git a/sysdeps/nptl/bits/libc-lockP.h b/sysdeps/nptl/bits/libc-lockP.h
16303index f55f621..da98869 100644
16304--- a/sysdeps/nptl/bits/libc-lockP.h
16305+++ b/sysdeps/nptl/bits/libc-lockP.h
16306@@ -33,6 +33,8 @@
16307 #include <lowlevellock.h>
16308 #include <tls.h>
16309 #include <pthread-functions.h>
16310+#include <errno.h> /* For EBUSY. */
16311+#include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */
16312
16313 #if IS_IN (libpthread)
16314 /* This gets us the declarations of the __pthread_* internal names,
16315@@ -171,10 +173,22 @@ typedef pthread_key_t __libc_key_t;
16316
16317 /* Lock the named lock variable. */
16318 #if IS_IN (libc) || IS_IN (libpthread)
16319-# ifndef __libc_lock_lock
16320-# define __libc_lock_lock(NAME) \
16321+# if __OPTION_EGLIBC_BIG_MACROS != 1
16322+/* EGLIBC: Declare wrapper function for a big macro if either
16323+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16324+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16325+extern void __libc_lock_lock_fn (__libc_lock_t *);
16326+libc_hidden_proto (__libc_lock_lock_fn);
16327+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16328+# if __OPTION_EGLIBC_BIG_MACROS
16329+# ifndef __libc_lock_lock
16330+# define __libc_lock_lock(NAME) \
16331 ({ lll_lock (NAME, LLL_PRIVATE); 0; })
16332-# endif
16333+# endif
16334+# else
16335+# define __libc_lock_lock(NAME) \
16336+ __libc_lock_lock_fn (&(NAME))
16337+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16338 #else
16339 # undef __libc_lock_lock
16340 # define __libc_lock_lock(NAME) \
16341@@ -187,10 +201,22 @@ typedef pthread_key_t __libc_key_t;
16342
16343 /* Try to lock the named lock variable. */
16344 #if IS_IN (libc) || IS_IN (libpthread)
16345-# ifndef __libc_lock_trylock
16346-# define __libc_lock_trylock(NAME) \
16347+# if __OPTION_EGLIBC_BIG_MACROS != 1
16348+/* EGLIBC: Declare wrapper function for a big macro if either
16349+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16350+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16351+extern int __libc_lock_trylock_fn (__libc_lock_t *);
16352+libc_hidden_proto (__libc_lock_trylock_fn);
16353+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16354+# if __OPTION_EGLIBC_BIG_MACROS
16355+# ifndef __libc_lock_trylock
16356+# define __libc_lock_trylock(NAME) \
16357 lll_trylock (NAME)
16358-# endif
16359+# endif
16360+# else
16361+# define __libc_lock_trylock(NAME) \
16362+ __libc_lock_trylock_fn (&(NAME))
16363+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16364 #else
16365 # undef __libc_lock_trylock
16366 # define __libc_lock_trylock(NAME) \
16367@@ -206,8 +232,20 @@ typedef pthread_key_t __libc_key_t;
16368
16369 /* Unlock the named lock variable. */
16370 #if IS_IN (libc) || IS_IN (libpthread)
16371+# if __OPTION_EGLIBC_BIG_MACROS != 1
16372+/* EGLIBC: Declare wrapper function for a big macro if either
16373+ !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
16374+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16375+extern void __libc_lock_unlock_fn (__libc_lock_t *);
16376+libc_hidden_proto (__libc_lock_unlock_fn);
16377+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16378+# if __OPTION_EGLIBC_BIG_MACROS
16379 # define __libc_lock_unlock(NAME) \
16380 lll_unlock (NAME, LLL_PRIVATE)
16381+# else
16382+# define __libc_lock_unlock(NAME) \
16383+ __libc_lock_unlock_fn (&(NAME))
16384+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16385 #else
16386 # define __libc_lock_unlock(NAME) \
16387 __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
16388diff --git a/sysdeps/nptl/small-macros-fns.c b/sysdeps/nptl/small-macros-fns.c
16389new file mode 100644
16390index 0000000..f751053
16391--- /dev/null
16392+++ b/sysdeps/nptl/small-macros-fns.c
16393@@ -0,0 +1,72 @@
16394+/* EGLIBC: function wrappers for big macros.
16395+ Copyright (C) 2009 Free Software Foundation, Inc.
16396+ This file is part of the GNU C Library.
16397+
16398+ The GNU C Library is free software; you can redistribute it and/or
16399+ modify it under the terms of the GNU Lesser General Public License as
16400+ published by the Free Software Foundation; either version 2.1 of the
16401+ License, or (at your option) any later version.
16402+
16403+ The GNU C Library is distributed in the hope that it will be useful,
16404+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16405+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16406+ Lesser General Public License for more details.
16407+
16408+ You should have received a copy of the GNU Lesser General Public
16409+ License along with the GNU C Library; see the file COPYING.LIB. If not,
16410+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16411+ Boston, MA 02111-1307, USA. */
16412+
16413+#include <gnu/option-groups.h>
16414+
16415+/* Handle macros from ./bits/libc-lock.h. */
16416+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
16417+
16418+/* Get the macros for function bodies through a back door. */
16419+# undef __OPTION_EGLIBC_BIG_MACROS
16420+# define __OPTION_EGLIBC_BIG_MACROS 2
16421+# include <bits/libc-lock.h>
16422+
16423+void
16424+__libc_lock_lock_fn (__libc_lock_t *name)
16425+{
16426+ __libc_lock_lock (*name);
16427+}
16428+libc_hidden_def (__libc_lock_lock_fn);
16429+
16430+void
16431+__libc_lock_lock_recursive_fn (__libc_lock_recursive_t *name)
16432+{
16433+ __libc_lock_lock_recursive (*name);
16434+}
16435+libc_hidden_def (__libc_lock_lock_recursive_fn);
16436+
16437+int
16438+__libc_lock_trylock_fn (__libc_lock_t *name)
16439+{
16440+ return __libc_lock_trylock (*name);
16441+}
16442+libc_hidden_def (__libc_lock_trylock_fn);
16443+
16444+int
16445+__libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *name)
16446+{
16447+ return __libc_lock_trylock_recursive (*name);
16448+}
16449+libc_hidden_def (__libc_lock_trylock_recursive_fn);
16450+
16451+void
16452+__libc_lock_unlock_fn (__libc_lock_t *name)
16453+{
16454+ __libc_lock_unlock (*name);
16455+}
16456+libc_hidden_def (__libc_lock_unlock_fn);
16457+
16458+void
16459+__libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *name)
16460+{
16461+ __libc_lock_unlock_recursive (*name);
16462+}
16463+libc_hidden_def (__libc_lock_unlock_recursive_fn);
16464+
16465+#endif /*defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)*/
16466diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c
16467index 26e4692..d0a26c8 100644
16468--- a/sysdeps/unix/sysv/linux/gethostid.c
16469+++ b/sysdeps/unix/sysv/linux/gethostid.c
16470@@ -21,6 +21,7 @@
16471 #include <unistd.h>
16472 #include <netdb.h>
16473 #include <not-cancel.h>
16474+#include <gnu/option-groups.h>
16475
16476 #define HOSTIDFILE "/etc/hostid"
16477
16478@@ -89,6 +90,7 @@ gethostid (void)
16479 return id;
16480 }
16481
16482+#if __OPTION_EGLIBC_INET
16483 /* Getting from the file was not successful. An intelligent guess for
16484 a unique number of a host is its IP address. Return this. */
16485 if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0')
16486@@ -115,5 +117,9 @@ gethostid (void)
16487 /* For the return value to be not exactly the IP address we do some
16488 bit fiddling. */
16489 return (int32_t) (in.s_addr << 16 | in.s_addr >> 16);
16490+#else
16491+ /* Return an arbitrary value. */
16492+ return 0;
16493+#endif
16494 }
16495 #endif
16496diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c
16497index 53a8bbb..cb110d4 100644
16498--- a/sysdeps/unix/sysv/linux/libc_fatal.c
16499+++ b/sysdeps/unix/sysv/linux/libc_fatal.c
16500@@ -23,6 +23,7 @@
16501 #include <string.h>
16502 #include <sys/mman.h>
16503 #include <sys/uio.h>
16504+#include <gnu/option-groups.h>
16505
16506 static bool
16507 writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
16508@@ -40,6 +41,7 @@ writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
16509 static void
16510 backtrace_and_maps (int do_abort, bool written, int fd)
16511 {
16512+#if __OPTION_EGLIBC_BACKTRACE
16513 if (do_abort > 1 && written)
16514 {
16515 void *addrs[64];
16516@@ -62,6 +64,7 @@ backtrace_and_maps (int do_abort, bool written, int fd)
16517 close_not_cancel_no_status (fd2);
16518 }
16519 }
16520+#endif /* __OPTION_EGLIBC_BACKTRACE */
16521 }
16522 #define BEFORE_ABORT backtrace_and_maps
16523
16524diff --git a/time/Makefile b/time/Makefile
16525index a411f62..2d022ca 100644
16526--- a/time/Makefile
16527+++ b/time/Makefile
16528@@ -18,6 +18,8 @@
16529 #
16530 # Makefile for time routines
16531 #
16532+include ../option-groups.mak
16533+
16534 subdir := time
16535
16536 include ../Makeconfig
16537@@ -30,15 +32,23 @@ routines := offtime asctime clock ctime ctime_r difftime \
16538 tzfile getitimer setitimer \
16539 stime dysize timegm ftime \
16540 getdate strptime strptime_l \
16541- strftime wcsftime strftime_l wcsftime_l \
16542+ strftime strftime_l \
16543 timespec_get
16544-aux := era alt_digit lc-time-cleanup
16545
16546-tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
16547- tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
16548+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16549+ := wcsftime wcsftime_l
16550+aux-$(OPTION_EGLIBC_LOCALE_CODE) += alt_digit era lc-time-cleanup
16551+
16552+tests := test_time clocktest tst-posixtz \
16553+ tst-getdate tst-mktime tst-mktime2 tst-strftime \
16554 tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
16555 tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime
16556
16557+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
16558+ += tst-strptime tst-ftime_l
16559+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
16560+ += tst_wcsftime
16561+
16562 include ../Rules
16563
16564 tz-cflags = -DTZDIR='"$(zonedir)"' \
16565diff --git a/time/strftime_l.c b/time/strftime_l.c
16566index b48ef34..bfdd618 100644
16567--- a/time/strftime_l.c
16568+++ b/time/strftime_l.c
16569@@ -35,6 +35,10 @@
16570 # include "../locale/localeinfo.h"
16571 #endif
16572
16573+#ifdef _LIBC
16574+# include <gnu/option-groups.h>
16575+#endif
16576+
16577 #if defined emacs && !defined HAVE_BCOPY
16578 # define HAVE_MEMCPY 1
16579 #endif
16580@@ -882,7 +886,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
16581 case L_('C'):
16582 if (modifier == L_('E'))
16583 {
16584-#if HAVE_STRUCT_ERA_ENTRY
16585+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
16586 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
16587 if (era)
16588 {
16589@@ -955,7 +959,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
16590
16591 if (modifier == L_('O') && 0 <= number_value)
16592 {
16593-#ifdef _NL_CURRENT
16594+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
16595 /* Get the locale specific alternate representation of
16596 the number NUMBER_VALUE. If none exist NULL is returned. */
16597 const CHAR_T *cp = nl_get_alt_digit (number_value
16598@@ -1260,7 +1264,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
16599 case L_('Y'):
16600 if (modifier == 'E')
16601 {
16602-#if HAVE_STRUCT_ERA_ENTRY
16603+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
16604 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
16605 if (era)
16606 {
16607@@ -1285,7 +1289,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
16608 case L_('y'):
16609 if (modifier == L_('E'))
16610 {
16611-#if HAVE_STRUCT_ERA_ENTRY
16612+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
16613 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
16614 if (era)
16615 {
16616diff --git a/time/strptime_l.c b/time/strptime_l.c
16617index 5640cce..784ccbc 100644
16618--- a/time/strptime_l.c
16619+++ b/time/strptime_l.c
16620@@ -29,6 +29,7 @@
16621
16622 #ifdef _LIBC
16623 # define HAVE_LOCALTIME_R 0
16624+# include <gnu/option-groups.h>
16625 # include "../locale/localeinfo.h"
16626 #endif
16627
16628@@ -84,7 +85,7 @@ localtime_r (t, tp)
16629 if (val < from || val > to) \
16630 return NULL; \
16631 } while (0)
16632-#ifdef _NL_CURRENT
16633+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
16634 # define get_alt_number(from, to, n) \
16635 ({ \
16636 __label__ do_normal; \
16637@@ -257,8 +258,10 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
16638 int cnt;
16639 int cnt_longest;
16640 size_t val;
16641+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16642 size_t num_eras;
16643 struct era_entry *era = NULL;
16644+#endif
16645 enum ptime_locale_status { not, loc, raw } decided_longest;
16646 struct __strptime_state
16647 {
16648@@ -820,6 +823,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
16649 s.want_xday = 1;
16650 break;
16651 case 'C':
16652+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16653 if (s.decided != raw)
16654 {
16655 if (s.era_cnt >= 0)
16656@@ -856,10 +860,12 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
16657
16658 s.decided = raw;
16659 }
16660+#endif
16661 /* The C locale has no era information, so use the
16662 normal representation. */
16663 goto match_century;
16664 case 'y':
16665+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16666 if (s.decided != raw)
16667 {
16668 get_number(0, 9999, 4);
16669@@ -918,9 +924,10 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
16670
16671 s.decided = raw;
16672 }
16673-
16674+#endif
16675 goto match_year_in_century;
16676 case 'Y':
16677+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16678 if (s.decided != raw)
16679 {
16680 num_eras = _NL_CURRENT_WORD (LC_TIME,
16681@@ -948,6 +955,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
16682
16683 s.decided = raw;
16684 }
16685+#endif
16686 get_number (0, 9999, 4);
16687 tm->tm_year = val - 1900;
16688 s.want_century = 0;
16689@@ -1118,6 +1126,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
16690 tm->tm_year = (s.century - 19) * 100;
16691 }
16692
16693+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16694 if (s.era_cnt != -1)
16695 {
16696 era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);
16697@@ -1132,6 +1141,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
16698 tm->tm_year = era->start_date[0];
16699 }
16700 else
16701+#endif
16702 if (s.want_era)
16703 {
16704 /* No era found but we have seen an E modifier. Rectify some
16705diff --git a/timezone/Makefile b/timezone/Makefile
16706index 886b06e..f922684 100644
16707--- a/timezone/Makefile
16708+++ b/timezone/Makefile
16709@@ -127,7 +127,7 @@ $(testdata)/XT%: testdata/XT%
16710
16711 $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
16712 sed -e 's|/bin/bash|/bin/sh|' \
16713- -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
16714+ -e '/TZDIR=/s|\$$(pwd)|$(zonedir)|' \
16715 -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
16716 -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \
16717 -e '/REPORT_BUGS_TO=/s|=.*|="$(REPORT_BUGS_TO)"|' \
16718diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
16719index 44a4494..db9fc24 100644
16720--- a/wcsmbs/Makefile
16721+++ b/wcsmbs/Makefile
16722@@ -18,15 +18,21 @@
16723 #
16724 # Sub-makefile for wcsmbs portion of the library.
16725 #
16726+include ../option-groups.mak
16727+
16728 subdir := wcsmbs
16729
16730 include ../Makeconfig
16731
16732 headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h
16733
16734-routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
16735+# These functions are used by printf_fp.c, even in the plain case; see
16736+# comments there for OPTION_EGLIBC_LOCALE_CODE.
16737+routines := wmemcpy wmemset
16738+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16739+ := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
16740 wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
16741- wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy wmempcpy \
16742+ wmemcmp wmemmove wcpcpy wcpncpy wmempcpy \
16743 btowc wctob mbsinit \
16744 mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
16745 mbsnrtowcs wcsnrtombs wcsnlen wcschrnul \
16746@@ -38,14 +44,21 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
16747 wcscoll_l wcsxfrm_l \
16748 wcscasecmp wcsncase wcscasecmp_l wcsncase_l \
16749 wcsmbsload mbsrtowcs_l \
16750- isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
16751 isoc99_swscanf isoc99_vswscanf \
16752 mbrtoc16 c16rtomb
16753
16754-strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy
16755-tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
16756- tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
16757- tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests))
16758+routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
16759+ += isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf
16760+
16761+strop-tests := wcscmp wmemcmp wmemcmp wcslen wcschr wcsrchr wcscpy
16762+
16763+tests := tst-wchar-h
16764+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
16765+ += tst-btowc tst-mbrtowc tst-mbrtowc2 tst-wcrtomb tst-c16c32-1
16766+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16767+ += tst-wcstof wcsmbs-tst1 tst-wcsnlen \
16768+ tst-wcpncpy tst-mbsrtowcs \
16769+ wcsatcliff $(addprefix test-,$(strop-tests))
16770
16771 include ../Rules
16772
16773diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c
16774index 6bb49bc..2ab9d07 100644
16775--- a/wcsmbs/wcsmbsload.c
16776+++ b/wcsmbs/wcsmbsload.c
16777@@ -21,6 +21,7 @@
16778 #include <limits.h>
16779 #include <stdlib.h>
16780 #include <string.h>
16781+#include <gnu/option-groups.h>
16782
16783 #include <locale/localeinfo.h>
16784 #include <wcsmbsload.h>
16785@@ -143,6 +144,7 @@ __wcsmbs_getfct (const char *to, const char *from, size_t *nstepsp)
16786 })
16787
16788
16789+#if __OPTION_EGLIBC_LOCALE_CODE
16790 /* Some of the functions here must not be used while setlocale is called. */
16791 __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
16792
16793@@ -211,6 +213,17 @@ __wcsmbs_load_conv (struct __locale_data *new_category)
16794
16795 __libc_rwlock_unlock (__libc_setlocale_lock);
16796 }
16797+#else
16798+void
16799+internal_function
16800+__wcsmbs_load_conv (struct __locale_data *new_category)
16801+{
16802+ /* When OPTION_EGLIBC_LOCALE_CODE is disabled, we should never reach
16803+ this point: there is no way to change locales, so every locale
16804+ passed to get_gconv_fcts should be _nl_C_LC_CTYPE. */
16805+ abort ();
16806+}
16807+#endif
16808
16809
16810 /* Clone the current conversion function set. */
16811diff --git a/wctype/Makefile b/wctype/Makefile
16812index c56f07c..4e8af43 100644
16813--- a/wctype/Makefile
16814+++ b/wctype/Makefile
16815@@ -18,14 +18,20 @@
16816 #
16817 # Sub-makefile for wctype portion of the library.
16818 #
16819+include ../option-groups.mak
16820+
16821 subdir := wctype
16822
16823 include ../Makeconfig
16824
16825 headers := wctype.h
16826-routines := wcfuncs wctype iswctype wctrans towctrans \
16827- wcfuncs_l wctype_l iswctype_l wctrans_l towctrans_l
16828-
16829-tests := test_wctype test_wcfuncs bug-wctypeh
16830+routines := wctrans towctrans towctrans_l
16831+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16832+ := wcfuncs wctype iswctype \
16833+ wcfuncs_l wctype_l iswctype_l wctrans_l
16834+
16835+tests :=
16836+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16837+ += test_wctype test_wcfuncs bug-wctypeh
16838
16839 include ../Rules
16840--
168412.1.4
16842
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 0000000000..68d11192ac
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0025-eglibc-Forward-port-cross-locale-generation-support.patch
@@ -0,0 +1,566 @@
1From a5695930aec68b3f501e475d8705cddbb63f695e Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 01:33:49 +0000
4Subject: [PATCH 25/25] eglibc: Forward port cross locale generation support
5
6Upstream-Status: Pending
7
8Signed-off-by: Khem Raj <raj.khem@gmail.com>
9---
10 locale/Makefile | 3 ++-
11 locale/catnames.c | 48 +++++++++++++++++++++++++++++++++++
12 locale/localeinfo.h | 2 +-
13 locale/programs/charmap-dir.c | 6 +++++
14 locale/programs/ld-collate.c | 17 ++++++-------
15 locale/programs/ld-ctype.c | 27 ++++++++++----------
16 locale/programs/ld-time.c | 31 +++++++++++++++--------
17 locale/programs/linereader.c | 2 +-
18 locale/programs/localedef.c | 8 ++++++
19 locale/programs/locfile.c | 5 +++-
20 locale/programs/locfile.h | 59 +++++++++++++++++++++++++++++++++++++++++--
21 locale/setlocale.c | 30 ----------------------
22 12 files changed, 169 insertions(+), 69 deletions(-)
23 create mode 100644 locale/catnames.c
24
25diff --git a/locale/Makefile b/locale/Makefile
26index 75afbe1..d32523b 100644
27--- a/locale/Makefile
28+++ b/locale/Makefile
29@@ -25,7 +25,8 @@ include ../Makeconfig
30 headers = locale.h bits/locale.h langinfo.h xlocale.h
31 routines = setlocale findlocale loadlocale loadarchive \
32 localeconv nl_langinfo nl_langinfo_l mb_cur_max \
33- newlocale duplocale freelocale uselocale
34+ newlocale duplocale freelocale uselocale \
35+ catnames
36 tests = tst-C-locale tst-locname tst-duplocale
37 categories = ctype messages monetary numeric time paper name \
38 address telephone measurement identification collate
39diff --git a/locale/catnames.c b/locale/catnames.c
40new file mode 100644
41index 0000000..9fad357
42--- /dev/null
43+++ b/locale/catnames.c
44@@ -0,0 +1,48 @@
45+/* Copyright (C) 2006 Free Software Foundation, Inc.
46+ This file is part of the GNU C Library.
47+
48+ The GNU C Library is free software; you can redistribute it and/or
49+ modify it under the terms of the GNU Lesser General Public
50+ License as published by the Free Software Foundation; either
51+ version 2.1 of the License, or (at your option) any later version.
52+
53+ The GNU C Library is distributed in the hope that it will be useful,
54+ but WITHOUT ANY WARRANTY; without even the implied warranty of
55+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
56+ Lesser General Public License for more details.
57+
58+ You should have received a copy of the GNU Lesser General Public
59+ License along with the GNU C Library; if not, write to the Free
60+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
61+ 02111-1307 USA. */
62+
63+#include "localeinfo.h"
64+
65+/* Define an array of category names (also the environment variable names). */
66+const union catnamestr_t _nl_category_names attribute_hidden =
67+ {
68+ {
69+#define DEFINE_CATEGORY(category, category_name, items, a) \
70+ category_name,
71+#include "categories.def"
72+#undef DEFINE_CATEGORY
73+ }
74+ };
75+
76+const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
77+ {
78+#define DEFINE_CATEGORY(category, category_name, items, a) \
79+ [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
80+#include "categories.def"
81+#undef DEFINE_CATEGORY
82+ };
83+
84+/* An array of their lengths, for convenience. */
85+const uint8_t _nl_category_name_sizes[] attribute_hidden =
86+ {
87+#define DEFINE_CATEGORY(category, category_name, items, a) \
88+ [category] = sizeof (category_name) - 1,
89+#include "categories.def"
90+#undef DEFINE_CATEGORY
91+ [LC_ALL] = sizeof ("LC_ALL") - 1
92+ };
93diff --git a/locale/localeinfo.h b/locale/localeinfo.h
94index 789da44..4ac9249 100644
95--- a/locale/localeinfo.h
96+++ b/locale/localeinfo.h
97@@ -224,7 +224,7 @@ __libc_tsd_define (extern, __locale_t, LOCALE)
98 unused. We can manage this playing some tricks with weak references.
99 But with thread-local locale settings, it becomes quite ungainly unless
100 we can use __thread variables. So only in that case do we attempt this. */
101-#ifndef SHARED
102+#if !defined SHARED && !defined IN_GLIBC_LOCALEDEF
103 # include <tls.h>
104 # define NL_CURRENT_INDIRECT 1
105 #endif
106diff --git a/locale/programs/charmap-dir.c b/locale/programs/charmap-dir.c
107index cf7adea..ef3b811 100644
108--- a/locale/programs/charmap-dir.c
109+++ b/locale/programs/charmap-dir.c
110@@ -19,7 +19,9 @@
111 #include <error.h>
112 #include <fcntl.h>
113 #include <libintl.h>
114+#ifndef NO_UNCOMPRESS
115 #include <spawn.h>
116+#endif
117 #include <stdio.h>
118 #include <stdlib.h>
119 #include <string.h>
120@@ -156,6 +158,7 @@ charmap_closedir (CHARMAP_DIR *cdir)
121 return closedir (dir);
122 }
123
124+#ifndef NO_UNCOMPRESS
125 /* Creates a subprocess decompressing the given pathname, and returns
126 a stream reading its output (the decompressed data). */
127 static
128@@ -204,6 +207,7 @@ fopen_uncompressed (const char *pathname, const char *compressor)
129 }
130 return NULL;
131 }
132+#endif
133
134 /* Opens a charmap for reading, given its name (not an alias name). */
135 FILE *
136@@ -226,6 +230,7 @@ charmap_open (const char *directory, const char *name)
137 if (stream != NULL)
138 return stream;
139
140+#ifndef NO_UNCOMPRESS
141 memcpy (p, ".gz", 4);
142 stream = fopen_uncompressed (pathname, "gzip");
143 if (stream != NULL)
144@@ -235,6 +240,7 @@ charmap_open (const char *directory, const char *name)
145 stream = fopen_uncompressed (pathname, "bzip2");
146 if (stream != NULL)
147 return stream;
148+#endif
149
150 return NULL;
151 }
152diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
153index dc0fe30..3c88c6d 100644
154--- a/locale/programs/ld-collate.c
155+++ b/locale/programs/ld-collate.c
156@@ -350,7 +350,7 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
157 }
158 if (wcs != NULL)
159 {
160- size_t nwcs = wcslen ((wchar_t *) wcs);
161+ size_t nwcs = wcslen_uint32 (wcs);
162 uint32_t zero = 0;
163 /* Handle <U0000> as a single character. */
164 if (nwcs == 0)
165@@ -1776,8 +1776,7 @@ symbol `%s' has the same encoding as"), (*eptr)->name);
166
167 if ((*eptr)->nwcs == runp->nwcs)
168 {
169- int c = wmemcmp ((wchar_t *) (*eptr)->wcs,
170- (wchar_t *) runp->wcs, runp->nwcs);
171+ int c = wmemcmp_uint32 ((*eptr)->wcs, runp->wcs, runp->nwcs);
172
173 if (c == 0)
174 {
175@@ -2010,9 +2009,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
176 one consecutive entry. */
177 if (runp->wcnext != NULL
178 && runp->nwcs == runp->wcnext->nwcs
179- && wmemcmp ((wchar_t *) runp->wcs,
180- (wchar_t *)runp->wcnext->wcs,
181- runp->nwcs - 1) == 0
182+ && wmemcmp_uint32 (runp->wcs,
183+ runp->wcnext->wcs,
184+ runp->nwcs - 1) == 0
185 && (runp->wcs[runp->nwcs - 1]
186 == runp->wcnext->wcs[runp->nwcs - 1] + 1))
187 {
188@@ -2036,9 +2035,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
189 runp = runp->wcnext;
190 while (runp->wcnext != NULL
191 && runp->nwcs == runp->wcnext->nwcs
192- && wmemcmp ((wchar_t *) runp->wcs,
193- (wchar_t *)runp->wcnext->wcs,
194- runp->nwcs - 1) == 0
195+ && wmemcmp_uint32 (runp->wcs,
196+ runp->wcnext->wcs,
197+ runp->nwcs - 1) == 0
198 && (runp->wcs[runp->nwcs - 1]
199 == runp->wcnext->wcs[runp->nwcs - 1] + 1));
200
201diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
202index 3f464ef..b7b6b51 100644
203--- a/locale/programs/ld-ctype.c
204+++ b/locale/programs/ld-ctype.c
205@@ -926,7 +926,7 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
206 allocate_arrays (ctype, charmap, ctype->repertoire);
207
208 default_missing_len = (ctype->default_missing
209- ? wcslen ((wchar_t *) ctype->default_missing)
210+ ? wcslen_uint32 (ctype->default_missing)
211 : 0);
212
213 init_locale_data (&file, nelems);
214@@ -1937,7 +1937,7 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype,
215 ignore = 1;
216 else
217 /* This value is usable. */
218- obstack_grow (ob, to_wstr, wcslen ((wchar_t *) to_wstr) * 4);
219+ obstack_grow (ob, to_wstr, wcslen_uint32 (to_wstr) * 4);
220
221 first = 0;
222 }
223@@ -2471,8 +2471,8 @@ with character code range values one must use the absolute ellipsis `...'"));
224 }
225
226 handle_tok_digit:
227- class_bit = _ISwdigit;
228- class256_bit = _ISdigit;
229+ class_bit = BITw (tok_digit);
230+ class256_bit = BIT (tok_digit);
231 handle_digits = 1;
232 goto read_charclass;
233
234@@ -3929,8 +3929,7 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
235
236 while (idx < number)
237 {
238- int res = wcscmp ((const wchar_t *) sorted[idx]->from,
239- (const wchar_t *) runp->from);
240+ int res = wcscmp_uint32 (sorted[idx]->from, runp->from);
241 if (res == 0)
242 {
243 replace = 1;
244@@ -3967,11 +3966,11 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
245 for (size_t cnt = 0; cnt < number; ++cnt)
246 {
247 struct translit_to_t *srunp;
248- from_len += wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
249+ from_len += wcslen_uint32 (sorted[cnt]->from) + 1;
250 srunp = sorted[cnt]->to;
251 while (srunp != NULL)
252 {
253- to_len += wcslen ((const wchar_t *) srunp->str) + 1;
254+ to_len += wcslen_uint32 (srunp->str) + 1;
255 srunp = srunp->next;
256 }
257 /* Plus one for the extra NUL character marking the end of
258@@ -3995,18 +3994,18 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
259 ctype->translit_from_idx[cnt] = from_len;
260 ctype->translit_to_idx[cnt] = to_len;
261
262- len = wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
263- wmemcpy ((wchar_t *) &ctype->translit_from_tbl[from_len],
264- (const wchar_t *) sorted[cnt]->from, len);
265+ len = wcslen_uint32 (sorted[cnt]->from) + 1;
266+ wmemcpy_uint32 (&ctype->translit_from_tbl[from_len],
267+ sorted[cnt]->from, len);
268 from_len += len;
269
270 ctype->translit_to_idx[cnt] = to_len;
271 srunp = sorted[cnt]->to;
272 while (srunp != NULL)
273 {
274- len = wcslen ((const wchar_t *) srunp->str) + 1;
275- wmemcpy ((wchar_t *) &ctype->translit_to_tbl[to_len],
276- (const wchar_t *) srunp->str, len);
277+ len = wcslen_uint32 (srunp->str) + 1;
278+ wmemcpy_uint32 (&ctype->translit_to_tbl[to_len],
279+ srunp->str, len);
280 to_len += len;
281 srunp = srunp->next;
282 }
283diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
284index db490c6..75dc505 100644
285--- a/locale/programs/ld-time.c
286+++ b/locale/programs/ld-time.c
287@@ -215,8 +215,10 @@ No definition for %s category found"), "LC_TIME"));
288 }
289 else
290 {
291+ static const uint32_t wt_fmt_ampm[]
292+ = { '%','I',':','%','M',':','%','S',' ','%','p',0 };
293 time->t_fmt_ampm = "%I:%M:%S %p";
294- time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p";
295+ time->wt_fmt_ampm = wt_fmt_ampm;
296 }
297 }
298
299@@ -226,7 +228,7 @@ No definition for %s category found"), "LC_TIME"));
300 const int days_per_month[12] = { 31, 29, 31, 30, 31, 30,
301 31, 31, 30, 31 ,30, 31 };
302 size_t idx;
303- wchar_t *wstr;
304+ uint32_t *wstr;
305
306 time->era_entries =
307 (struct era_data *) xmalloc (time->num_era
308@@ -464,18 +466,18 @@ No definition for %s category found"), "LC_TIME"));
309 }
310
311 /* Now generate the wide character name and format. */
312- wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */
313- wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end offset */
314- wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end start */
315- wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end end */
316+ wstr = wcschr_uint32 (time->wera[idx], L':'); /* end direction */
317+ wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end offset */
318+ wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end start */
319+ wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end end */
320 if (wstr != NULL)
321 {
322- time->era_entries[idx].wname = (uint32_t *) wstr + 1;
323- wstr = wcschr (wstr + 1, L':'); /* end name */
324+ time->era_entries[idx].wname = wstr + 1;
325+ wstr = wcschr_uint32 (wstr + 1, L':'); /* end name */
326 if (wstr != NULL)
327 {
328 *wstr = L'\0';
329- time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
330+ time->era_entries[idx].wformat = wstr + 1;
331 }
332 else
333 time->era_entries[idx].wname =
334@@ -530,7 +532,16 @@ No definition for %s category found"), "LC_TIME"));
335 if (time->date_fmt == NULL)
336 time->date_fmt = "%a %b %e %H:%M:%S %Z %Y";
337 if (time->wdate_fmt == NULL)
338- time->wdate_fmt = (const uint32_t *) L"%a %b %e %H:%M:%S %Z %Y";
339+ {
340+ static const uint32_t wdate_fmt[] =
341+ { '%','a',' ',
342+ '%','b',' ',
343+ '%','e',' ',
344+ '%','H',':','%','M',':','%','S',' ',
345+ '%','Z',' ',
346+ '%','Y',0 };
347+ time->wdate_fmt = wdate_fmt;
348+ }
349 }
350
351
352diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c
353index 2e05130..653b68c 100644
354--- a/locale/programs/linereader.c
355+++ b/locale/programs/linereader.c
356@@ -595,7 +595,7 @@ get_string (struct linereader *lr, const struct charmap_t *charmap,
357 {
358 int return_widestr = lr->return_widestr;
359 char *buf;
360- wchar_t *buf2 = NULL;
361+ uint32_t *buf2 = NULL;
362 size_t bufact;
363 size_t bufmax = 56;
364
365diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
366index fd6ca51..328d36c 100644
367--- a/locale/programs/localedef.c
368+++ b/locale/programs/localedef.c
369@@ -114,6 +114,7 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
370 #define OPT_LIST_ARCHIVE 309
371 #define OPT_LITTLE_ENDIAN 400
372 #define OPT_BIG_ENDIAN 401
373+#define OPT_UINT32_ALIGN 402
374
375 /* Definitions of arguments for argp functions. */
376 static const struct argp_option options[] =
377@@ -150,6 +151,8 @@ static const struct argp_option options[] =
378 N_("Generate little-endian output") },
379 { "big-endian", OPT_BIG_ENDIAN, NULL, 0,
380 N_("Generate big-endian output") },
381+ { "uint32-align", OPT_UINT32_ALIGN, "ALIGNMENT", 0,
382+ N_("Set the target's uint32_t alignment in bytes (default 4)") },
383 { NULL, 0, NULL, 0, NULL }
384 };
385
386@@ -239,12 +242,14 @@ main (int argc, char *argv[])
387 ctype locale. (P1003.2 4.35.5.2) */
388 setlocale (LC_CTYPE, "POSIX");
389
390+#ifndef NO_SYSCONF
391 /* Look whether the system really allows locale definitions. POSIX
392 defines error code 3 for this situation so I think it must be
393 a fatal error (see P1003.2 4.35.8). */
394 if (sysconf (_SC_2_LOCALEDEF) < 0)
395 WITH_CUR_LOCALE (error (3, 0, _("\
396 FATAL: system does not define `_POSIX2_LOCALEDEF'")));
397+#endif
398
399 /* Process charmap file. */
400 charmap = charmap_read (charmap_file, verbose, 1, be_quiet, 1);
401@@ -338,6 +343,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
402 case OPT_BIG_ENDIAN:
403 set_big_endian (true);
404 break;
405+ case OPT_UINT32_ALIGN:
406+ uint32_align_mask = strtol (arg, NULL, 0) - 1;
407+ break;
408 case 'c':
409 force_output = 1;
410 break;
411diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c
412index 33da52e..f790c4c 100644
413--- a/locale/programs/locfile.c
414+++ b/locale/programs/locfile.c
415@@ -544,6 +544,9 @@ compare_files (const char *filename1, const char *filename2, size_t size,
416 machine running localedef. */
417 bool swap_endianness_p;
418
419+/* The target's value of __align__(uint32_t) - 1. */
420+unsigned int uint32_align_mask = 3;
421+
422 /* When called outside a start_locale_structure/end_locale_structure
423 or start_locale_prelude/end_locale_prelude block, record that the
424 next byte in FILE's obstack will be the first byte of a new element.
425@@ -621,7 +624,7 @@ add_locale_string (struct locale_file *file, const char *string)
426 void
427 add_locale_wstring (struct locale_file *file, const uint32_t *string)
428 {
429- add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1);
430+ add_locale_uint32_array (file, string, wcslen_uint32 (string) + 1);
431 }
432
433 /* Record that FILE's next element is the 32-bit integer VALUE. */
434diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h
435index 6fc441b..118b171 100644
436--- a/locale/programs/locfile.h
437+++ b/locale/programs/locfile.h
438@@ -71,6 +71,8 @@ extern void write_all_categories (struct localedef_t *definitions,
439
440 extern bool swap_endianness_p;
441
442+extern unsigned int uint32_align_mask;
443+
444 /* Change the output to be big-endian if BIG_ENDIAN is true and
445 little-endian otherwise. */
446 static inline void
447@@ -89,7 +91,8 @@ maybe_swap_uint32 (uint32_t value)
448 }
449
450 /* Likewise, but munge an array of N uint32_ts starting at ARRAY. */
451-static inline void
452+static void
453+__attribute__ ((unused))
454 maybe_swap_uint32_array (uint32_t *array, size_t n)
455 {
456 if (swap_endianness_p)
457@@ -99,7 +102,8 @@ maybe_swap_uint32_array (uint32_t *array, size_t n)
458
459 /* Like maybe_swap_uint32_array, but the array of N elements is at
460 the end of OBSTACK's current object. */
461-static inline void
462+static void
463+__attribute__ ((unused))
464 maybe_swap_uint32_obstack (struct obstack *obstack, size_t n)
465 {
466 maybe_swap_uint32_array ((uint32_t *) obstack_next_free (obstack) - n, n);
467@@ -276,4 +280,55 @@ extern void identification_output (struct localedef_t *locale,
468 const struct charmap_t *charmap,
469 const char *output_path);
470
471+static size_t wcslen_uint32 (const uint32_t *str) __attribute__ ((unused));
472+static uint32_t * wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
473+static uint32_t * wcschr_uint32 (const uint32_t *s, uint32_t ch) __attribute__ ((unused));
474+static int wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2) __attribute__ ((unused));
475+static int wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
476+
477+static size_t
478+wcslen_uint32 (const uint32_t *str)
479+{
480+ size_t len = 0;
481+ while (str[len] != 0)
482+ len++;
483+ return len;
484+}
485+
486+static int
487+wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n)
488+{
489+ while (n-- != 0)
490+ {
491+ int diff = *s1++ - *s2++;
492+ if (diff != 0)
493+ return diff;
494+ }
495+ return 0;
496+}
497+
498+static int
499+wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2)
500+{
501+ while (*s1 != 0 && *s1 == *s2)
502+ s1++, s2++;
503+ return *s1 - *s2;
504+}
505+
506+static uint32_t *
507+wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n)
508+{
509+ return memcpy (s1, s2, n * sizeof (uint32_t));
510+}
511+
512+static uint32_t *
513+wcschr_uint32 (const uint32_t *s, uint32_t ch)
514+{
515+ do
516+ if (*s == ch)
517+ return (uint32_t *) s;
518+ while (*s++ != 0);
519+ return 0;
520+}
521+
522 #endif /* locfile.h */
523diff --git a/locale/setlocale.c b/locale/setlocale.c
524index ead030d..b551332 100644
525--- a/locale/setlocale.c
526+++ b/locale/setlocale.c
527@@ -64,36 +64,6 @@ static char *const _nl_current_used[] =
528 #endif
529
530
531-/* Define an array of category names (also the environment variable names). */
532-const union catnamestr_t _nl_category_names attribute_hidden =
533- {
534- {
535-#define DEFINE_CATEGORY(category, category_name, items, a) \
536- category_name,
537-#include "categories.def"
538-#undef DEFINE_CATEGORY
539- }
540- };
541-
542-const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
543- {
544-#define DEFINE_CATEGORY(category, category_name, items, a) \
545- [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
546-#include "categories.def"
547-#undef DEFINE_CATEGORY
548- };
549-
550-/* An array of their lengths, for convenience. */
551-const uint8_t _nl_category_name_sizes[] attribute_hidden =
552- {
553-#define DEFINE_CATEGORY(category, category_name, items, a) \
554- [category] = sizeof (category_name) - 1,
555-#include "categories.def"
556-#undef DEFINE_CATEGORY
557- [LC_ALL] = sizeof ("LC_ALL") - 1
558- };
559-
560-
561 #ifdef NL_CURRENT_INDIRECT
562 # define WEAK_POSTLOAD(postload) weak_extern (postload)
563 #else
564--
5652.6.4
566
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 0000000000..2b889a94cf
--- /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 @@
1From 97fe7f1b23ea1f17533884b8fa7f7eb40087d558 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Tue, 5 Jan 2016 17:50:00 -0800
4Subject: [PATCH] When disabling SSE, make sure -fpmath is not set to use SSE
5 either
6
7This fixes errors when we inject sse options through CFLAGS and now
8that we have -Werror turned on by default this warning turns to become
9error on x86
10
11gcc -m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -x c /dev/null -S
12-mno-sse -mno-mmx
13
14generates warning
15/dev/null:1:0: warning: SSE instruction set disabled, using 387
16arithmetics
17
18where as
19
20gcc -m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -x c /dev/null -S
21-mno-sse -mno-mmx -mfpmath=387
22
23Generates no warnings
24
25Signed-off-by: Khem Raj <raj.khem@gmail.com>
26---
27Upstream-Status: Submitted
28
29 ChangeLog | 5 +++++
30 sysdeps/i386/Makefile | 2 +-
31 2 files changed, 6 insertions(+), 1 deletion(-)
32
33diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile
34index 168512f..70153b3 100644
35--- a/sysdeps/i386/Makefile
36+++ b/sysdeps/i386/Makefile
37@@ -89,7 +89,7 @@ ifeq ($(subdir),elf)
38 # the first 3 mm/xmm/ymm/zmm registers are used to pass vector parameters
39 # which must be preserved.
40 CFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\
41- -mno-sse -mno-mmx)
42+ -mno-sse -mno-mmx -mfpmath=387)
43
44 tests-special += $(objpfx)tst-ld-sse-use.out
45 $(objpfx)tst-ld-sse-use.out: ../sysdeps/i386/tst-ld-sse-use.sh $(objpfx)ld.so
46--
472.6.4
48
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 6b611dbde7..0000000000
--- a/meta/recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch
+++ /dev/null
@@ -1,556 +0,0 @@
1From ba069b3107f5ad200c4ab95e69cf368e2353b00a Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 00:46:50 +0000
4Subject: [PATCH 26/27] eglibc: dl_debug_mask is controlled by
5 __OPTION_EGLIBC_RTLD_DEBUG
6
7use GLRO_dl_debug_mask
8
9Singed-off-by: Khem Raj <raj.khem@gmail.com>
10
11Upstream-Status: Pending
12---
13 csu/libc-start.c | 4 ++--
14 elf/dl-cache.c | 4 ++--
15 elf/dl-close.c | 6 +++---
16 elf/dl-conflict.c | 2 +-
17 elf/dl-deps.c | 6 +++---
18 elf/dl-error.c | 2 +-
19 elf/dl-fini.c | 4 ++--
20 elf/dl-init.c | 4 ++--
21 elf/dl-load.c | 16 ++++++++--------
22 elf/dl-lookup.c | 14 +++++++-------
23 elf/dl-object.c | 2 +-
24 elf/dl-open.c | 10 +++++-----
25 elf/dl-reloc.c | 2 +-
26 elf/dl-version.c | 2 +-
27 elf/get-dynamic-info.h | 2 +-
28 elf/rtld.c | 22 +++++++++++-----------
29 16 files changed, 51 insertions(+), 51 deletions(-)
30
31diff --git a/csu/libc-start.c b/csu/libc-start.c
32index 0afa7c0..2151fb6 100644
33--- a/csu/libc-start.c
34+++ b/csu/libc-start.c
35@@ -238,7 +238,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
36
37 /* Call the initializer of the program, if any. */
38 #ifdef SHARED
39- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
40+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
41 GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]);
42 #endif
43 if (init)
44@@ -261,7 +261,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
45 #endif
46
47 #ifdef SHARED
48- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
49+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
50 GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
51 #endif
52
53diff --git a/elf/dl-cache.c b/elf/dl-cache.c
54index 862f1d8..dab9c51 100644
55--- a/elf/dl-cache.c
56+++ b/elf/dl-cache.c
57@@ -194,7 +194,7 @@ _dl_load_cache_lookup (const char *name)
58 const char *best;
59
60 /* Print a message if the loading of libs is traced. */
61- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
62+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
63 _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE);
64
65 if (cache == NULL)
66@@ -292,7 +292,7 @@ _dl_load_cache_lookup (const char *name)
67 }
68
69 /* Print our result if wanted. */
70- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)
71+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0)
72 && best != NULL)
73 _dl_debug_printf (" trying file=%s\n", best);
74
75diff --git a/elf/dl-close.c b/elf/dl-close.c
76index c897247..b1b4bd5 100644
77--- a/elf/dl-close.c
78+++ b/elf/dl-close.c
79@@ -125,7 +125,7 @@ _dl_close_worker (struct link_map *map, bool force)
80 dl_close_state = rerun;
81
82 /* There are still references to this object. Do nothing more. */
83- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
84+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
85 _dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n",
86 map->l_name, map->l_direct_opencount);
87
88@@ -269,7 +269,7 @@ _dl_close_worker (struct link_map *map, bool force)
89 if (imap->l_init_called)
90 {
91 /* When debugging print a message first. */
92- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
93+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS,
94 0))
95 _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
96 imap->l_name, nsid);
97@@ -711,7 +711,7 @@ _dl_close_worker (struct link_map *map, bool force)
98 free (imap->l_reldeps);
99
100 /* Print debugging message. */
101- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
102+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
103 _dl_debug_printf ("\nfile=%s [%lu]; destroying link map\n",
104 imap->l_name, imap->l_ns);
105
106diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
107index 47a946e..e6a3f21 100644
108--- a/elf/dl-conflict.c
109+++ b/elf/dl-conflict.c
110@@ -32,7 +32,7 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
111 ElfW(Rela) *conflictend)
112 {
113 #if ! ELF_MACHINE_NO_RELA
114- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
115+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC))
116 _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
117
118 {
119diff --git a/elf/dl-deps.c b/elf/dl-deps.c
120index eee146a..1a4b004 100644
121--- a/elf/dl-deps.c
122+++ b/elf/dl-deps.c
123@@ -127,7 +127,7 @@ empty dynamic string token substitution")); \
124 else \
125 { \
126 /* This is for DT_AUXILIARY. */ \
127- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) \
128+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) \
129 _dl_debug_printf (N_("\
130 cannot load auxiliary `%s' because of empty dynamic string token " \
131 "substitution\n"), __str); \
132@@ -303,7 +303,7 @@ _dl_map_object_deps (struct link_map *map,
133 args.name = name;
134
135 /* Say that we are about to load an auxiliary library. */
136- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS,
137+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS,
138 0))
139 _dl_debug_printf ("load auxiliary object=%s"
140 " requested by file=%s\n",
141@@ -520,7 +520,7 @@ _dl_map_object_deps (struct link_map *map,
142 runp->map->l_reserved = 0;
143 }
144
145- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
146+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_PRELINK, 0) != 0
147 && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
148 {
149 /* If we are to compute conflicts, we have to build local scope
150diff --git a/elf/dl-error.c b/elf/dl-error.c
151index 0fc3fd8..ea82f4d 100644
152--- a/elf/dl-error.c
153+++ b/elf/dl-error.c
154@@ -139,7 +139,7 @@ internal_function
155 _dl_signal_cerror (int errcode, const char *objname, const char *occation,
156 const char *errstring)
157 {
158- if (__builtin_expect (GLRO(dl_debug_mask)
159+ if (__builtin_expect (GLRO_dl_debug_mask
160 & ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0))
161 _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation,
162 errstring, receiver ? "continued" : "fatal");
163diff --git a/elf/dl-fini.c b/elf/dl-fini.c
164index 6cfe651..f59f7fe 100644
165--- a/elf/dl-fini.c
166+++ b/elf/dl-fini.c
167@@ -234,7 +234,7 @@ _dl_fini (void)
168 || l->l_info[DT_FINI] != NULL)
169 {
170 /* When debugging print a message first. */
171- if (__builtin_expect (GLRO(dl_debug_mask)
172+ if (__builtin_expect (GLRO_dl_debug_mask
173 & DL_DEBUG_IMPCALLS, 0))
174 _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
175 DSO_FILENAME (l->l_name),
176@@ -286,7 +286,7 @@ _dl_fini (void)
177 goto again;
178 }
179
180- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
181+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS))
182 _dl_debug_printf ("\nruntime linker statistics:\n"
183 " final number of relocations: %lu\n"
184 "final number of relocations from cache: %lu\n",
185diff --git a/elf/dl-init.c b/elf/dl-init.c
186index 2f85731..e46e8b6 100644
187--- a/elf/dl-init.c
188+++ b/elf/dl-init.c
189@@ -46,7 +46,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
190 return;
191
192 /* Print a debug message if wanted. */
193- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
194+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
195 _dl_debug_printf ("\ncalling init: %s\n\n",
196 DSO_FILENAME (l->l_name));
197
198@@ -96,7 +96,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
199 ElfW(Addr) *addrs;
200 unsigned int cnt;
201
202- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
203+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
204 _dl_debug_printf ("\ncalling preinit: %s\n\n",
205 DSO_FILENAME (main_map->l_name));
206
207diff --git a/elf/dl-load.c b/elf/dl-load.c
208index f664f50..8c28744 100644
209--- a/elf/dl-load.c
210+++ b/elf/dl-load.c
211@@ -943,7 +943,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
212 }
213
214 /* Print debugging message. */
215- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
216+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
217 _dl_debug_printf ("file=%s [%lu]; generating link map\n", name, nsid);
218
219 /* This is the ELF header. We read it in `open_verify'. */
220@@ -1347,7 +1347,7 @@ cannot enable executable stack as shared object requires");
221
222 l->l_entry += l->l_addr;
223
224- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
225+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
226 _dl_debug_printf ("\
227 dynamic: 0x%0*lx base: 0x%0*lx size: 0x%0*Zx\n\
228 entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u\n\n",
229@@ -1789,7 +1789,7 @@ open_path (const char *name, size_t namelen, int mode,
230
231 /* If we are debugging the search for libraries print the path
232 now if it hasn't happened now. */
233- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)
234+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)
235 && current_what != this_dir->what)
236 {
237 current_what = this_dir->what;
238@@ -1810,7 +1810,7 @@ open_path (const char *name, size_t namelen, int mode,
239 - buf);
240
241 /* Print name we try if this is wanted. */
242- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
243+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
244 _dl_debug_printf (" trying file=%s\n", buf);
245
246 fd = open_verify (buf, fbp, loader, whatcode, mode,
247@@ -1955,7 +1955,7 @@ _dl_map_object (struct link_map *loader, const char *name,
248 }
249
250 /* Display information if we are debugging. */
251- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)
252+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)
253 && loader != NULL)
254 _dl_debug_printf ((mode & __RTLD_CALLMAP) == 0
255 ? "\nfile=%s [%lu]; needed by %s [%lu]\n"
256@@ -1997,7 +1997,7 @@ _dl_map_object (struct link_map *loader, const char *name,
257
258 size_t namelen = strlen (name) + 1;
259
260- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
261+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
262 _dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid);
263
264 fd = -1;
265@@ -2119,7 +2119,7 @@ _dl_map_object (struct link_map *loader, const char *name,
266 #endif
267
268 /* Add another newline when we are tracing the library loading. */
269- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
270+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
271 _dl_debug_printf ("\n");
272 }
273 else
274@@ -2152,7 +2152,7 @@ _dl_map_object (struct link_map *loader, const char *name,
275 if (__glibc_unlikely (fd == -1))
276 {
277 if (trace_mode
278- && __glibc_likely ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) == 0))
279+ && __glibc_likely ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK) == 0))
280 {
281 /* We haven't found an appropriate library. But since we
282 are only interested in the list of libraries this isn't
283diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
284index 11cb44b..588c3e4 100644
285--- a/elf/dl-lookup.c
286+++ b/elf/dl-lookup.c
287@@ -302,7 +302,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash,
288 hash table. */
289 if (__glibc_unlikely (tab->size))
290 {
291- assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
292+ assert (GLRO_dl_debug_mask & DL_DEBUG_PRELINK);
293 goto success;
294 }
295 #endif
296@@ -378,7 +378,7 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
297 continue;
298
299 /* Print some debugging info if wanted. */
300- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS))
301+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SYMBOLS))
302 _dl_debug_printf ("symbol=%s; lookup in file=%s [%lu]\n",
303 undef_name, DSO_FILENAME (map->l_name),
304 map->l_ns);
305@@ -755,7 +755,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
306 }
307
308 /* Display information if we are debugging. */
309- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
310+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
311 _dl_debug_printf ("\
312 \nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
313 DSO_FILENAME (map->l_name),
314@@ -859,7 +859,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
315 {
316 if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
317 && skip_map == NULL
318- && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED))
319+ && !(GLRO_dl_debug_mask & DL_DEBUG_UNUSED))
320 {
321 /* We could find no value for a strong reference. */
322 const char *reference_name = undef_map ? undef_map->l_name : "";
323@@ -935,7 +935,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
324 if (__glibc_unlikely (current_value.m->l_used == 0))
325 current_value.m->l_used = 1;
326
327- if (__glibc_unlikely (GLRO(dl_debug_mask)
328+ if (__glibc_unlikely (GLRO_dl_debug_mask
329 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK)))
330 _dl_debug_bindings (undef_name, undef_map, ref,
331 &current_value, version, type_class, protected);
332@@ -1000,7 +1000,7 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
333 {
334 const char *reference_name = undef_map->l_name;
335
336- if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
337+ if (GLRO_dl_debug_mask & DL_DEBUG_BINDINGS)
338 {
339 _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
340 DSO_FILENAME (reference_name),
341@@ -1014,7 +1014,7 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
342 _dl_debug_printf_c ("\n");
343 }
344 #ifdef SHARED
345- if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
346+ if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
347 {
348 int conflict = 0;
349 struct sym_val val = { NULL, NULL };
350diff --git a/elf/dl-object.c b/elf/dl-object.c
351index 1d58bbc..938a257 100644
352--- a/elf/dl-object.c
353+++ b/elf/dl-object.c
354@@ -98,7 +98,7 @@ _dl_new_object (char *realname, const char *libname, int type,
355 new->l_type = type;
356 /* If we set the bit now since we know it is never used we avoid
357 dirtying the cache line later. */
358- if ((GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) == 0)
359+ if ((GLRO_dl_debug_mask & DL_DEBUG_UNUSED) == 0)
360 new->l_used = 1;
361 new->l_loader = loader;
362 #if NO_TLS_OFFSET != 0
363diff --git a/elf/dl-open.c b/elf/dl-open.c
364index 2db1c02..1288604 100644
365--- a/elf/dl-open.c
366+++ b/elf/dl-open.c
367@@ -147,7 +147,7 @@ add_to_global (struct link_map *new)
368 ns->_ns_main_searchlist->r_list[new_nlist++] = map;
369
370 /* We modify the global scope. Report this. */
371- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
372+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
373 _dl_debug_printf ("\nadd %s [%lu] to global scope\n",
374 map->l_name, map->l_ns);
375 }
376@@ -251,7 +251,7 @@ dl_open_worker (void *a)
377 if (__glibc_unlikely (new->l_searchlist.r_list != NULL))
378 {
379 /* Let the user know about the opencount. */
380- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
381+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
382 _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
383 new->l_name, new->l_ns, new->l_direct_opencount);
384
385@@ -302,7 +302,7 @@ dl_open_worker (void *a)
386 LIBC_PROBE (map_complete, 3, args->nsid, r, new);
387
388 /* Print scope information. */
389- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
390+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
391 _dl_show_scope (new, 0);
392
393 /* Only do lazy relocation if `LD_BIND_NOW' is not set. */
394@@ -519,7 +519,7 @@ dl_open_worker (void *a)
395 }
396
397 /* Print scope information. */
398- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
399+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
400 _dl_show_scope (imap, from_scope);
401 }
402
403@@ -577,7 +577,7 @@ TLS generation counter wrapped! Please report this."));
404 #endif
405
406 /* Let the user know about the opencount. */
407- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
408+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
409 _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
410 new->l_name, new->l_ns, new->l_direct_opencount);
411 }
412diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
413index 61252d7..4c83815 100644
414--- a/elf/dl-reloc.c
415+++ b/elf/dl-reloc.c
416@@ -178,7 +178,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
417 && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0))
418 lazy = 0;
419
420- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
421+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC))
422 _dl_debug_printf ("\nrelocation processing: %s%s\n",
423 DSO_FILENAME (l->l_name), lazy ? " (lazy)" : "");
424
425diff --git a/elf/dl-version.c b/elf/dl-version.c
426index f6e5cd9..320628c 100644
427--- a/elf/dl-version.c
428+++ b/elf/dl-version.c
429@@ -82,7 +82,7 @@ match_symbol (const char *name, Lmid_t ns, ElfW(Word) hash, const char *string,
430 int result = 0;
431
432 /* Display information about what we are doing while debugging. */
433- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS))
434+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_VERSIONS))
435 _dl_debug_printf ("\
436 checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
437 string, DSO_FILENAME (map->l_name),
438diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
439index dc8359d..7774fda 100644
440--- a/elf/get-dynamic-info.h
441+++ b/elf/get-dynamic-info.h
442@@ -166,7 +166,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
443 them. Therefore to avoid breaking existing applications the
444 best we can do is add a warning during debugging with the
445 intent of notifying the user of the problem. */
446- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
447+ if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0)
448 && l->l_flags_1 & ~DT_1_SUPPORTED_MASK)
449 _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.\n",
450 l->l_flags_1 & ~DT_1_SUPPORTED_MASK);
451diff --git a/elf/rtld.c b/elf/rtld.c
452index fc3a2db..59c4637 100644
453--- a/elf/rtld.c
454+++ b/elf/rtld.c
455@@ -323,7 +323,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
456 }
457 #endif
458
459- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
460+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS))
461 {
462 #ifndef HP_TIMING_NONAVAIL
463 print_statistics (&rtld_total_time);
464@@ -1701,7 +1701,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
465 after relocation. */
466 struct link_map *l;
467
468- if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
469+ if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
470 {
471 struct r_scope_elem *scope = &main_map->l_searchlist;
472
473@@ -1731,7 +1731,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
474 _dl_printf ("\n");
475 }
476 }
477- else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
478+ else if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED)
479 {
480 /* Look through the dependencies of the main executable
481 and determine which of them is not actually
482@@ -1839,7 +1839,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
483 }
484 }
485
486- if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
487+ if ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
488 && rtld_multiple_ref)
489 {
490 /* Mark the link map as not yet relocated again. */
491@@ -1972,7 +1972,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
492 if (r_list == r_listend && liblist == liblistend)
493 prelinked = true;
494
495- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
496+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
497 _dl_debug_printf ("\nprelink checking: %s\n",
498 prelinked ? "ok" : "failed");
499 }
500@@ -1990,7 +1990,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
501 GLRO(dl_init_all_dirs) = GL(dl_all_dirs);
502
503 /* Print scope information. */
504- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
505+ if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
506 {
507 _dl_debug_printf ("\nInitial object scopes\n");
508
509@@ -2265,7 +2265,7 @@ process_dl_debug (const char *dl_debug)
510 if (debopts[cnt].len == len
511 && memcmp (dl_debug, debopts[cnt].name, len) == 0)
512 {
513- GLRO(dl_debug_mask) |= debopts[cnt].mask;
514+ GLRO_dl_debug_mask |= debopts[cnt].mask;
515 any_debug = 1;
516 break;
517 }
518@@ -2286,7 +2286,7 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
519 ++dl_debug;
520 }
521
522- if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
523+ if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED)
524 {
525 /* In order to get an accurate picture of whether a particular
526 DT_NEEDED entry is actually used we have to process both
527@@ -2294,7 +2294,7 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
528 GLRO(dl_lazy) = 0;
529 }
530
531- if (GLRO(dl_debug_mask) & DL_DEBUG_HELP)
532+ if (GLRO_dl_debug_mask & DL_DEBUG_HELP)
533 {
534 size_t cnt;
535
536@@ -2499,7 +2499,7 @@ process_envvars (enum mode *modep)
537 mode = trace;
538 GLRO(dl_verbose) = 1;
539 #if __OPTION_EGLIBC_RTLD_DEBUG
540- GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
541+ GLRO_dl_debug_mask |= DL_DEBUG_PRELINK;
542 #endif
543 GLRO(dl_trace_prelink) = &envline[17];
544 }
545@@ -2548,7 +2548,7 @@ process_envvars (enum mode *modep)
546 {
547 unsetenv ("MALLOC_CHECK_");
548 #if __OPTION_EGLIBC_RTLD_DEBUG
549- GLRO(dl_debug_mask) = 0;
550+ GLRO_dl_debug_mask = 0;
551 #endif
552 }
553
554--
5552.1.4
556
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 4106167df5..0000000000
--- a/meta/recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch
+++ /dev/null
@@ -1,145 +0,0 @@
1From e98779aa56fae0346dff2d0b72acadd0eaf01891 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 27 May 2015 16:10:50 -0700
4Subject: [PATCH 27/27] eglibc-use-option-groups: Conditionally exclude c++
5 tests
6
7 Some test programs written in c++ are still included in spite of
8 "libc-cxx-tests" being omitted from DISTRO_FEATURES_LIBC.
9 All .cc programs are compiled with g++.
10 g++ automatically specifies linking against the C++ library.
11 This patch conditionally excludes the following tests as well:
12
13 bug-atexit3-lib.cc
14 tst-cancel24.cc
15 tst-cancel24-static.cc
16 tst-unique3lib.cc
17 tst-unique3lib2.cc
18 tst-unique4lib.cc
19 tst-unique3.cc
20 tst-unique4.cc
21
22 Tested with DISTRO_FEATURES_LIBC_remove = " libc-cxx-tests"
23
24 [YOCTO #7003]
25
26Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
27Signed-off-by: Khem Raj <raj.khem@gmail.com>
28---
29 dlfcn/Makefile | 8 ++++++--
30 elf/Makefile | 19 ++++++++++++++-----
31 nptl/Makefile | 12 ++++++++++--
32 3 files changed, 30 insertions(+), 9 deletions(-)
33
34diff --git a/dlfcn/Makefile b/dlfcn/Makefile
35index 3827607..920bd58 100644
36--- a/dlfcn/Makefile
37+++ b/dlfcn/Makefile
38@@ -39,16 +39,20 @@ ifeq (yes,$(build-shared))
39 tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
40 bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
41 tstatexit bug-dl-leaf tst-rec-dlopen
42-endif
43-
44 tests-$(OPTION_EGLIBC_CXX_TESTS) += bug-atexit3
45
46+endif
47+
48 modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
49 defaultmod2 errmsg1mod modatexit modcxaatexit \
50 bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \
51 bug-atexit2-lib bug-dl-leaf-lib \
52 bug-dl-leaf-lib-cb moddummy1 moddummy2
53
54+ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
55+modules-names += bug-atexit3-lib
56+endif
57+
58 failtestmod.so-no-z-defs = yes
59 glreflib2.so-no-z-defs = yes
60 errmsg1mod.so-no-z-defs = yes
61diff --git a/elf/Makefile b/elf/Makefile
62index 71a18a1..26fe3c5 100644
63--- a/elf/Makefile
64+++ b/elf/Makefile
65@@ -17,6 +17,8 @@
66
67 # Makefile for elf subdirectory of GNU C Library.
68
69+include ../option-groups.mak
70+
71 subdir := elf
72
73 include ../Makeconfig
74@@ -145,12 +147,15 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
75 unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
76 tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
77 tst-stackguard1 tst-addr1 tst-thrlock \
78- tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \
79- tst-nodelete) \
80+ tst-unique1 tst-unique2 \
81 tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
82 tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
83 tst-nodelete2
84 # reldep9
85+ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
86+tests += $(if $(CXX),tst-unique3 tst-unique4 tst-nodelete)
87+endif
88+
89 ifeq ($(build-hardcoded-path-in-tests),yes)
90 tests += tst-dlopen-aout
91 LDFLAGS-tst-dlopen-aout = $(no-pie-ldflag)
92@@ -209,9 +214,6 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
93 tst-unique1mod1 tst-unique1mod2 \
94 tst-unique2mod1 tst-unique2mod2 \
95 tst-auditmod9a tst-auditmod9b \
96- $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \
97- tst-nodelete-uniquemod tst-nodelete-rtldmod \
98- tst-nodelete-zmod) \
99 tst-initordera1 tst-initorderb1 \
100 tst-initordera2 tst-initorderb2 \
101 tst-initordera3 tst-initordera4 \
102@@ -220,6 +222,13 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
103 tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
104 tst-array5dep tst-null-argv-lib \
105 tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod
106+
107+ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
108+modules-names += $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \
109+ tst-nodelete-uniquemod tst-nodelete-rtldmod \
110+ tst-nodelete-zmod)
111+endif
112+
113 ifeq (yes,$(have-protected-data))
114 modules-names += tst-protected1moda tst-protected1modb
115 tests += tst-protected1a tst-protected1b
116diff --git a/nptl/Makefile b/nptl/Makefile
117index 596ca3c..50a708b 100644
118--- a/nptl/Makefile
119+++ b/nptl/Makefile
120@@ -390,12 +390,20 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \
121 $(common-objpfx)libc.a
122
123 tests-static += tst-locale1 tst-locale2 tst-stackguard1-static \
124- tst-cancel21-static tst-cancel24-static tst-cond8-static \
125+ tst-cancel21-static tst-cond8-static \
126 tst-mutex8-static tst-mutexpi8-static tst-sem11-static \
127 tst-sem12-static
128-tests += tst-stackguard1-static tst-cancel21-static tst-cancel24-static \
129+
130+ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
131+tests-static += tst-cancel24-static
132+endif
133+
134+tests += tst-stackguard1-static tst-cancel21-static \
135 tst-cond8-static tst-mutex8-static tst-mutexpi8-static \
136 tst-sem11-static tst-sem12-static
137+
138+tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24-static
139+
140 xtests-static += tst-setuid1-static
141
142 # These tests are linked with libc before libpthread
143--
1442.1.4
145
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 3455df1cff..0000000000
--- a/meta/recipes-core/glibc/glibc/0028-Clear-ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA-for-prel.patch
+++ /dev/null
@@ -1,84 +0,0 @@
1From cadaf1336332ca7bcdfe4a400776e5782a20e26d Mon Sep 17 00:00:00 2001
2From: "H.J. Lu" <hjl.tools@gmail.com>
3Date: Wed, 28 Oct 2015 07:49:44 -0700
4Subject: [PATCH] Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits for prelink
5
6prelink runs ld.so with the environment variable LD_TRACE_PRELINKING
7set to dump the relocation type class from _dl_debug_bindings. prelink
8has the following relocation type classes:
9
10 #define RTYPE_CLASS_VALID 8
11 #define RTYPE_CLASS_PLT (8|1)
12 #define RTYPE_CLASS_COPY (8|2)
13 #define RTYPE_CLASS_TLS (8|4)
14
15where ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA has a conflict with
16RTYPE_CLASS_TLS.
17
18Since prelink only uses ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
19bits, we should clear the other bits when the DL_DEBUG_PRELINK bit is
20set.
21
22 [BZ #19178]
23 * elf/dl-lookup.c (RTYPE_CLASS_VALID): New.
24 (RTYPE_CLASS_PLT): Likewise.
25 (RTYPE_CLASS_COPY): Likewise.
26 (RTYPE_CLASS_TLS): Likewise.
27 (_dl_debug_bindings): Use RTYPE_CLASS_TLS and RTYPE_CLASS_VALID
28 to set relocation type class for DL_DEBUG_PRELINK. Keep only
29 ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY bits for
30 DL_DEBUG_PRELINK.
31
32Upstream-Status: submitted (https://sourceware.org/bugzilla/show_bug.cgi?id=19178)
33
34Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
35---
36 elf/dl-lookup.c | 21 +++++++++++++++++++--
37 1 file changed, 19 insertions(+), 2 deletions(-)
38
39diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
40index 581fb20..6ae6cc3 100644
41--- a/elf/dl-lookup.c
42+++ b/elf/dl-lookup.c
43@@ -1016,6 +1016,18 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
44 #ifdef SHARED
45 if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
46 {
47+/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with
48+ LD_TRACE_PRELINKING. */
49+#define RTYPE_CLASS_VALID 8
50+#define RTYPE_CLASS_PLT (8|1)
51+#define RTYPE_CLASS_COPY (8|2)
52+#define RTYPE_CLASS_TLS (8|4)
53+#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1
54+# error ELF_RTYPE_CLASS_PLT must be 0 or 1!
55+#endif
56+#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2
57+# error ELF_RTYPE_CLASS_COPY must be 0 or 2!
58+#endif
59 int conflict = 0;
60 struct sym_val val = { NULL, NULL };
61
62@@ -1071,12 +1083,17 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
63
64 if (value->s)
65 {
66+ /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
67+ bits since since prelink only uses them. */
68+ type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY;
69 if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
70 == STT_TLS))
71- type_class = 4;
72+ /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS. */
73+ type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID;
74 else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
75 == STT_GNU_IFUNC))
76- type_class |= 8;
77+ /* Set the RTYPE_CLASS_VALID bit. */
78+ type_class |= RTYPE_CLASS_VALID;
79 }
80
81 if (conflict
82--
831.9.3
84
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 390bb3034d..0000000000
--- a/meta/recipes-core/glibc/glibc/0029-fix-getmntent-empty-lines.patch
+++ /dev/null
@@ -1,40 +0,0 @@
1From b0e805fa0d6fea33745952df7b7f5442ca4c374f Mon Sep 17 00:00:00 2001
2From: Mike Frysinger <vapier@gentoo.org>
3Date: Fri, 28 Aug 2015 17:08:49 -0400
4Subject: [PATCH] getmntent: fix memory corruption w/blank lines [BZ #18887]
5
6The fix for BZ #17273 introduced a single byte of memory corruption when
7the line is entirely blank. It would walk back past the start of the
8buffer if the heap happened to be 0x20 or 0x09 and then write a NUL byte.
9 buffer = '\n';
10 end_ptr = buffer;
11 while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')
12 end_ptr--;
13 *end_ptr = '\0';
14
15Fix that and rework the tests. Adding the testcase for BZ #17273 to the
16existing \040 parser does not really make sense as it's unrelated, and
17leads to confusing behavior: it implicitly relies on the new entry being
18longer than the previous entry (since it just rewinds the FILE*). Split
19it out into its own dedicated testcase instead.
20
21The original patch is at link https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=b0e805fa0d6fea33745952df7b7f5442ca4c374f.
22Only code to mntent_r.c is kept in this patch, Change log, NEWS, Makefile, and test cases are excluded.
23
24Upstream-Status: Backport (upstreamed to 2.23)
25Signed-off-by: Baoshan Pang <baoshan.pang@windriver.com>
26
27diff --git a/misc/mntent_r.c b/misc/mntent_r.c
28index 6159873..19af8a8 100644
29--- a/misc/mntent_r.c
30+++ b/misc/mntent_r.c
31@@ -136,7 +136,8 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
32 end_ptr = strchr (buffer, '\n');
33 if (end_ptr != NULL) /* chop newline */
34 {
35- while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')
36+ while (end_ptr != buffer
37+ && (end_ptr[-1] == ' ' || end_ptr[-1] == '\t'))
38 end_ptr--;
39 *end_ptr = '\0';
40 }
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 4e539f8497..0000000000
--- a/meta/recipes-core/glibc/glibc/CVE-2015-7547.patch
+++ /dev/null
@@ -1,642 +0,0 @@
1From e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca Mon Sep 17 00:00:00 2001
2From: Carlos O'Donell <carlos@systemhalted.org>
3Date: Tue, 16 Feb 2016 21:26:37 -0500
4Subject: [PATCH] CVE-2015-7547: getaddrinfo() stack-based buffer overflow (Bug
5 18665).
6
7* A stack-based buffer overflow was found in libresolv when invoked from
8 libnss_dns, allowing specially crafted DNS responses to seize control
9 of execution flow in the DNS client. The buffer overflow occurs in
10 the functions send_dg (send datagram) and send_vc (send TCP) for the
11 NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC
12 family. The use of AF_UNSPEC triggers the low-level resolver code to
13 send out two parallel queries for A and AAAA. A mismanagement of the
14 buffers used for those queries could result in the response of a query
15 writing beyond the alloca allocated buffer created by
16 _nss_dns_gethostbyname4_r. Buffer management is simplified to remove
17 the overflow. Thanks to the Google Security Team and Red Hat for
18 reporting the security impact of this issue, and Robert Holiday of
19 Ciena for reporting the related bug 18665. (CVE-2015-7547)
20
21See also:
22https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html
23https://sourceware.org/ml/libc-alpha/2016-02/msg00418.html
24
25Upstream-Status: Backport
26CVE: CVE-2015-7547
27
28https://sourceware.org/git/?p=glibc.git;a=commit;h=e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca
29minor tweeking to apply to Changelog and res_send.c
30
31Signed-off-by: Armin Kuster <akuster@mvista.com>
32
33---
34 ChangeLog | 17 ++-
35 NEWS | 14 +++
36 resolv/nss_dns/dns-host.c | 111 +++++++++++++++++++-
37 resolv/res_query.c | 3 +
38 resolv/res_send.c | 260 +++++++++++++++++++++++++++++++++++-----------
39 5 files changed, 339 insertions(+), 66 deletions(-)
40
41Index: git/NEWS
42===================================================================
43--- git.orig/NEWS
44+++ git/NEWS
45@@ -105,6 +105,20 @@ Security related changes:
46 depending on the length of the string passed as an argument to the
47 functions. Reported by Joseph Myers.
48
49+* A stack-based buffer overflow was found in libresolv when invoked from
50+ libnss_dns, allowing specially crafted DNS responses to seize control
51+ of execution flow in the DNS client. The buffer overflow occurs in
52+ the functions send_dg (send datagram) and send_vc (send TCP) for the
53+ NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC
54+ family. The use of AF_UNSPEC triggers the low-level resolver code to
55+ send out two parallel queries for A and AAAA. A mismanagement of the
56+ buffers used for those queries could result in the response of a query
57+ writing beyond the alloca allocated buffer created by
58+ _nss_dns_gethostbyname4_r. Buffer management is simplified to remove
59+ the overflow. Thanks to the Google Security Team and Red Hat for
60+ reporting the security impact of this issue, and Robert Holiday of
61+ Ciena for reporting the related bug 18665. (CVE-2015-7547)
62+
63 * The following bugs are resolved with this release:
64
65 6652, 10672, 12674, 12847, 12926, 13862, 14132, 14138, 14171, 14498,
66Index: git/resolv/nss_dns/dns-host.c
67===================================================================
68--- git.orig/resolv/nss_dns/dns-host.c
69+++ git/resolv/nss_dns/dns-host.c
70@@ -1031,7 +1031,10 @@ gaih_getanswer_slice (const querybuf *an
71 int h_namelen = 0;
72
73 if (ancount == 0)
74- return NSS_STATUS_NOTFOUND;
75+ {
76+ *h_errnop = HOST_NOT_FOUND;
77+ return NSS_STATUS_NOTFOUND;
78+ }
79
80 while (ancount-- > 0 && cp < end_of_message && had_error == 0)
81 {
82@@ -1208,7 +1211,14 @@ gaih_getanswer_slice (const querybuf *an
83 /* Special case here: if the resolver sent a result but it only
84 contains a CNAME while we are looking for a T_A or T_AAAA record,
85 we fail with NOTFOUND instead of TRYAGAIN. */
86- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
87+ if (canon != NULL)
88+ {
89+ *h_errnop = HOST_NOT_FOUND;
90+ return NSS_STATUS_NOTFOUND;
91+ }
92+
93+ *h_errnop = NETDB_INTERNAL;
94+ return NSS_STATUS_TRYAGAIN;
95 }
96
97
98@@ -1222,11 +1232,101 @@ gaih_getanswer (const querybuf *answer1,
99
100 enum nss_status status = NSS_STATUS_NOTFOUND;
101
102+ /* Combining the NSS status of two distinct queries requires some
103+ compromise and attention to symmetry (A or AAAA queries can be
104+ returned in any order). What follows is a breakdown of how this
105+ code is expected to work and why. We discuss only SUCCESS,
106+ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
107+ that apply (though RETURN and MERGE exist). We make a distinction
108+ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
109+ A recoverable TRYAGAIN is almost always due to buffer size issues
110+ and returns ERANGE in errno and the caller is expected to retry
111+ with a larger buffer.
112+
113+ Lastly, you may be tempted to make significant changes to the
114+ conditions in this code to bring about symmetry between responses.
115+ Please don't change anything without due consideration for
116+ expected application behaviour. Some of the synthesized responses
117+ aren't very well thought out and sometimes appear to imply that
118+ IPv4 responses are always answer 1, and IPv6 responses are always
119+ answer 2, but that's not true (see the implementation of send_dg
120+ and send_vc to see response can arrive in any order, particularly
121+ for UDP). However, we expect it holds roughly enough of the time
122+ that this code works, but certainly needs to be fixed to make this
123+ a more robust implementation.
124+
125+ ----------------------------------------------
126+ | Answer 1 Status / | Synthesized | Reason |
127+ | Answer 2 Status | Status | |
128+ |--------------------------------------------|
129+ | SUCCESS/SUCCESS | SUCCESS | [1] |
130+ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] |
131+ | SUCCESS/TRYAGAIN' | SUCCESS | [1] |
132+ | SUCCESS/NOTFOUND | SUCCESS | [1] |
133+ | SUCCESS/UNAVAIL | SUCCESS | [1] |
134+ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] |
135+ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] |
136+ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] |
137+ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] |
138+ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] |
139+ | TRYAGAIN'/SUCCESS | SUCCESS | [3] |
140+ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] |
141+ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] |
142+ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] |
143+ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] |
144+ | NOTFOUND/SUCCESS | SUCCESS | [3] |
145+ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] |
146+ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] |
147+ | NOTFOUND/NOTFOUND | NOTFOUND | [3] |
148+ | NOTFOUND/UNAVAIL | UNAVAIL | [3] |
149+ | UNAVAIL/SUCCESS | UNAVAIL | [4] |
150+ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] |
151+ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] |
152+ | UNAVAIL/NOTFOUND | UNAVAIL | [4] |
153+ | UNAVAIL/UNAVAIL | UNAVAIL | [4] |
154+ ----------------------------------------------
155+
156+ [1] If the first response is a success we return success.
157+ This ignores the state of the second answer and in fact
158+ incorrectly sets errno and h_errno to that of the second
159+ answer. However because the response is a success we ignore
160+ *errnop and *h_errnop (though that means you touched errno on
161+ success). We are being conservative here and returning the
162+ likely IPv4 response in the first answer as a success.
163+
164+ [2] If the first response is a recoverable TRYAGAIN we return
165+ that instead of looking at the second response. The
166+ expectation here is that we have failed to get an IPv4 response
167+ and should retry both queries.
168+
169+ [3] If the first response was not a SUCCESS and the second
170+ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
171+ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
172+ result from the second response, otherwise the first responses
173+ status is used. Again we have some odd side-effects when the
174+ second response is NOTFOUND because we overwrite *errnop and
175+ *h_errnop that means that a first answer of NOTFOUND might see
176+ its *errnop and *h_errnop values altered. Whether it matters
177+ in practice that a first response NOTFOUND has the wrong
178+ *errnop and *h_errnop is undecided.
179+
180+ [4] If the first response is UNAVAIL we return that instead of
181+ looking at the second response. The expectation here is that
182+ it will have failed similarly e.g. configuration failure.
183+
184+ [5] Testing this code is complicated by the fact that truncated
185+ second response buffers might be returned as SUCCESS if the
186+ first answer is a SUCCESS. To fix this we add symmetry to
187+ TRYAGAIN with the second response. If the second response
188+ is a recoverable error we now return TRYAGIN even if the first
189+ response was SUCCESS. */
190+
191 if (anslen1 > 0)
192 status = gaih_getanswer_slice(answer1, anslen1, qname,
193 &pat, &buffer, &buflen,
194 errnop, h_errnop, ttlp,
195 &first);
196+
197 if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
198 || (status == NSS_STATUS_TRYAGAIN
199 /* We want to look at the second answer in case of an
200@@ -1242,8 +1342,15 @@ gaih_getanswer (const querybuf *answer1,
201 &pat, &buffer, &buflen,
202 errnop, h_errnop, ttlp,
203 &first);
204+ /* Use the second response status in some cases. */
205 if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
206 status = status2;
207+ /* Do not return a truncated second response (unless it was
208+ unavoidable e.g. unrecoverable TRYAGAIN). */
209+ if (status == NSS_STATUS_SUCCESS
210+ && (status2 == NSS_STATUS_TRYAGAIN
211+ && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
212+ status = NSS_STATUS_TRYAGAIN;
213 }
214
215 return status;
216Index: git/resolv/res_query.c
217===================================================================
218--- git.orig/resolv/res_query.c
219+++ git/resolv/res_query.c
220@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp,
221 {
222 free (*answerp2);
223 *answerp2 = NULL;
224+ *nanswerp2 = 0;
225 *answerp2_malloced = 0;
226 }
227 }
228@@ -447,6 +448,7 @@ __libc_res_nsearch(res_state statp,
229 {
230 free (*answerp2);
231 *answerp2 = NULL;
232+ *nanswerp2 = 0;
233 *answerp2_malloced = 0;
234 }
235
236@@ -521,6 +523,7 @@ __libc_res_nsearch(res_state statp,
237 {
238 free (*answerp2);
239 *answerp2 = NULL;
240+ *nanswerp2 = 0;
241 *answerp2_malloced = 0;
242 }
243 if (saved_herrno != -1)
244Index: git/resolv/res_send.c
245===================================================================
246--- git.orig/resolv/res_send.c
247+++ git/resolv/res_send.c
248@@ -1,3 +1,20 @@
249+/* Copyright (C) 2016 Free Software Foundation, Inc.
250+ This file is part of the GNU C Library.
251+
252+ The GNU C Library is free software; you can redistribute it and/or
253+ modify it under the terms of the GNU Lesser General Public
254+ License as published by the Free Software Foundation; either
255+ version 2.1 of the License, or (at your option) any later version.
256+
257+ The GNU C Library is distributed in the hope that it will be useful,
258+ but WITHOUT ANY WARRANTY; without even the implied warranty of
259+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
260+ Lesser General Public License for more details.
261+
262+ You should have received a copy of the GNU Lesser General Public
263+ License along with the GNU C Library; if not, see
264+ <http://www.gnu.org/licenses/>. */
265+
266 /*
267 * Copyright (c) 1985, 1989, 1993
268 * The Regents of the University of California. All rights reserved.
269@@ -363,6 +380,8 @@ __libc_res_nsend(res_state statp, const
270 #ifdef USE_HOOKS
271 if (__glibc_unlikely (statp->qhook || statp->rhook)) {
272 if (anssiz < MAXPACKET && ansp) {
273+ /* Always allocate MAXPACKET, callers expect
274+ this specific size. */
275 u_char *buf = malloc (MAXPACKET);
276 if (buf == NULL)
277 return (-1);
278@@ -638,6 +657,77 @@ get_nsaddr (res_state statp, int n)
279 return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
280 }
281
282+/* The send_vc function is responsible for sending a DNS query over TCP
283+ to the nameserver numbered NS from the res_state STATP i.e.
284+ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
285+ IPv6 queries at the same serially on the same socket.
286+
287+ Please note that for TCP there is no way to disable sending both
288+ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
289+ and sends the queries serially and waits for the result after each
290+ sent query. This implemetnation should be corrected to honour these
291+ options.
292+
293+ Please also note that for TCP we send both queries over the same
294+ socket one after another. This technically violates best practice
295+ since the server is allowed to read the first query, respond, and
296+ then close the socket (to service another client). If the server
297+ does this, then the remaining second query in the socket data buffer
298+ will cause the server to send the client an RST which will arrive
299+ asynchronously and the client's OS will likely tear down the socket
300+ receive buffer resulting in a potentially short read and lost
301+ response data. This will force the client to retry the query again,
302+ and this process may repeat until all servers and connection resets
303+ are exhausted and then the query will fail. It's not known if this
304+ happens with any frequency in real DNS server implementations. This
305+ implementation should be corrected to use two sockets by default for
306+ parallel queries.
307+
308+ The query stored in BUF of BUFLEN length is sent first followed by
309+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
310+ serially on the same socket.
311+
312+ Answers to the query are stored firstly in *ANSP up to a max of
313+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
314+ is non-NULL (to indicate that modifying the answer buffer is allowed)
315+ then malloc is used to allocate a new response buffer and ANSCP and
316+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
317+ are needed but ANSCP is NULL, then as much of the response as
318+ possible is read into the buffer, but the results will be truncated.
319+ When truncation happens because of a small answer buffer the DNS
320+ packets header field TC will bet set to 1, indicating a truncated
321+ message and the rest of the socket data will be read and discarded.
322+
323+ Answers to the query are stored secondly in *ANSP2 up to a max of
324+ *ANSSIZP2 bytes, with the actual response length stored in
325+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
326+ is non-NULL (required for a second query) then malloc is used to
327+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
328+ size and *ANSP2_MALLOCED is set to 1.
329+
330+ The ANSP2_MALLOCED argument will eventually be removed as the
331+ change in buffer pointer can be used to detect the buffer has
332+ changed and that the caller should use free on the new buffer.
333+
334+ Note that the answers may arrive in any order from the server and
335+ therefore the first and second answer buffers may not correspond to
336+ the first and second queries.
337+
338+ It is not supported to call this function with a non-NULL ANSP2
339+ but a NULL ANSCP. Put another way, you can call send_vc with a
340+ single unmodifiable buffer or two modifiable buffers, but no other
341+ combination is supported.
342+
343+ It is the caller's responsibility to free the malloc allocated
344+ buffers by detecting that the pointers have changed from their
345+ original values i.e. *ANSCP or *ANSP2 has changed.
346+
347+ If errors are encountered then *TERRNO is set to an appropriate
348+ errno value and a zero result is returned for a recoverable error,
349+ and a less-than zero result is returned for a non-recoverable error.
350+
351+ If no errors are encountered then *TERRNO is left unmodified and
352+ a the length of the first response in bytes is returned. */
353 static int
354 send_vc(res_state statp,
355 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
356@@ -647,11 +737,7 @@ send_vc(res_state statp,
357 {
358 const HEADER *hp = (HEADER *) buf;
359 const HEADER *hp2 = (HEADER *) buf2;
360- u_char *ans = *ansp;
361- int orig_anssizp = *anssizp;
362- // XXX REMOVE
363- // int anssiz = *anssizp;
364- HEADER *anhp = (HEADER *) ans;
365+ HEADER *anhp = (HEADER *) *ansp;
366 struct sockaddr *nsap = get_nsaddr (statp, ns);
367 int truncating, connreset, n;
368 /* On some architectures compiler might emit a warning indicating
369@@ -743,6 +829,8 @@ send_vc(res_state statp,
370 * Receive length & response
371 */
372 int recvresp1 = 0;
373+ /* Skip the second response if there is no second query.
374+ To do that we mark the second response as received. */
375 int recvresp2 = buf2 == NULL;
376 uint16_t rlen16;
377 read_len:
378@@ -779,40 +867,14 @@ send_vc(res_state statp,
379 u_char **thisansp;
380 int *thisresplenp;
381 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
382+ /* We have not received any responses
383+ yet or we only have one response to
384+ receive. */
385 thisanssizp = anssizp;
386 thisansp = anscp ?: ansp;
387 assert (anscp != NULL || ansp2 == NULL);
388 thisresplenp = &resplen;
389 } else {
390- if (*anssizp != MAXPACKET) {
391- /* No buffer allocated for the first
392- reply. We can try to use the rest
393- of the user-provided buffer. */
394-#if __GNUC_PREREQ (4, 7)
395- DIAG_PUSH_NEEDS_COMMENT;
396- DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
397-#endif
398-#if _STRING_ARCH_unaligned
399- *anssizp2 = orig_anssizp - resplen;
400- *ansp2 = *ansp + resplen;
401-#else
402- int aligned_resplen
403- = ((resplen + __alignof__ (HEADER) - 1)
404- & ~(__alignof__ (HEADER) - 1));
405- *anssizp2 = orig_anssizp - aligned_resplen;
406- *ansp2 = *ansp + aligned_resplen;
407-#endif
408-#if __GNUC_PREREQ (4, 7)
409- DIAG_POP_NEEDS_COMMENT;
410-#endif
411- } else {
412- /* The first reply did not fit into the
413- user-provided buffer. Maybe the second
414- answer will. */
415- *anssizp2 = orig_anssizp;
416- *ansp2 = *ansp;
417- }
418-
419 thisanssizp = anssizp2;
420 thisansp = ansp2;
421 thisresplenp = resplen2;
422@@ -820,10 +882,14 @@ send_vc(res_state statp,
423 anhp = (HEADER *) *thisansp;
424
425 *thisresplenp = rlen;
426- if (rlen > *thisanssizp) {
427- /* Yes, we test ANSCP here. If we have two buffers
428- both will be allocatable. */
429- if (__glibc_likely (anscp != NULL)) {
430+ /* Is the answer buffer too small? */
431+ if (*thisanssizp < rlen) {
432+ /* If the current buffer is not the the static
433+ user-supplied buffer then we can reallocate
434+ it. */
435+ if (thisansp != NULL && thisansp != ansp) {
436+ /* Always allocate MAXPACKET, callers expect
437+ this specific size. */
438 u_char *newp = malloc (MAXPACKET);
439 if (newp == NULL) {
440 *terrno = ENOMEM;
441@@ -835,6 +901,9 @@ send_vc(res_state statp,
442 if (thisansp == ansp2)
443 *ansp2_malloced = 1;
444 anhp = (HEADER *) newp;
445+ /* A uint16_t can't be larger than MAXPACKET
446+ thus it's safe to allocate MAXPACKET but
447+ read RLEN bytes instead. */
448 len = rlen;
449 } else {
450 Dprint(statp->options & RES_DEBUG,
451@@ -997,6 +1066,66 @@ reopen (res_state statp, int *terrno, in
452 return 1;
453 }
454
455+/* The send_dg function is responsible for sending a DNS query over UDP
456+ to the nameserver numbered NS from the res_state STATP i.e.
457+ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
458+ along with the ability to send the query in parallel for both stacks
459+ (default) or serially (RES_SINGLKUP). It also supports serial lookup
460+ with a close and reopen of the socket used to talk to the server
461+ (RES_SNGLKUPREOP) to work around broken name servers.
462+
463+ The query stored in BUF of BUFLEN length is sent first followed by
464+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
465+ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
466+
467+ Answers to the query are stored firstly in *ANSP up to a max of
468+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
469+ is non-NULL (to indicate that modifying the answer buffer is allowed)
470+ then malloc is used to allocate a new response buffer and ANSCP and
471+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
472+ are needed but ANSCP is NULL, then as much of the response as
473+ possible is read into the buffer, but the results will be truncated.
474+ When truncation happens because of a small answer buffer the DNS
475+ packets header field TC will bet set to 1, indicating a truncated
476+ message, while the rest of the UDP packet is discarded.
477+
478+ Answers to the query are stored secondly in *ANSP2 up to a max of
479+ *ANSSIZP2 bytes, with the actual response length stored in
480+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
481+ is non-NULL (required for a second query) then malloc is used to
482+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
483+ size and *ANSP2_MALLOCED is set to 1.
484+
485+ The ANSP2_MALLOCED argument will eventually be removed as the
486+ change in buffer pointer can be used to detect the buffer has
487+ changed and that the caller should use free on the new buffer.
488+
489+ Note that the answers may arrive in any order from the server and
490+ therefore the first and second answer buffers may not correspond to
491+ the first and second queries.
492+
493+ It is not supported to call this function with a non-NULL ANSP2
494+ but a NULL ANSCP. Put another way, you can call send_vc with a
495+ single unmodifiable buffer or two modifiable buffers, but no other
496+ combination is supported.
497+
498+ It is the caller's responsibility to free the malloc allocated
499+ buffers by detecting that the pointers have changed from their
500+ original values i.e. *ANSCP or *ANSP2 has changed.
501+
502+ If an answer is truncated because of UDP datagram DNS limits then
503+ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
504+ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
505+ if any progress was made reading a response from the nameserver and
506+ is used by the caller to distinguish between ECONNREFUSED and
507+ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
508+
509+ If errors are encountered then *TERRNO is set to an appropriate
510+ errno value and a zero result is returned for a recoverable error,
511+ and a less-than zero result is returned for a non-recoverable error.
512+
513+ If no errors are encountered then *TERRNO is left unmodified and
514+ a the length of the first response in bytes is returned. */
515 static int
516 send_dg(res_state statp,
517 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
518@@ -1006,8 +1135,6 @@ send_dg(res_state statp,
519 {
520 const HEADER *hp = (HEADER *) buf;
521 const HEADER *hp2 = (HEADER *) buf2;
522- u_char *ans = *ansp;
523- int orig_anssizp = *anssizp;
524 struct timespec now, timeout, finish;
525 struct pollfd pfd[1];
526 int ptimeout;
527@@ -1040,6 +1167,8 @@ send_dg(res_state statp,
528 int need_recompute = 0;
529 int nwritten = 0;
530 int recvresp1 = 0;
531+ /* Skip the second response if there is no second query.
532+ To do that we mark the second response as received. */
533 int recvresp2 = buf2 == NULL;
534 pfd[0].fd = EXT(statp).nssocks[ns];
535 pfd[0].events = POLLOUT;
536@@ -1203,55 +1332,56 @@ send_dg(res_state statp,
537 int *thisresplenp;
538
539 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
540+ /* We have not received any responses
541+ yet or we only have one response to
542+ receive. */
543 thisanssizp = anssizp;
544 thisansp = anscp ?: ansp;
545 assert (anscp != NULL || ansp2 == NULL);
546 thisresplenp = &resplen;
547 } else {
548- if (*anssizp != MAXPACKET) {
549- /* No buffer allocated for the first
550- reply. We can try to use the rest
551- of the user-provided buffer. */
552-#if _STRING_ARCH_unaligned
553- *anssizp2 = orig_anssizp - resplen;
554- *ansp2 = *ansp + resplen;
555-#else
556- int aligned_resplen
557- = ((resplen + __alignof__ (HEADER) - 1)
558- & ~(__alignof__ (HEADER) - 1));
559- *anssizp2 = orig_anssizp - aligned_resplen;
560- *ansp2 = *ansp + aligned_resplen;
561-#endif
562- } else {
563- /* The first reply did not fit into the
564- user-provided buffer. Maybe the second
565- answer will. */
566- *anssizp2 = orig_anssizp;
567- *ansp2 = *ansp;
568- }
569-
570 thisanssizp = anssizp2;
571 thisansp = ansp2;
572 thisresplenp = resplen2;
573 }
574
575 if (*thisanssizp < MAXPACKET
576- /* Yes, we test ANSCP here. If we have two buffers
577- both will be allocatable. */
578- && anscp
579+ /* If the current buffer is not the the static
580+ user-supplied buffer then we can reallocate
581+ it. */
582+ && (thisansp != NULL && thisansp != ansp)
583 #ifdef FIONREAD
584+ /* Is the size too small? */
585 && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
586 || *thisanssizp < *thisresplenp)
587 #endif
588 ) {
589+ /* Always allocate MAXPACKET, callers expect
590+ this specific size. */
591 u_char *newp = malloc (MAXPACKET);
592 if (newp != NULL) {
593- *anssizp = MAXPACKET;
594- *thisansp = ans = newp;
595+ *thisanssizp = MAXPACKET;
596+ *thisansp = newp;
597 if (thisansp == ansp2)
598 *ansp2_malloced = 1;
599 }
600 }
601+ /* We could end up with truncation if anscp was NULL
602+ (not allowed to change caller's buffer) and the
603+ response buffer size is too small. This isn't a
604+ reliable way to detect truncation because the ioctl
605+ may be an inaccurate report of the UDP message size.
606+ Therefore we use this only to issue debug output.
607+ To do truncation accurately with UDP we need
608+ MSG_TRUNC which is only available on Linux. We
609+ can abstract out the Linux-specific feature in the
610+ future to detect truncation. */
611+ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
612+ Dprint(statp->options & RES_DEBUG,
613+ (stdout, ";; response may be truncated (UDP)\n")
614+ );
615+ }
616+
617 HEADER *anhp = (HEADER *) *thisansp;
618 socklen_t fromlen = sizeof(struct sockaddr_in6);
619 assert (sizeof(from) <= fromlen);
620Index: git/ChangeLog
621===================================================================
622--- git.orig/ChangeLog
623+++ git/ChangeLog
624@@ -1,3 +1,18 @@
625+2016-02-15 Carlos O'Donell <carlos@redhat.com>
626+
627+ [BZ #18665]
628+ * resolv/nss_dns/dns-host.c (gaih_getanswer_slice): Always set
629+ *herrno_p.
630+ (gaih_getanswer): Document functional behviour. Return tryagain
631+ if any result is tryagain.
632+ * resolv/res_query.c (__libc_res_nsearch): Set buffer size to zero
633+ when freed.
634+ * resolv/res_send.c: Add copyright text.
635+ (__libc_res_nsend): Document that MAXPACKET is expected.
636+ (send_vc): Document. Remove buffer reuse.
637+ (send_dg): Document. Remove buffer reuse. Set *thisanssizp to set the
638+ size of the buffer. Add Dprint for truncated UDP buffer.
639+
640 2015-09-26 Paul Pluzhnikov <ppluzhnikov@google.com>
641
642 [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 8ce255f110..0000000000
--- a/meta/recipes-core/glibc/glibc/strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch
+++ /dev/null
@@ -1,323 +0,0 @@
1Upstream-Status: Backport
2
3Signed-off-by: Li Xin <lixin.fnst@cn.fujitsu.com>
4
5From https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=6c84109cfa26f35c3dfed3acb97d347361bd5849
6Author: Carlos O'Donell <carlos@systemhalted.org>
7Date: Thu Oct 8 16:34:53 2015 -0400
8
9 strcoll: Remove incorrect STRDIFF-based optimization (Bug 18589).
10
11 The optimization introduced in commit
12 f13c2a8dff2329c6692a80176262ceaaf8a6f74e, causes regressions in
13 sorting for languages that have digraphs that change sort order, like
14 cs_CZ which sorts ch between h and i.
15
16 My analysis shows the fast-forwarding optimization in STRCOLL advances
17 through a digraph while possibly stopping in the middle which results
18 in a subsequent skipping of the digraph and incorrect sorting. The
19 optimization is incorrect as implemented and because of that I'm
20 removing it for 2.23, and I will also commit this fix for 2.22 where
21 it was originally introduced.
22
23 This patch reverts the optimization, introduces a new bug-strcoll2.c
24 regression test that tests both cs_CZ.UTF-8 and da_DK.ISO-8859-1 and
25 ensures they sort one digraph each correctly. The optimization can't be
26 applied without regressing this test.
27
28 Checked on x86_64, bug-strcoll2.c fails without this patch and passes
29 after. This will also get a fix on 2.22 which has the same bug.
30
31 (cherry picked from commit 87701a58e291bd7ac3b407d10a829dac52c9c16e)
32---
33 locale/C-collate.c | 4 +-
34 locale/categories.def | 1 -
35 locale/langinfo.h | 1 -
36 locale/localeinfo.h | 7 ----
37 locale/programs/ld-collate.c | 9 -----
38 string/bug-strcoll2.c | 95 ++++++++++++++++++++++++++++++++++++++++++++
39 string/strcoll_l.c | 39 +-----------------
40 wcsmbs/wcscoll_l.c | 1 -
41 8 files changed, 98 insertions(+), 59 deletions(-)
42 create mode 100644 string/bug-strcoll2.c
43
44diff --git a/locale/C-collate.c b/locale/C-collate.c
45index d7f3c55..06dfdfa 100644
46--- a/locale/C-collate.c
47+++ b/locale/C-collate.c
48@@ -144,8 +144,6 @@ const struct __locale_data _nl_C_LC_COLLATE attribute_hidden =
49 /* _NL_COLLATE_COLLSEQWC */
50 { .string = (const char *) collseqwc },
51 /* _NL_COLLATE_CODESET */
52- { .string = _nl_C_codeset },
53- /* _NL_COLLATE_ENCODING_TYPE */
54- { .word = __cet_8bit }
55+ { .string = _nl_C_codeset }
56 }
57 };
58diff --git a/locale/categories.def b/locale/categories.def
59index 045489d..a8dda53 100644
60--- a/locale/categories.def
61+++ b/locale/categories.def
62@@ -58,7 +58,6 @@ DEFINE_CATEGORY
63 DEFINE_ELEMENT (_NL_COLLATE_COLLSEQMB, "collate-collseqmb", std, wstring)
64 DEFINE_ELEMENT (_NL_COLLATE_COLLSEQWC, "collate-collseqwc", std, wstring)
65 DEFINE_ELEMENT (_NL_COLLATE_CODESET, "collate-codeset", std, string)
66- DEFINE_ELEMENT (_NL_COLLATE_ENCODING_TYPE, "collate-encoding-type", std, word)
67 ), NO_POSTLOAD)
68
69
70diff --git a/locale/langinfo.h b/locale/langinfo.h
71index ffc5c7f..a565d9d 100644
72--- a/locale/langinfo.h
73+++ b/locale/langinfo.h
74@@ -255,7 +255,6 @@ enum
75 _NL_COLLATE_COLLSEQMB,
76 _NL_COLLATE_COLLSEQWC,
77 _NL_COLLATE_CODESET,
78- _NL_COLLATE_ENCODING_TYPE,
79 _NL_NUM_LC_COLLATE,
80
81 /* LC_CTYPE category: character classification.
82diff --git a/locale/localeinfo.h b/locale/localeinfo.h
83index a7516c0..c076d8e 100644
84--- a/locale/localeinfo.h
85+++ b/locale/localeinfo.h
86@@ -110,13 +110,6 @@ enum coll_sort_rule
87 sort_mask
88 };
89
90-/* Collation encoding type. */
91-enum collation_encoding_type
92-{
93- __cet_other,
94- __cet_8bit,
95- __cet_utf8
96-};
97
98 /* We can map the types of the entries into a few categories. */
99 enum value_type
100diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
101index 16e9039..3c88c6d 100644
102--- a/locale/programs/ld-collate.c
103+++ b/locale/programs/ld-collate.c
104@@ -32,7 +32,6 @@
105 #include "linereader.h"
106 #include "locfile.h"
107 #include "elem-hash.h"
108-#include "../localeinfo.h"
109
110 /* Uncomment the following line in the production version. */
111 /* #define NDEBUG 1 */
112@@ -2130,8 +2129,6 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
113 /* The words have to be handled specially. */
114 if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB))
115 add_locale_uint32 (&file, 0);
116- else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE))
117- add_locale_uint32 (&file, __cet_other);
118 else
119 add_locale_empty (&file);
120 }
121@@ -2495,12 +2492,6 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
122 add_locale_raw_data (&file, collate->mbseqorder, 256);
123 add_locale_collseq_table (&file, &collate->wcseqorder);
124 add_locale_string (&file, charmap->code_set_name);
125- if (strcmp (charmap->code_set_name, "UTF-8") == 0)
126- add_locale_uint32 (&file, __cet_utf8);
127- else if (charmap->mb_cur_max == 1)
128- add_locale_uint32 (&file, __cet_8bit);
129- else
130- add_locale_uint32 (&file, __cet_other);
131 write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file);
132
133 obstack_free (&weightpool, NULL);
134diff --git a/string/bug-strcoll2.c b/string/bug-strcoll2.c
135new file mode 100644
136index 0000000..950b090
137--- /dev/null
138+++ b/string/bug-strcoll2.c
139@@ -0,0 +1,95 @@
140+/* Bug 18589: sort-test.sh fails at random.
141+ * Copyright (C) 1998-2015 Free Software Foundation, Inc.
142+ * This file is part of the GNU C Library.
143+ * Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
144+ *
145+ * The GNU C Library is free software; you can redistribute it and/or
146+ * modify it under the terms of the GNU Lesser General Public
147+ * License as published by the Free Software Foundation; either
148+ * version 2.1 of the License, or (at your option) any later version.
149+ *
150+ * The GNU C Library is distributed in the hope that it will be useful,
151+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
152+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
153+ * Lesser General Public License for more details.
154+ *
155+ * You should have received a copy of the GNU Lesser General Public
156+ * License along with the GNU C Library; if not, see
157+ * <http://www.gnu.org/licenses/>. */
158+
159+#include <stdio.h>
160+#include <string.h>
161+#include <locale.h>
162+
163+/* An incorrect strcoll optimization resulted in incorrect
164+ * results from strcoll for cs_CZ and da_DK. */
165+
166+int
167+test_cs_CZ (void)
168+{
169+ const char t1[] = "config";
170+ const char t2[] = "choose";
171+ if (setlocale (LC_ALL, "cs_CZ.UTF-8") == NULL)
172+ {
173+ perror ("setlocale");
174+ return 1;
175+ }
176+ /* In Czech the digraph ch sorts after c, therefore we expect
177+ * config to sort before choose. */
178+ int a = strcoll (t1, t2);
179+ int b = strcoll (t2, t1);
180+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a);
181+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b);
182+ if (a < 0 && b > 0)
183+ {
184+ puts ("PASS: config < choose");
185+ return 0;
186+ }
187+ else
188+ {
189+ puts ("FAIL: Wrong sorting in cz_CZ.UTF-8.");
190+ return 1;
191+ }
192+}
193+
194+int
195+test_da_DK (void)
196+{
197+ const char t1[] = "AS";
198+ const char t2[] = "AA";
199+ if (setlocale (LC_ALL, "da_DK.ISO-8859-1") == NULL)
200+ {
201+ perror ("setlocale");
202+ return 1;
203+ }
204+ /* AA should be treated as the last letter of the Danish alphabet,
205+ * hence sorting after AS. */
206+ int a = strcoll (t1, t2);
207+ int b = strcoll (t2, t1);
208+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a);
209+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b);
210+ if (a < 0 && b > 0)
211+ {
212+ puts ("PASS: AS < AA");
213+ return 0;
214+ }
215+ else
216+ {
217+ puts ("FAIL: Wrong sorting in da_DK.ISO-8859-1");
218+ return 1;
219+ }
220+}
221+
222+static int
223+do_test (void)
224+{
225+ int err = 0;
226+ err |= test_cs_CZ ();
227+ err |= test_da_DK ();
228+ return err;
229+}
230+
231+#define TEST_FUNCTION do_test ()
232+#include "../test-skeleton.c"
233+
234+
235diff --git a/string/strcoll_l.c b/string/strcoll_l.c
236index b36b18c..a18b65e 100644
237--- a/string/strcoll_l.c
238+++ b/string/strcoll_l.c
239@@ -30,7 +30,6 @@
240 # define STRING_TYPE char
241 # define USTRING_TYPE unsigned char
242 # define STRCOLL __strcoll_l
243-# define STRDIFF __strdiff
244 # define STRCMP strcmp
245 # define WEIGHT_H "../locale/weight.h"
246 # define SUFFIX MB
247@@ -43,19 +42,6 @@
248 #include "../locale/localeinfo.h"
249 #include WEIGHT_H
250
251-#define MASK_UTF8_7BIT (1 << 7)
252-#define MASK_UTF8_START (3 << 6)
253-
254-size_t
255-STRDIFF (const STRING_TYPE *s, const STRING_TYPE *t)
256-{
257- size_t n;
258-
259- for (n = 0; *s != '\0' && *s++ == *t++; ++n)
260- continue;
261-
262- return n;
263-}
264
265 /* Track status while looking for sequences in a string. */
266 typedef struct
267@@ -274,29 +260,9 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
268 const USTRING_TYPE *extra;
269 const int32_t *indirect;
270
271- /* In case there is no locale specific sort order (C / POSIX). */
272 if (nrules == 0)
273 return STRCMP (s1, s2);
274
275- /* Fast forward to the position of the first difference. Needs to be
276- encoding aware as the byte-by-byte comparison can stop in the middle
277- of a char sequence for multibyte encodings like UTF-8. */
278- uint_fast32_t encoding =
279- current->values[_NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE)].word;
280- if (encoding != __cet_other)
281- {
282- size_t diff = STRDIFF (s1, s2);
283- if (diff > 0)
284- {
285- if (encoding == __cet_utf8 && (*(s1 + diff) & MASK_UTF8_7BIT) != 0)
286- do
287- diff--;
288- while (diff > 0 && (*(s1 + diff) & MASK_UTF8_START) != MASK_UTF8_START);
289- s1 += diff;
290- s2 += diff;
291- }
292- }
293-
294 /* Catch empty strings. */
295 if (__glibc_unlikely (*s1 == '\0') || __glibc_unlikely (*s2 == '\0'))
296 return (*s1 != '\0') - (*s2 != '\0');
297@@ -363,9 +329,8 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
298 byte-level comparison to ensure that we don't waste time
299 going through multiple passes for totally equal strings
300 before proceeding to subsequent passes. */
301- if (pass == 0 && encoding == __cet_other &&
302- STRCMP (s1, s2) == 0)
303- return result;
304+ if (pass == 0 && STRCMP (s1, s2) == 0)
305+ return result;
306 else
307 break;
308 }
309diff --git a/wcsmbs/wcscoll_l.c b/wcsmbs/wcscoll_l.c
310index 6d9384a..87f240d 100644
311--- a/wcsmbs/wcscoll_l.c
312+++ b/wcsmbs/wcscoll_l.c
313@@ -23,7 +23,6 @@
314 #define STRING_TYPE wchar_t
315 #define USTRING_TYPE wint_t
316 #define STRCOLL __wcscoll_l
317-#define STRDIFF __wcsdiff
318 #define STRCMP __wcscmp
319 #define WEIGHT_H "../locale/weightwc.h"
320 #define SUFFIX WC
321--
3221.8.4.2
323
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 16d7698207..0000000000
--- a/meta/recipes-core/glibc/glibc/use_64bit_atomics.patch
+++ /dev/null
@@ -1,24 +0,0 @@
1This patch alows using 64 bit atomic instructions on a
232 bit platform. This is safe, providing x86 is Pentium or
3later (would not work on i386, i486). Using 64 bit atomic
4instructions bypasses code containing a bug as documented in
5https://bugzilla.yoctoproject.org/show_bug.cgi?id=8140
6
7Upstream-Status: Pending
8
9Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
10
11
12Index: libc/sysdeps/i386/i486/bits/atomic.h
13===================================================================
14--- libc.orig/sysdeps/i386/i486/bits/atomic.h
15+++ libc/sysdeps/i386/i486/bits/atomic.h
16@@ -54,7 +54,7 @@ typedef uintmax_t uatomic_max_t;
17 # endif
18 #endif
19
20-#define __HAVE_64B_ATOMICS 0
21+#define __HAVE_64B_ATOMICS 1
22 #define USE_ATOMIC_COMPILER_BUILTINS 0
23
24
diff --git a/meta/recipes-core/glibc/glibc_2.22.bb b/meta/recipes-core/glibc/glibc_2.23.bb
index c70d16e05a..18f40660ec 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 \
5 file://posix/rxspencer/COPYRIGHT;md5=dc5485bb394a13b2332ec1c785f5d83a \ 5 file://posix/rxspencer/COPYRIGHT;md5=dc5485bb394a13b2332ec1c785f5d83a \
6 file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c" 6 file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c"
7 7
8DEPENDS += "gperf-native kconfig-frontends-native" 8DEPENDS += "gperf-native"
9 9
10SRCREV ?= "a34d1c6afc86521d6ad17662a3b5362d8481514c" 10SRCREV ?= "e742928c1592b43db6809db4f39e67be151cdd27"
11 11
12SRCBRANCH ?= "release/${PV}/master" 12SRCBRANCH ?= "release/${PV}/master"
13 13
@@ -15,7 +15,6 @@ GLIBC_GIT_URI ?= "git://sourceware.org/git/glibc.git"
15UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+\.\d+(\.\d+)*)" 15UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+\.\d+(\.\d+)*)"
16 16
17SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \ 17SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
18 file://0004-Backport-https-sourceware.org-ml-libc-ports-2007-12-.patch \
19 file://0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch \ 18 file://0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch \
20 file://0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch \ 19 file://0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch \
21 file://0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch \ 20 file://0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch \
@@ -26,29 +25,17 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
26 file://0012-Make-ld-version-output-matching-grok-gold-s-output.patch \ 25 file://0012-Make-ld-version-output-matching-grok-gold-s-output.patch \
27 file://0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch \ 26 file://0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch \
28 file://0014-Add-unused-attribute.patch \ 27 file://0014-Add-unused-attribute.patch \
29 file://0015-When-disabling-SSE-also-make-sure-that-fpmath-is-not.patch \ 28 file://0015-yes-within-the-path-sets-wrong-config-variables.patch \
30 file://0016-yes-within-the-path-sets-wrong-config-variables.patch \ 29 file://0016-timezone-re-written-tzselect-as-posix-sh.patch \
31 file://0017-timezone-re-written-tzselect-as-posix-sh.patch \ 30 file://0017-Remove-bash-dependency-for-nscd-init-script.patch \
32 file://0018-eglibc-Cross-building-and-testing-instructions.patch \ 31 file://0018-eglibc-Cross-building-and-testing-instructions.patch \
33 file://0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch \ 32 file://0019-eglibc-Help-bootstrap-cross-toolchain.patch \
34 file://0020-eglibc-Help-bootstrap-cross-toolchain.patch \ 33 file://0020-eglibc-cherry-picked-from.patch \
35 file://0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch \ 34 file://0021-eglibc-Clear-cache-lines-on-ppc8xx.patch \
36 file://0022-eglibc-Clear-cache-lines-on-ppc8xx.patch \ 35 file://0022-eglibc-Resolve-__fpscr_values-on-SH4.patch \
37 file://0023-eglibc-Resolve-__fpscr_values-on-SH4.patch \ 36 file://0023-eglibc-Install-PIC-archives.patch \
38 file://0024-eglibc-Forward-port-eglibc-options-groups-support.patch \ 37 file://0025-eglibc-Forward-port-cross-locale-generation-support.patch \
39 file://0025-eglibc-Install-PIC-archives.patch \ 38 file://0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch \
40 file://0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch \
41 file://0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch \
42 file://nscd-no-bash.patch \
43 file://0028-Clear-ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA-for-prel.patch \
44 file://strcoll-Remove-incorrect-STRDIFF-based-optimization-.patch \
45 file://0029-fix-getmntent-empty-lines.patch \
46 file://CVE-2015-8777.patch \
47 file://CVE-2015-8779.patch \
48 file://CVE-2015-9761_1.patch \
49 file://CVE-2015-9761_2.patch \
50 file://CVE-2015-8776.patch \
51 file://CVE-2015-7547.patch \
52" 39"
53 40
54SRC_URI += "\ 41SRC_URI += "\
@@ -60,7 +47,7 @@ SRC_URI_append_class-nativesdk = "\
60 file://0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch \ 47 file://0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch \
61 file://0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch \ 48 file://0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch \
62 file://0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch \ 49 file://0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch \
63 file://use_64bit_atomics.patch \ 50 file://0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch \
64" 51"
65 52
66S = "${WORKDIR}/git" 53S = "${WORKDIR}/git"
@@ -89,7 +76,6 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
89 --with-headers=${STAGING_INCDIR} \ 76 --with-headers=${STAGING_INCDIR} \
90 --without-selinux \ 77 --without-selinux \
91 --enable-obsolete-rpc \ 78 --enable-obsolete-rpc \
92 --with-kconfig=${STAGING_BINDIR_NATIVE} \
93 ${GLIBC_EXTRA_OECONF}" 79 ${GLIBC_EXTRA_OECONF}"
94 80
95EXTRA_OECONF += "${@get_libc_fpu_setting(bb, d)}" 81EXTRA_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 a2e347adfe..06672995cd 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 = "\
118EXTRA_OECONF_INITIAL = "\ 118EXTRA_OECONF_INITIAL = "\
119 --disable-libmudflap \ 119 --disable-libmudflap \
120 --disable-libgomp \ 120 --disable-libgomp \
121 --disable-libssp \
122 --disable-libquadmath \ 121 --disable-libquadmath \
123 --with-system-zlib \ 122 --with-system-zlib \
124 --disable-lto \ 123 --disable-lto \
125 --disable-plugin \ 124 --disable-plugin \
126 --enable-decimal-float=no \ 125 --enable-decimal-float=no \
127 --without-isl \ 126 --without-isl \
127 gcc_cv_libc_provides_ssp=yes \
128" 128"
129 129
130EXTRA_OECONF_append_libc-uclibc = " --disable-decimal-float " 130EXTRA_OECONF_append_libc-uclibc = " --disable-decimal-float "