diff options
author | Khem Raj <raj.khem@gmail.com> | 2016-01-02 21:37:22 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-02-21 09:32:43 +0000 |
commit | 91a1baaf57153a86b7e14318c9d36e1cc38e3077 (patch) | |
tree | 51bb1d2724bbc5d3b98d9412de9cab8fb7b02524 | |
parent | c1f9507c69cac8cc28fec837a4bbb070c52a8a39 (diff) | |
download | poky-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>
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" | |||
22 | PREFERRED_PROVIDER_virtual/nativesdk-${SDK_PREFIX}libc-initial ?= "nativesdk-glibc-initial" | 22 | PREFERRED_PROVIDER_virtual/nativesdk-${SDK_PREFIX}libc-initial ?= "nativesdk-glibc-initial" |
23 | PREFERRED_PROVIDER_virtual/gettext ??= "gettext" | 23 | PREFERRED_PROVIDER_virtual/gettext ??= "gettext" |
24 | 24 | ||
25 | GCCVERSION ?= "5.%" | 25 | GCCVERSION ?= "5.3%" |
26 | SDKGCCVERSION ?= "${GCCVERSION}" | 26 | SDKGCCVERSION ?= "${GCCVERSION}" |
27 | BINUVERSION ?= "2.26%" | 27 | BINUVERSION ?= "2.26%" |
28 | GDBVERSION ?= "7.10%" | 28 | GDBVERSION ?= "7.10%" |
29 | GLIBCVERSION ?= "2.22" | 29 | GLIBCVERSION ?= "2.23" |
30 | UCLIBCVERSION ?= "1.0%" | 30 | UCLIBCVERSION ?= "1.0%" |
31 | LINUXLIBCVERSION ?= "4.4" | 31 | LINUXLIBCVERSION ?= "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 | " |
26 | EGLIBCPATCHES = "\ | 26 | EGLIBCPATCHES = "\ |
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 | ||
41 | SRCREV_glibc ?= "a34d1c6afc86521d6ad17662a3b5362d8481514c" | 38 | SRCREV_glibc ?= "e742928c1592b43db6809db4f39e67be151cdd27" |
42 | SRCREV_localedef ?= "c833367348d39dad7ba018990bfdaffaec8e9ed3" | 39 | SRCREV_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 @@ | |||
1 | require glibc_${PV}.bb | 1 | require glibc_${PV}.bb |
2 | require glibc-initial.inc | 2 | require glibc-initial.inc |
3 | 3 | ||
4 | DEPENDS += "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 @@ | |||
1 | def 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 | ||
14 | def 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 | |||
44 | PROVIDES = "virtual/libc virtual/${TARGET_PREFIX}libc-for-gcc" | 44 | PROVIDES = "virtual/libc virtual/${TARGET_PREFIX}libc-for-gcc" |
45 | PROVIDES += "virtual/libintl virtual/libiconv" | 45 | PROVIDES += "virtual/libintl virtual/libiconv" |
46 | inherit autotools texinfo distro_features_check systemd | 46 | inherit autotools texinfo distro_features_check systemd |
47 | require 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. | ||
52 | REQUIRED_DISTRO_FEATURES = "${DISTRO_FEATURES_LIBC}" | ||
53 | 47 | ||
54 | LEAD_SONAME = "libc.so" | 48 | LEAD_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 |
83 | EXTRA_OEMAKE += "SHELL=/bin/bash" | 78 | EXTRA_OEMAKE += "SHELL=/bin/bash" |
84 | 79 | ||
85 | OE_FEATURES = "${@features_to_glibc_settings(d)}" | ||
86 | do_configure_prepend() { | 80 | do_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 | |||
91 | do_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 | ||
99 | GLIBC_ADDONS ?= "nptl,libidn" | 84 | GLIBC_ADDONS ?= "nptl,libidn" |
diff --git a/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch b/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch index 3d66348133..97c280059f 100644 --- a/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch +++ b/meta/recipes-core/glibc/glibc/0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch | |||
@@ -1,7 +1,7 @@ | |||
1 | From 0876fea1b5b26da84f298714a2e23ba696607dba Mon Sep 17 00:00:00 2001 | 1 | From 66d04e2cd8badb0984050e4e9f2732f47151fbbf Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 01:48:24 +0000 | 3 | Date: Wed, 18 Mar 2015 01:48:24 +0000 |
4 | Subject: [PATCH 01/27] nativesdk-glibc: Look for host system ld.so.cache as | 4 | Subject: [PATCH 01/24] nativesdk-glibc: Look for host system ld.so.cache as |
5 | well | 5 | well |
6 | 6 | ||
7 | Upstream-Status: Inappropriate [embedded specific] | 7 | Upstream-Status: Inappropriate [embedded specific] |
@@ -27,18 +27,17 @@ RP 14/10/2010 | |||
27 | 27 | ||
28 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | 28 | Signed-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 | ||
33 | diff --git a/elf/dl-load.c b/elf/dl-load.c | 33 | diff --git a/elf/dl-load.c b/elf/dl-load.c |
34 | index 0c052e4..f45085a 100644 | 34 | index 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 | -- |
69 | 2.1.4 | 68 | 2.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 @@ | |||
1 | From 086b65d9aacffc47fcd8df68818a476a5ae76fa1 Mon Sep 17 00:00:00 2001 | 1 | From 179dc5f1e13c3ff96d5f21a2a78c089cf120ceb8 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 01:50:00 +0000 | 3 | Date: Wed, 18 Mar 2015 01:50:00 +0000 |
4 | Subject: [PATCH 02/27] nativesdk-glibc: Fix buffer overrun with a relocated | 4 | Subject: [PATCH 02/24] nativesdk-glibc: Fix buffer overrun with a relocated |
5 | SDK | 5 | SDK |
6 | 6 | ||
7 | When ld-linux-*.so.2 is relocated to a path that is longer than the | 7 | When ld-linux-*.so.2 is relocated to a path that is longer than the |
@@ -22,10 +22,10 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com> | |||
22 | 1 file changed, 12 insertions(+) | 22 | 1 file changed, 12 insertions(+) |
23 | 23 | ||
24 | diff --git a/elf/dl-load.c b/elf/dl-load.c | 24 | diff --git a/elf/dl-load.c b/elf/dl-load.c |
25 | index f45085a..f1eb5ed 100644 | 25 | index 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 | -- |
49 | 2.1.4 | 49 | 2.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 @@ | |||
1 | From fd595a5ec885bcb4c14417daa21c2e61c5b72e42 Mon Sep 17 00:00:00 2001 | 1 | From e76048898ae9aa49dc70d6f9b1bbc22082e61fe3 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 01:51:38 +0000 | 3 | Date: Wed, 18 Mar 2015 01:51:38 +0000 |
4 | Subject: [PATCH 03/27] nativesdk-glibc: Raise the size of arrays containing dl | 4 | Subject: [PATCH 03/24] nativesdk-glibc: Raise the size of arrays containing dl |
5 | paths | 5 | paths |
6 | 6 | ||
7 | This patch puts the dynamic loader path in the binaries, SYSTEM_DIRS strings | 7 | This 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) |
42 | diff --git a/elf/dl-load.c b/elf/dl-load.c | 42 | diff --git a/elf/dl-load.c b/elf/dl-load.c |
43 | index f1eb5ed..f664f50 100644 | 43 | index 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 |
82 | diff --git a/elf/rtld.c b/elf/rtld.c | 82 | diff --git a/elf/rtld.c b/elf/rtld.c |
83 | index 69873c2..6d3add7 100644 | 83 | index 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; |
109 | diff --git a/sysdeps/generic/dl-cache.h b/sysdeps/generic/dl-cache.h | 109 | diff --git a/sysdeps/generic/dl-cache.h b/sysdeps/generic/dl-cache.h |
110 | index 4b49869..1800d03 100644 | 110 | index 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 | -- |
125 | 2.1.4 | 125 | 2.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 @@ | |||
1 | From 2560b564b5674bf2990e5607f6342c1647a5dc4f Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Sun, 8 Mar 2015 04:01:01 +0000 | ||
4 | Subject: [PATCH 04/27] Backport | ||
5 | https://sourceware.org/ml/libc-ports/2007-12/msg00000.html | ||
6 | |||
7 | Upstream-Status: Pending | ||
8 | |||
9 | 2007-12-03 Kristian Van Der Vliet <vanders@liqwyd.com> | ||
10 | |||
11 | * bits/stdio-lock.h (_IO_acquire_lock_clear_flags2): Define | ||
12 | |||
13 | Signed-off-by: Kristian Van Der Vliet <vanders@liqwyd.com> | ||
14 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
15 | --- | ||
16 | bits/stdio-lock.h | 2 ++ | ||
17 | 1 file changed, 2 insertions(+) | ||
18 | |||
19 | diff --git a/bits/stdio-lock.h b/bits/stdio-lock.h | ||
20 | index 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 | -- | ||
33 | 2.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 @@ | |||
1 | From 2e1638115f0f924ee8235eee9265047054c15cfd Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Thu, 31 Dec 2015 14:35:35 -0800 | ||
4 | Subject: [PATCH 04/24] nativesdk-glibc: Allow 64 bit atomics for x86 | ||
5 | |||
6 | The fix consist of allowing 64bit atomic ops for x86. | ||
7 | This should be safe for i586 and newer CPUs. | ||
8 | It also makes the synchronization more efficient. | ||
9 | |||
10 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
11 | Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> | ||
12 | Signed-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 | |||
17 | diff --git a/sysdeps/i386/atomic-machine.h b/sysdeps/i386/atomic-machine.h | ||
18 | index 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 | -- | ||
31 | 2.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 @@ | |||
1 | From aa0cd82892f32e58602143c697ef0524696a6428 Mon Sep 17 00:00:00 2001 | 1 | From 7ff57edfe24b4243373fcb896ee0b613938c1ec9 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:01:50 +0000 | 3 | Date: Wed, 18 Mar 2015 00:01:50 +0000 |
4 | Subject: [PATCH 05/27] fsl e500/e5500/e6500/603e fsqrt implementation | 4 | Subject: [PATCH 05/24] fsl e500/e5500/e6500/603e fsqrt implementation |
5 | 5 | ||
6 | Upstream-Status: Pending | 6 | Upstream-Status: Pending |
7 | Signed-off-by: Edmar Wienskoski <edmar@freescale.com> | 7 | Signed-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 | -- |
1583 | 2.1.4 | 1583 | 2.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 @@ | |||
1 | From 5ec1bc5172851278231ce940b68b35ce9cbf8500 Mon Sep 17 00:00:00 2001 | 1 | From 61129ef3ee735b300604f75d50e01cb29f4387f4 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:11:22 +0000 | 3 | Date: Wed, 18 Mar 2015 00:11:22 +0000 |
4 | Subject: [PATCH 06/27] readlib: Add OECORE_KNOWN_INTERPRETER_NAMES to known | 4 | Subject: [PATCH 06/24] readlib: Add OECORE_KNOWN_INTERPRETER_NAMES to known |
5 | names | 5 | names |
6 | 6 | ||
7 | This bolts in a hook for OE to pass its own version of interpreter | 7 | This 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 | -- |
32 | 2.1.4 | 32 | 2.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 @@ | |||
1 | From ea98b1a12b5f779fd79478ff930a79ef60387851 Mon Sep 17 00:00:00 2001 | 1 | From f936548decac99501f9a4c522a3211d16542fa49 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:15:07 +0000 | 3 | Date: Wed, 18 Mar 2015 00:15:07 +0000 |
4 | Subject: [PATCH 07/27] ppc/sqrt: Fix undefined reference to `__sqrt_finite' | 4 | Subject: [PATCH 07/24] ppc/sqrt: Fix undefined reference to `__sqrt_finite' |
5 | 5 | ||
6 | on ppc fixes the errors like below | 6 | on 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 | -- |
207 | 2.1.4 | 207 | 2.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 @@ | |||
1 | From 2456ea44aeeedae87edb522f77a7969d636399b0 Mon Sep 17 00:00:00 2001 | 1 | From d02704895fdce917e337619a4414042f63edd88b Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:16:38 +0000 | 3 | Date: Wed, 18 Mar 2015 00:16:38 +0000 |
4 | Subject: [PATCH 08/27] __ieee754_sqrt{,f} are now inline functions and call | 4 | Subject: [PATCH 08/24] __ieee754_sqrt{,f} are now inline functions and call |
5 | out __slow versions | 5 | out __slow versions |
6 | 6 | ||
7 | Upstream-Status: Pending | 7 | Upstream-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 | -- |
386 | 2.1.4 | 386 | 2.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 @@ | |||
1 | From acf7a028817e71eb99d785037659abd4d120ffe2 Mon Sep 17 00:00:00 2001 | 1 | From 502f061d846e58aac7aca67e4e0d6ba9e0763b17 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:20:09 +0000 | 3 | Date: Wed, 18 Mar 2015 00:20:09 +0000 |
4 | Subject: [PATCH 09/27] Quote from bug 1443 which explains what the patch does | 4 | Subject: [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 | -- |
61 | 2.1.4 | 61 | 2.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 @@ | |||
1 | From 017322ee28c1579ce6c81904842aaada9c82403c Mon Sep 17 00:00:00 2001 | 1 | From 69a3e30b49d28a7386d18725528652931510cbfc Mon Sep 17 00:00:00 2001 |
2 | From: Ting Liu <b28495@freescale.com> | 2 | From: Ting Liu <b28495@freescale.com> |
3 | Date: Wed, 19 Dec 2012 04:39:57 -0600 | 3 | Date: Wed, 19 Dec 2012 04:39:57 -0600 |
4 | Subject: [PATCH 10/27] eglibc: run libm-err-tab.pl with specific dirs in ${S} | 4 | Subject: [PATCH 10/24] eglibc: run libm-err-tab.pl with specific dirs in ${S} |
5 | 5 | ||
6 | libm-err-tab.pl will parse all the files named "libm-test-ulps" | 6 | libm-err-tab.pl will parse all the files named "libm-test-ulps" |
7 | in the given dir recursively. To avoid parsing the one in | 7 | in 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 | ||
20 | diff --git a/manual/Makefile b/manual/Makefile | 20 | diff --git a/manual/Makefile b/manual/Makefile |
21 | index 5382208..6b701b0 100644 | 21 | index 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 | -- |
35 | 2.1.4 | 35 | 2.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 @@ | |||
1 | From 1be45f870ebbb0259bea5250a6d2c2fbcb33409d Mon Sep 17 00:00:00 2001 | 1 | From 4cf52971a841304aec30b2e975f81d7ad9d42ef0 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:24:46 +0000 | 3 | Date: Wed, 18 Mar 2015 00:24:46 +0000 |
4 | Subject: [PATCH 11/27] __ieee754_sqrt{,f} are now inline functions and call | 4 | Subject: [PATCH 11/24] __ieee754_sqrt{,f} are now inline functions and call |
5 | out __slow versions | 5 | out __slow versions |
6 | 6 | ||
7 | Upstream-Status: Pending | 7 | Upstream-Status: Pending |
@@ -57,5 +57,5 @@ index 8126535..10de1f0 100644 | |||
57 | #endif | 57 | #endif |
58 | { | 58 | { |
59 | -- | 59 | -- |
60 | 2.1.4 | 60 | 2.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 @@ | |||
1 | From 49471ab1f90e392da9520eea831ce8731be9fc8b Mon Sep 17 00:00:00 2001 | 1 | From b356816d6e005ecda7adbed9627a4315ad39de39 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:25:45 +0000 | 3 | Date: Wed, 18 Mar 2015 00:25:45 +0000 |
4 | Subject: [PATCH 12/27] Make ld --version output matching grok gold's output | 4 | Subject: [PATCH 12/24] Make ld --version output matching grok gold's output |
5 | 5 | ||
6 | adapted from from upstream branch roland/gold-vs-libc | 6 | adapted 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 | ||
16 | diff --git a/configure b/configure | 16 | diff --git a/configure b/configure |
17 | index 45cc7cb..7d7299a 100755 | 17 | index 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]*) |
29 | diff --git a/configure.ac b/configure.ac | 29 | diff --git a/configure.ac b/configure.ac |
30 | index 7e9383a..a467a69 100644 | 30 | index 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 | -- |
43 | 2.1.4 | 43 | 2.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 @@ | |||
1 | From b55e49b199c46a278ab66b6b1e3eab483b913197 Mon Sep 17 00:00:00 2001 | 1 | From 10003d48f83f7a4f7fa562ed89af904a544b6323 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:27:10 +0000 | 3 | Date: Wed, 18 Mar 2015 00:27:10 +0000 |
4 | Subject: [PATCH 13/27] sysdeps/gnu/configure.ac: handle correctly | 4 | Subject: [PATCH 13/24] sysdeps/gnu/configure.ac: handle correctly |
5 | $libc_cv_rootsbindir | 5 | $libc_cv_rootsbindir |
6 | 6 | ||
7 | Upstream-Status:Pending | 7 | Upstream-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 | ||
16 | diff --git a/sysdeps/gnu/configure b/sysdeps/gnu/configure | 16 | diff --git a/sysdeps/gnu/configure b/sysdeps/gnu/configure |
17 | index 9239297..c5ed3ca 100644 | 17 | index 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 | -- |
41 | 2.1.4 | 41 | 2.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 @@ | |||
1 | From 0229d6c9c0e7721773118d5ae1d172c269bc9826 Mon Sep 17 00:00:00 2001 | 1 | From cafa8a7ef830e02cdbf928471e06d11054946940 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:28:41 +0000 | 3 | Date: Wed, 18 Mar 2015 00:28:41 +0000 |
4 | Subject: [PATCH 14/27] Add unused attribute | 4 | Subject: [PATCH 14/24] Add unused attribute |
5 | 5 | ||
6 | Helps in avoiding gcc warning when header is is included in | 6 | Helps in avoiding gcc warning when header is is included in |
7 | a source file which does not use both functions | 7 | a 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 | -- |
33 | 2.1.4 | 33 | 2.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 @@ | |||
1 | From f058c884dd26d10c94550ca5252ed6576614d659 Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Thu, 19 Feb 2015 03:23:45 +0000 | ||
4 | Subject: [PATCH 15/27] When disabling SSE also make sure that fpmath is not | ||
5 | set to use SSE as well | ||
6 | |||
7 | This fixes errors when we inject sse options through CFLAGS and now | ||
8 | that we have -Werror turned on by default this warning turns to become | ||
9 | error on x86 | ||
10 | |||
11 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
12 | |||
13 | Upstream-Status: Pending | ||
14 | --- | ||
15 | sysdeps/x86/Makefile | 2 +- | ||
16 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
17 | |||
18 | diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile | ||
19 | index 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 | -- | ||
31 | 2.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 @@ | |||
1 | From 70199fe59c38b621ab4121d7a55719b2b29b36de Mon Sep 17 00:00:00 2001 | 1 | From 4d6bead19874e519752ceeb2a15897ff2ffbe5e8 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:31:06 +0000 | 3 | Date: Wed, 18 Mar 2015 00:31:06 +0000 |
4 | Subject: [PATCH 16/27] 'yes' within the path sets wrong config variables | 4 | Subject: [PATCH 15/24] 'yes' within the path sets wrong config variables |
5 | 5 | ||
6 | It seems that the 'AC_EGREP_CPP(yes...' example is quite popular | 6 | It seems that the 'AC_EGREP_CPP(yes...' example is quite popular |
7 | but being such a short word to grep it is likely to produce | 7 | but 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 |
65 | diff --git a/sysdeps/arm/configure b/sysdeps/arm/configure | 65 | diff --git a/sysdeps/arm/configure b/sysdeps/arm/configure |
66 | index 158116b..5eaf54e 100644 | 66 | index 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 |
84 | diff --git a/sysdeps/arm/configure.ac b/sysdeps/arm/configure.ac | 84 | diff --git a/sysdeps/arm/configure.ac b/sysdeps/arm/configure.ac |
85 | index 859c92a..2f4a6e2 100644 | 85 | index 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 |
167 | diff --git a/sysdeps/unix/sysv/linux/mips/configure b/sysdeps/unix/sysv/linux/mips/configure | 167 | diff --git a/sysdeps/unix/sysv/linux/mips/configure b/sysdeps/unix/sysv/linux/mips/configure |
168 | index 83f8b13..2b6cbee 100644 | 168 | index 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 |
185 | diff --git a/sysdeps/unix/sysv/linux/mips/configure.ac b/sysdeps/unix/sysv/linux/mips/configure.ac | 185 | diff --git a/sysdeps/unix/sysv/linux/mips/configure.ac b/sysdeps/unix/sysv/linux/mips/configure.ac |
186 | index 5039ec9..1035f76 100644 | 186 | index 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= |
201 | diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure b/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure | 201 | diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure b/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure |
202 | index 70bb18a..ffd9e3e 100644 | 202 | index 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 | -- |
262 | 2.1.4 | 262 | 2.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 @@ | |||
1 | From c90306107fbbe2979012917e87747ce78c82ab88 Mon Sep 17 00:00:00 2001 | 1 | From 3e8586eb3509e2f0d6dfb74be8f89a30b06b56e9 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:33:03 +0000 | 3 | Date: Wed, 18 Mar 2015 00:33:03 +0000 |
4 | Subject: [PATCH 17/27] timezone: re-written tzselect as posix sh | 4 | Subject: [PATCH 16/24] timezone: re-written tzselect as posix sh |
5 | 5 | ||
6 | To avoid the bash dependency. | 6 | To 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 | ||
17 | diff --git a/timezone/Makefile b/timezone/Makefile | 17 | diff --git a/timezone/Makefile b/timezone/Makefile |
18 | index 24c93c6..886b06e 100644 | 18 | index 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 | -- |
44 | 2.1.4 | 44 | 2.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 @@ | |||
1 | Don't use bashisms (except for echo -n, which busybox supports) to avoid needing bash to start nscd. | 1 | From cd9d9fe7316f4ce4ca9d8e67e22f5718879535e4 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Thu, 31 Dec 2015 14:33:02 -0800 | ||
4 | Subject: [PATCH 17/24] Remove bash dependency for nscd init script | ||
5 | |||
6 | The 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 | ||
3 | Upstream-Status: Pending | ||
4 | Signed-off-by: Ross Burton <ross.burton@intel.com> | 9 | Signed-off-by: Ross Burton <ross.burton@intel.com> |
10 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
11 | --- | ||
12 | nscd/nscd.init | 14 +++++++------- | ||
13 | 1 file changed, 7 insertions(+), 7 deletions(-) | ||
5 | 14 | ||
6 | diff --git a/nscd/nscd.init b/nscd/nscd.init | 15 | diff --git a/nscd/nscd.init b/nscd/nscd.init |
7 | index a882da7..b02986e 100644 | 16 | index a882da7..b02986e 100644 |
@@ -59,3 +68,6 @@ index a882da7..b02986e 100644 | |||
59 | RETVAL=1 | 68 | RETVAL=1 |
60 | ;; | 69 | ;; |
61 | esac | 70 | esac |
71 | -- | ||
72 | 2.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 @@ | |||
1 | From eff048074ac7b5258bb615e5a5b221daa19b18ae Mon Sep 17 00:00:00 2001 | 1 | From 8f554f4a1beb39182aad9cd9b5e1da69464dff7e Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:42:58 +0000 | 3 | Date: Wed, 18 Mar 2015 00:42:58 +0000 |
4 | Subject: [PATCH 18/27] eglibc: Cross building and testing instructions | 4 | Subject: [PATCH 18/24] eglibc: Cross building and testing instructions |
5 | 5 | ||
6 | Ported from eglibc | 6 | Ported from eglibc |
7 | Upstream-Status: Pending | 7 | Upstream-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 | -- |
618 | 2.1.4 | 618 | 2.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 @@ | |||
1 | From aa7c5fe86d04584a9aed4dc40ba856c65a1ef9c4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Wed, 18 Mar 2015 00:45:18 +0000 | ||
4 | Subject: [PATCH 19/27] eglibc: Bring Eglibc option group infrastructure to | ||
5 | glibc | ||
6 | |||
7 | Upstream-Status: Pending | ||
8 | |||
9 | Signed-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 | |||
33 | diff --git a/EGLIBC.option-groups b/EGLIBC.option-groups | ||
34 | new file mode 100644 | ||
35 | index 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 | ||
161 | diff --git a/Makefile b/Makefile | ||
162 | index 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 | ||
173 | diff --git a/config.make.in b/config.make.in | ||
174 | index 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@ | ||
186 | diff --git a/configure b/configure | ||
187 | index 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 : | ||
231 | diff --git a/configure.ac b/configure.ac | ||
232 | index 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], | ||
252 | diff --git a/option-groups.def b/option-groups.def | ||
253 | new file mode 100644 | ||
254 | index 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: | ||
1126 | diff --git a/option-groups.defaults b/option-groups.defaults | ||
1127 | new file mode 100644 | ||
1128 | index 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 | ||
1179 | diff --git a/option-groups.mak b/option-groups.mak | ||
1180 | new file mode 100644 | ||
1181 | index 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 := | ||
1226 | diff --git a/options-config/Makefile b/options-config/Makefile | ||
1227 | new file mode 100644 | ||
1228 | index 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 | ||
1287 | diff --git a/options-config/config-postproc.pl b/options-config/config-postproc.pl | ||
1288 | new file mode 100644 | ||
1289 | index 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 | +} | ||
1351 | diff --git a/options-config/config-preproc.pl b/options-config/config-preproc.pl | ||
1352 | new file mode 100644 | ||
1353 | index 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 | +} | ||
1365 | diff --git a/scripts/option-groups.awk b/scripts/option-groups.awk | ||
1366 | new file mode 100644 | ||
1367 | index 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 | -- | ||
1435 | 2.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 @@ | |||
1 | From 8fe0d29488b376011cdaaa462d557ffc0b31fb63 Mon Sep 17 00:00:00 2001 | 1 | From c2d49eab20db4ab02b6de62092fedc623d757146 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:49:28 +0000 | 3 | Date: Wed, 18 Mar 2015 00:49:28 +0000 |
4 | Subject: [PATCH 20/27] eglibc: Help bootstrap cross toolchain | 4 | Subject: [PATCH 19/24] eglibc: Help bootstrap cross toolchain |
5 | 5 | ||
6 | Taken from EGLIBC, r1484 + r1525 | 6 | Taken 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 | ||
31 | diff --git a/Makefile b/Makefile | 31 | diff --git a/Makefile b/Makefile |
32 | index f906391..e4e149e 100644 | 32 | index 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 | -- |
99 | 2.1.4 | 99 | 2.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 @@ | |||
1 | From fe2ae4f877928dd6bff5bac3f15bce4b50d2bd12 Mon Sep 17 00:00:00 2001 | 1 | From 588d936b9aa65e7cc8b1eb2cad1d209087db43a9 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:51:16 +0000 | 3 | Date: Thu, 31 Dec 2015 15:10:33 -0800 |
4 | Subject: [PATCH 21/27] eglibc: cherry-picked from | 4 | Subject: [PATCH 20/24] eglibc: cherry-picked from |
5 | http://www.eglibc.org/archives/patches/msg00772.html | ||
6 | 5 | ||
7 | It hasn't yet been merged into glibc | 6 | http://www.eglibc.org/archives/patches/msg00772.html |
7 | |||
8 | Not yet merged into glibc | ||
8 | 9 | ||
9 | Upstream-Status: Pending | 10 | Upstream-Status: Pending |
10 | 11 | ||
11 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | 12 | Signed-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 | ||
16 | diff --git a/resolv/res_libc.c b/resolv/res_libc.c | 17 | diff --git a/resolv/res_libc.c b/resolv/res_libc.c |
17 | index ee3fa21..29e2340 100644 | 18 | index 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 | -- |
63 | 2.1.4 | 65 | 2.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 @@ | |||
1 | From be7273225698074347a71de58006977bb304d7f7 Mon Sep 17 00:00:00 2001 | 1 | From b74e34e6f53816ad57b13ba6fd70a97db1bc1eae Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:53:47 +0000 | 3 | Date: Thu, 31 Dec 2015 15:15:09 -0800 |
4 | Subject: [PATCH 22/27] eglibc: Clear cache lines on ppc8xx | 4 | Subject: [PATCH 21/24] eglibc: Clear cache lines on ppc8xx |
5 | 5 | ||
6 | 2007-06-13 Nathan Sidwell <nathan@codesourcery.com> | 6 | 2007-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 | ||
15 | Upstream-Status: Pending | 15 | Upstream-Status: Pending |
16 | |||
16 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | 17 | Signed-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 | ||
22 | diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c | 23 | diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c |
23 | index c2504ff..d50f1cb 100644 | 24 | index c2504ff..d50f1cb 100644 |
@@ -47,15 +48,16 @@ index c2504ff..d50f1cb 100644 | |||
47 | break; | 48 | break; |
48 | 49 | ||
49 | diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c | 50 | diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c |
50 | index a9364c7..a3ed1d4 100644 | 51 | index 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 | -- |
80 | 2.1.4 | 82 | 2.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 @@ | |||
1 | From 718e7e5db1c8b073adb9a79ec6f167238c2d8bda Mon Sep 17 00:00:00 2001 | 1 | From 8f483cb1f21ab6431ff99e8d30d56b91607ae918 Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 00:55:53 +0000 | 3 | Date: Wed, 18 Mar 2015 00:55:53 +0000 |
4 | Subject: [PATCH 23/27] eglibc: Resolve __fpscr_values on SH4 | 4 | Subject: [PATCH 22/24] eglibc: Resolve __fpscr_values on SH4 |
5 | 5 | ||
6 | 2010-09-29 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> | 6 | 2010-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 | -- |
55 | 2.1.4 | 55 | 2.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 @@ | |||
1 | From 5773417fa91a18cd39fb35c9907d72af0ed9ea33 Mon Sep 17 00:00:00 2001 | 1 | From 58d424884eed7efde6c90af0cd7c6c37cf9b444a Mon Sep 17 00:00:00 2001 |
2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
3 | Date: Wed, 18 Mar 2015 01:57:01 +0000 | 3 | Date: Wed, 18 Mar 2015 01:57:01 +0000 |
4 | Subject: [PATCH 25/27] eglibc: Install PIC archives | 4 | Subject: [PATCH 23/24] eglibc: Install PIC archives |
5 | 5 | ||
6 | Forward port from eglibc | 6 | Forward 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 | ||
31 | diff --git a/Makerules b/Makerules | 31 | diff --git a/Makerules b/Makerules |
32 | index 1dd41aa..41778e1 100644 | 32 | index 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 | -- |
122 | 2.1.4 | 122 | 2.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 @@ | |||
1 | From 2a5d7bcf0ff791c95ee1388772408a1bf4454694 Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Wed, 18 Mar 2015 01:33:49 +0000 | ||
4 | Subject: [PATCH 24/27] eglibc: Forward port eglibc options groups support | ||
5 | |||
6 | Upstream-Status: Pending | ||
7 | |||
8 | Signed-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 | |||
162 | diff --git a/Makeconfig b/Makeconfig | ||
163 | index 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. | ||
200 | diff --git a/Makerules b/Makerules | ||
201 | index 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)) | ||
230 | diff --git a/argp/Makefile b/argp/Makefile | ||
231 | index 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 | ||
243 | diff --git a/argp/argp-fmtstream.c b/argp/argp-fmtstream.c | ||
244 | index 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 | ||
305 | diff --git a/argp/argp-help.c b/argp/argp-help.c | ||
306 | index 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) | ||
345 | diff --git a/argp/argp-namefrob.h b/argp/argp-namefrob.h | ||
346 | index 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 | ||
362 | diff --git a/catgets/Makefile b/catgets/Makefile | ||
363 | index 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 | ||
397 | diff --git a/crypt/Makefile b/crypt/Makefile | ||
398 | index 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 | ||
453 | diff --git a/crypt/crypt-entry.c b/crypt/crypt-entry.c | ||
454 | index 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 | |||
509 | diff --git a/crypt/crypt_common.c b/crypt/crypt_common.c | ||
510 | new file mode 100644 | ||
511 | index 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 | +} | ||
557 | diff --git a/crypt/crypt_util.c b/crypt/crypt_util.c | ||
558 | index 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 | -} | ||
590 | diff --git a/csu/Makefile b/csu/Makefile | ||
591 | index 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 | ||
603 | diff --git a/debug/Makefile b/debug/Makefile | ||
604 | index 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 \ | ||
682 | diff --git a/debug/segfault.c b/debug/segfault.c | ||
683 | index 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. */ | ||
727 | diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c | ||
728 | index 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) | ||
787 | diff --git a/dlfcn/Makefile b/dlfcn/Makefile | ||
788 | index 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 \ | ||
813 | diff --git a/elf/dl-support.c b/elf/dl-support.c | ||
814 | index 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; | ||
835 | diff --git a/elf/rtld.c b/elf/rtld.c | ||
836 | index 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 | |||
939 | diff --git a/extra-lib.mk b/extra-lib.mk | ||
940 | index 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 | ||
963 | diff --git a/grp/Makefile b/grp/Makefile | ||
964 | index 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 | ||
986 | diff --git a/hesiod/Makefile b/hesiod/Makefile | ||
987 | index 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 | ||
1007 | diff --git a/iconv/Makefile b/iconv/Makefile | ||
1008 | index 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 | |||
1032 | diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c | ||
1033 | index 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; | ||
1056 | diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c | ||
1057 | index 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) | ||
1104 | diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c | ||
1105 | index 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 | { | ||
1134 | diff --git a/iconvdata/Makefile b/iconvdata/Makefile | ||
1135 | index 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 | |||
1219 | diff --git a/include/netdb.h b/include/netdb.h | ||
1220 | index 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); \ | ||
1234 | diff --git a/inet/Makefile b/inet/Makefile | ||
1235 | index 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 | |||
1287 | diff --git a/intl/Makefile b/intl/Makefile | ||
1288 | index 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 \ | ||
1308 | diff --git a/intl/dcigettext.c b/intl/dcigettext.c | ||
1309 | index 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 | ||
1412 | diff --git a/io/Makefile b/io/Makefile | ||
1413 | index 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 | |||
1475 | diff --git a/libidn/Makefile b/libidn/Makefile | ||
1476 | index 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 | ||
1498 | diff --git a/libidn/toutf8.c b/libidn/toutf8.c | ||
1499 | index 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 | ||
1527 | diff --git a/libio/Makefile b/libio/Makefile | ||
1528 | index 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 | |||
1641 | diff --git a/libio/__fpurge.c b/libio/__fpurge.c | ||
1642 | index 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)) | ||
1654 | diff --git a/libio/fileops.c b/libio/fileops.c | ||
1655 | index 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 | |||
1696 | diff --git a/libio/iofwide.c b/libio/iofwide.c | ||
1697 | index 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 | ||
1744 | diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c | ||
1745 | index 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); | ||
1757 | diff --git a/libio/ioseekpos.c b/libio/ioseekpos.c | ||
1758 | index 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); | ||
1770 | diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c | ||
1771 | index 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) | ||
1795 | diff --git a/libio/libioP.h b/libio/libioP.h | ||
1796 | index 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, \ | ||
1832 | diff --git a/libio/wdummyfileops.c b/libio/wdummyfileops.c | ||
1833 | new file mode 100644 | ||
1834 | index 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) | ||
1999 | diff --git a/locale/C-ctype.c b/locale/C-ctype.c | ||
2000 | index 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 */ | ||
2046 | diff --git a/locale/Makefile b/locale/Makefile | ||
2047 | index 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) \ | ||
2115 | diff --git a/locale/catnames.c b/locale/catnames.c | ||
2116 | new file mode 100644 | ||
2117 | index 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 | + }; | ||
2169 | diff --git a/locale/dummy-setlocale.c b/locale/dummy-setlocale.c | ||
2170 | new file mode 100644 | ||
2171 | index 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) | ||
2208 | diff --git a/locale/localeinfo.h b/locale/localeinfo.h | ||
2209 | index 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 | ||
2221 | diff --git a/locale/programs/charmap-dir.c b/locale/programs/charmap-dir.c | ||
2222 | index 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 | } | ||
2267 | diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c | ||
2268 | index 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 | |||
2316 | diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c | ||
2317 | index 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 | } | ||
2398 | diff --git a/locale/programs/ld-messages.c b/locale/programs/ld-messages.c | ||
2399 | index 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 | |||
2442 | diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c | ||
2443 | index 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 | |||
2511 | diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c | ||
2512 | index 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 | |||
2524 | diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c | ||
2525 | index 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; | ||
2570 | diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c | ||
2571 | index 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. */ | ||
2593 | diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h | ||
2594 | index 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 */ | ||
2682 | diff --git a/locale/setlocale.c b/locale/setlocale.c | ||
2683 | index 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 | ||
2723 | diff --git a/locale/xlocale.c b/locale/xlocale.c | ||
2724 | index 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 */ | ||
2782 | diff --git a/localedata/Makefile b/localedata/Makefile | ||
2783 | index 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. | ||
2864 | diff --git a/login/Makefile b/login/Makefile | ||
2865 | index 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 | |||
2909 | diff --git a/malloc/Makefile b/malloc/Makefile | ||
2910 | index 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 | ||
2947 | diff --git a/malloc/memusage.c b/malloc/memusage.c | ||
2948 | index 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; | ||
2972 | diff --git a/malloc/memusage.sh b/malloc/memusage.sh | ||
2973 | index 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 | ||
2985 | diff --git a/math/Makefile b/math/Makefile | ||
2986 | index 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 \ | ||
3009 | diff --git a/misc/Makefile b/misc/Makefile | ||
3010 | index 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) | ||
3079 | diff --git a/misc/err.c b/misc/err.c | ||
3080 | index 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 | { | ||
3139 | diff --git a/misc/error.c b/misc/error.c | ||
3140 | index 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 | ||
3169 | diff --git a/misc/tst-efgcvt.c b/misc/tst-efgcvt.c | ||
3170 | index 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 | ||
3182 | diff --git a/nis/Makefile b/nis/Makefile | ||
3183 | index 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 | ||
3258 | diff --git a/nptl/Makefile b/nptl/Makefile | ||
3259 | index 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 | ||
3352 | diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c | ||
3353 | index 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 | ||
3386 | diff --git a/nscd/Makefile b/nscd/Makefile | ||
3387 | index 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 | ||
3452 | diff --git a/nscd/nis_hash.c b/nscd/nis_hash.c | ||
3453 | new file mode 100644 | ||
3454 | index 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" | ||
3461 | diff --git a/nss/Makefile b/nss/Makefile | ||
3462 | index 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)) | ||
3575 | diff --git a/nss/fixed-nsswitch.conf b/nss/fixed-nsswitch.conf | ||
3576 | new file mode 100644 | ||
3577 | index 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 | ||
3603 | diff --git a/nss/fixed-nsswitch.functions b/nss/fixed-nsswitch.functions | ||
3604 | new file mode 100644 | ||
3605 | index 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) | ||
3730 | diff --git a/nss/gen-fixed-nsswitch.c b/nss/gen-fixed-nsswitch.c | ||
3731 | new file mode 100644 | ||
3732 | index 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 | +} | ||
4539 | diff --git a/nss/getent.c b/nss/getent.c | ||
4540 | index 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 } | ||
4658 | diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c | ||
4659 | index 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 | ||
4722 | diff --git a/nss/nsswitch.c b/nss/nsswitch.c | ||
4723 | index 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 */ | ||
5012 | diff --git a/nss/nsswitch.h b/nss/nsswitch.h | ||
5013 | index 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 | |||
5049 | diff --git a/posix/Makefile b/posix/Makefile | ||
5050 | index 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 | ||
5216 | diff --git a/posix/bug-regex1.c b/posix/bug-regex1.c | ||
5217 | index 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 (®ex, '\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 | |||
5238 | diff --git a/posix/bug-regex6.c b/posix/bug-regex6.c | ||
5239 | index 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 }, | ||
5264 | diff --git a/posix/fnmatch.c b/posix/fnmatch.c | ||
5265 | index 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 | ||
5288 | diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c | ||
5289 | index 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 | |||
5359 | diff --git a/posix/glob.c b/posix/glob.c | ||
5360 | index 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) | ||
5424 | diff --git a/posix/regcomp.c b/posix/regcomp.c | ||
5425 | index 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. */ | ||
5797 | diff --git a/posix/regex.h b/posix/regex.h | ||
5798 | index 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 | ||
5852 | diff --git a/posix/regex_internal.c b/posix/regex_internal.c | ||
5853 | index 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); | ||
6041 | diff --git a/posix/regex_internal.h b/posix/regex_internal.h | ||
6042 | index 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 | } | ||
6103 | diff --git a/posix/regexec-compat.c b/posix/regexec-compat.c | ||
6104 | new file mode 100644 | ||
6105 | index 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 | ||
6148 | diff --git a/posix/regexec.c b/posix/regexec.c | ||
6149 | index 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 */ | ||
6352 | diff --git a/posix/xregex.c b/posix/xregex.c | ||
6353 | new file mode 100644 | ||
6354 | index 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 ? ®s : (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 | ||
14573 | diff --git a/pwd/Makefile b/pwd/Makefile | ||
14574 | index 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 | ||
14586 | diff --git a/resolv/Makefile b/resolv/Makefile | ||
14587 | index 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 | |||
14639 | diff --git a/stdio-common/Makefile b/stdio-common/Makefile | ||
14640 | index 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 | |||
14707 | diff --git a/stdio-common/_i18n_number.h b/stdio-common/_i18n_number.h | ||
14708 | index 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 | ||
14739 | diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c | ||
14740 | index 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); | ||
14769 | diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c | ||
14770 | index 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 | ||
14839 | diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c | ||
14840 | index 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. */ | ||
14881 | diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c | ||
14882 | index 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. */ | ||
14908 | diff --git a/stdio-common/scanf14.c b/stdio-common/scanf14.c | ||
14909 | index 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 | ||
14936 | diff --git a/stdio-common/tst-popen.c b/stdio-common/tst-popen.c | ||
14937 | index 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 | { | ||
14963 | diff --git a/stdio-common/tst-sprintf.c b/stdio-common/tst-sprintf.c | ||
14964 | index 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 | ||
14991 | diff --git a/stdio-common/tstdiomisc.c b/stdio-common/tstdiomisc.c | ||
14992 | index 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 | } | ||
15035 | diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c | ||
15036 | index 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, | ||
15119 | diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c | ||
15120 | index 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 (); | ||
15268 | diff --git a/stdlib/Makefile b/stdlib/Makefile | ||
15269 | index 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 | |||
15360 | diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c | ||
15361 | index 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; | ||
15398 | diff --git a/stdlib/tst-strtod.c b/stdlib/tst-strtod.c | ||
15399 | index 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 */ | ||
15433 | diff --git a/streams/Makefile b/streams/Makefile | ||
15434 | index 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 | ||
15453 | diff --git a/string/Makefile b/string/Makefile | ||
15454 | index 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 | |||
15496 | diff --git a/string/strcoll_l.c b/string/strcoll_l.c | ||
15497 | index 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; | ||
15520 | diff --git a/string/strerror_l.c b/string/strerror_l.c | ||
15521 | index 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 | |||
15547 | diff --git a/string/strxfrm_l.c b/string/strxfrm_l.c | ||
15548 | index 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) | ||
15571 | diff --git a/string/test-strcmp.c b/string/test-strcmp.c | ||
15572 | index 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 | |||
15610 | diff --git a/string/tst-strxfrm.c b/string/tst-strxfrm.c | ||
15611 | index 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 | } | ||
15633 | diff --git a/string/tst-strxfrm2.c b/string/tst-strxfrm2.c | ||
15634 | index 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 | } | ||
15661 | diff --git a/sunrpc/Makefile b/sunrpc/Makefile | ||
15662 | index 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) | ||
15755 | diff --git a/sysdeps/arm/Makefile b/sysdeps/arm/Makefile | ||
15756 | index 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 | ||
15774 | diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h | ||
15775 | index 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) | ||
15802 | diff --git a/sysdeps/gnu/Makefile b/sysdeps/gnu/Makefile | ||
15803 | index 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 | ||
15816 | diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile | ||
15817 | index 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) | ||
15866 | diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c | ||
15867 | index 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); | ||
16109 | diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h | ||
16110 | index 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 */ | ||
16190 | diff --git a/sysdeps/nptl/Makefile b/sysdeps/nptl/Makefile | ||
16191 | index 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) | ||
16204 | diff --git a/sysdeps/nptl/bits/libc-lock.h b/sysdeps/nptl/bits/libc-lock.h | ||
16205 | index 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) | ||
16302 | diff --git a/sysdeps/nptl/bits/libc-lockP.h b/sysdeps/nptl/bits/libc-lockP.h | ||
16303 | index 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) | ||
16388 | diff --git a/sysdeps/nptl/small-macros-fns.c b/sysdeps/nptl/small-macros-fns.c | ||
16389 | new file mode 100644 | ||
16390 | index 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)*/ | ||
16466 | diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c | ||
16467 | index 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 | ||
16496 | diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c | ||
16497 | index 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 | |||
16524 | diff --git a/time/Makefile b/time/Makefile | ||
16525 | index 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)"' \ | ||
16565 | diff --git a/time/strftime_l.c b/time/strftime_l.c | ||
16566 | index 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 | { | ||
16616 | diff --git a/time/strptime_l.c b/time/strptime_l.c | ||
16617 | index 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 | ||
16705 | diff --git a/timezone/Makefile b/timezone/Makefile | ||
16706 | index 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)"|' \ | ||
16718 | diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile | ||
16719 | index 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 | |||
16773 | diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c | ||
16774 | index 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. */ | ||
16811 | diff --git a/wctype/Makefile b/wctype/Makefile | ||
16812 | index 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 | -- | ||
16841 | 2.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 @@ | |||
1 | From a5695930aec68b3f501e475d8705cddbb63f695e Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Wed, 18 Mar 2015 01:33:49 +0000 | ||
4 | Subject: [PATCH 25/25] eglibc: Forward port cross locale generation support | ||
5 | |||
6 | Upstream-Status: Pending | ||
7 | |||
8 | Signed-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 | |||
25 | diff --git a/locale/Makefile b/locale/Makefile | ||
26 | index 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 | ||
39 | diff --git a/locale/catnames.c b/locale/catnames.c | ||
40 | new file mode 100644 | ||
41 | index 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 | + }; | ||
93 | diff --git a/locale/localeinfo.h b/locale/localeinfo.h | ||
94 | index 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 | ||
106 | diff --git a/locale/programs/charmap-dir.c b/locale/programs/charmap-dir.c | ||
107 | index 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 | } | ||
152 | diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c | ||
153 | index 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 | |||
201 | diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c | ||
202 | index 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 | } | ||
283 | diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c | ||
284 | index 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 | |||
352 | diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c | ||
353 | index 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 | |||
365 | diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c | ||
366 | index 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; | ||
411 | diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c | ||
412 | index 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. */ | ||
434 | diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h | ||
435 | index 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 */ | ||
523 | diff --git a/locale/setlocale.c b/locale/setlocale.c | ||
524 | index 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 | -- | ||
565 | 2.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 @@ | |||
1 | From 97fe7f1b23ea1f17533884b8fa7f7eb40087d558 Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Tue, 5 Jan 2016 17:50:00 -0800 | ||
4 | Subject: [PATCH] When disabling SSE, make sure -fpmath is not set to use SSE | ||
5 | either | ||
6 | |||
7 | This fixes errors when we inject sse options through CFLAGS and now | ||
8 | that we have -Werror turned on by default this warning turns to become | ||
9 | error on x86 | ||
10 | |||
11 | gcc -m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -x c /dev/null -S | ||
12 | -mno-sse -mno-mmx | ||
13 | |||
14 | generates warning | ||
15 | /dev/null:1:0: warning: SSE instruction set disabled, using 387 | ||
16 | arithmetics | ||
17 | |||
18 | where as | ||
19 | |||
20 | gcc -m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -x c /dev/null -S | ||
21 | -mno-sse -mno-mmx -mfpmath=387 | ||
22 | |||
23 | Generates no warnings | ||
24 | |||
25 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
26 | --- | ||
27 | Upstream-Status: Submitted | ||
28 | |||
29 | ChangeLog | 5 +++++ | ||
30 | sysdeps/i386/Makefile | 2 +- | ||
31 | 2 files changed, 6 insertions(+), 1 deletion(-) | ||
32 | |||
33 | diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile | ||
34 | index 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 | -- | ||
47 | 2.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 @@ | |||
1 | From ba069b3107f5ad200c4ab95e69cf368e2353b00a Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Wed, 18 Mar 2015 00:46:50 +0000 | ||
4 | Subject: [PATCH 26/27] eglibc: dl_debug_mask is controlled by | ||
5 | __OPTION_EGLIBC_RTLD_DEBUG | ||
6 | |||
7 | use GLRO_dl_debug_mask | ||
8 | |||
9 | Singed-off-by: Khem Raj <raj.khem@gmail.com> | ||
10 | |||
11 | Upstream-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 | |||
31 | diff --git a/csu/libc-start.c b/csu/libc-start.c | ||
32 | index 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 | |||
53 | diff --git a/elf/dl-cache.c b/elf/dl-cache.c | ||
54 | index 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 | |||
75 | diff --git a/elf/dl-close.c b/elf/dl-close.c | ||
76 | index 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 | |||
106 | diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c | ||
107 | index 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 | { | ||
119 | diff --git a/elf/dl-deps.c b/elf/dl-deps.c | ||
120 | index 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 | ||
150 | diff --git a/elf/dl-error.c b/elf/dl-error.c | ||
151 | index 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"); | ||
163 | diff --git a/elf/dl-fini.c b/elf/dl-fini.c | ||
164 | index 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", | ||
185 | diff --git a/elf/dl-init.c b/elf/dl-init.c | ||
186 | index 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 | |||
207 | diff --git a/elf/dl-load.c b/elf/dl-load.c | ||
208 | index 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 | ||
283 | diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c | ||
284 | index 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 | ¤t_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 }; | ||
350 | diff --git a/elf/dl-object.c b/elf/dl-object.c | ||
351 | index 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 | ||
363 | diff --git a/elf/dl-open.c b/elf/dl-open.c | ||
364 | index 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 | } | ||
412 | diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c | ||
413 | index 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 | |||
425 | diff --git a/elf/dl-version.c b/elf/dl-version.c | ||
426 | index 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), | ||
438 | diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h | ||
439 | index 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); | ||
451 | diff --git a/elf/rtld.c b/elf/rtld.c | ||
452 | index 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 | -- | ||
555 | 2.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 @@ | |||
1 | From e98779aa56fae0346dff2d0b72acadd0eaf01891 Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Wed, 27 May 2015 16:10:50 -0700 | ||
4 | Subject: [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 | |||
26 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
27 | Signed-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 | |||
34 | diff --git a/dlfcn/Makefile b/dlfcn/Makefile | ||
35 | index 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 | ||
61 | diff --git a/elf/Makefile b/elf/Makefile | ||
62 | index 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 | ||
116 | diff --git a/nptl/Makefile b/nptl/Makefile | ||
117 | index 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 | -- | ||
144 | 2.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 @@ | |||
1 | From cadaf1336332ca7bcdfe4a400776e5782a20e26d Mon Sep 17 00:00:00 2001 | ||
2 | From: "H.J. Lu" <hjl.tools@gmail.com> | ||
3 | Date: Wed, 28 Oct 2015 07:49:44 -0700 | ||
4 | Subject: [PATCH] Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits for prelink | ||
5 | |||
6 | prelink runs ld.so with the environment variable LD_TRACE_PRELINKING | ||
7 | set to dump the relocation type class from _dl_debug_bindings. prelink | ||
8 | has 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 | |||
15 | where ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA has a conflict with | ||
16 | RTYPE_CLASS_TLS. | ||
17 | |||
18 | Since prelink only uses ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY | ||
19 | bits, we should clear the other bits when the DL_DEBUG_PRELINK bit is | ||
20 | set. | ||
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 | |||
32 | Upstream-Status: submitted (https://sourceware.org/bugzilla/show_bug.cgi?id=19178) | ||
33 | |||
34 | Signed-off-by: Mark Hatle <mark.hatle@windriver.com> | ||
35 | --- | ||
36 | elf/dl-lookup.c | 21 +++++++++++++++++++-- | ||
37 | 1 file changed, 19 insertions(+), 2 deletions(-) | ||
38 | |||
39 | diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c | ||
40 | index 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 | -- | ||
83 | 1.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 @@ | |||
1 | From b0e805fa0d6fea33745952df7b7f5442ca4c374f Mon Sep 17 00:00:00 2001 | ||
2 | From: Mike Frysinger <vapier@gentoo.org> | ||
3 | Date: Fri, 28 Aug 2015 17:08:49 -0400 | ||
4 | Subject: [PATCH] getmntent: fix memory corruption w/blank lines [BZ #18887] | ||
5 | |||
6 | The fix for BZ #17273 introduced a single byte of memory corruption when | ||
7 | the line is entirely blank. It would walk back past the start of the | ||
8 | buffer 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 | |||
15 | Fix that and rework the tests. Adding the testcase for BZ #17273 to the | ||
16 | existing \040 parser does not really make sense as it's unrelated, and | ||
17 | leads to confusing behavior: it implicitly relies on the new entry being | ||
18 | longer than the previous entry (since it just rewinds the FILE*). Split | ||
19 | it out into its own dedicated testcase instead. | ||
20 | |||
21 | The original patch is at link https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=b0e805fa0d6fea33745952df7b7f5442ca4c374f. | ||
22 | Only code to mntent_r.c is kept in this patch, Change log, NEWS, Makefile, and test cases are excluded. | ||
23 | |||
24 | Upstream-Status: Backport (upstreamed to 2.23) | ||
25 | Signed-off-by: Baoshan Pang <baoshan.pang@windriver.com> | ||
26 | |||
27 | diff --git a/misc/mntent_r.c b/misc/mntent_r.c | ||
28 | index 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 @@ | |||
1 | From e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca Mon Sep 17 00:00:00 2001 | ||
2 | From: Carlos O'Donell <carlos@systemhalted.org> | ||
3 | Date: Tue, 16 Feb 2016 21:26:37 -0500 | ||
4 | Subject: [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 | |||
21 | See also: | ||
22 | https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html | ||
23 | https://sourceware.org/ml/libc-alpha/2016-02/msg00418.html | ||
24 | |||
25 | Upstream-Status: Backport | ||
26 | CVE: CVE-2015-7547 | ||
27 | |||
28 | https://sourceware.org/git/?p=glibc.git;a=commit;h=e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca | ||
29 | minor tweeking to apply to Changelog and res_send.c | ||
30 | |||
31 | Signed-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 | |||
41 | Index: 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, | ||
66 | Index: 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; | ||
216 | Index: 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) | ||
244 | Index: 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); | ||
620 | Index: 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 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Li Xin <lixin.fnst@cn.fujitsu.com> | ||
4 | |||
5 | From https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=6c84109cfa26f35c3dfed3acb97d347361bd5849 | ||
6 | Author: Carlos O'Donell <carlos@systemhalted.org> | ||
7 | Date: 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 | |||
44 | diff --git a/locale/C-collate.c b/locale/C-collate.c | ||
45 | index 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 | }; | ||
58 | diff --git a/locale/categories.def b/locale/categories.def | ||
59 | index 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 | |||
70 | diff --git a/locale/langinfo.h b/locale/langinfo.h | ||
71 | index 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. | ||
82 | diff --git a/locale/localeinfo.h b/locale/localeinfo.h | ||
83 | index 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 | ||
100 | diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c | ||
101 | index 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); | ||
134 | diff --git a/string/bug-strcoll2.c b/string/bug-strcoll2.c | ||
135 | new file mode 100644 | ||
136 | index 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 | + | ||
235 | diff --git a/string/strcoll_l.c b/string/strcoll_l.c | ||
236 | index 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 | } | ||
309 | diff --git a/wcsmbs/wcscoll_l.c b/wcsmbs/wcscoll_l.c | ||
310 | index 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 | -- | ||
322 | 1.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 @@ | |||
1 | This patch alows using 64 bit atomic instructions on a | ||
2 | 32 bit platform. This is safe, providing x86 is Pentium or | ||
3 | later (would not work on i386, i486). Using 64 bit atomic | ||
4 | instructions bypasses code containing a bug as documented in | ||
5 | https://bugzilla.yoctoproject.org/show_bug.cgi?id=8140 | ||
6 | |||
7 | Upstream-Status: Pending | ||
8 | |||
9 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
10 | |||
11 | |||
12 | Index: 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 | ||
8 | DEPENDS += "gperf-native kconfig-frontends-native" | 8 | DEPENDS += "gperf-native" |
9 | 9 | ||
10 | SRCREV ?= "a34d1c6afc86521d6ad17662a3b5362d8481514c" | 10 | SRCREV ?= "e742928c1592b43db6809db4f39e67be151cdd27" |
11 | 11 | ||
12 | SRCBRANCH ?= "release/${PV}/master" | 12 | SRCBRANCH ?= "release/${PV}/master" |
13 | 13 | ||
@@ -15,7 +15,6 @@ GLIBC_GIT_URI ?= "git://sourceware.org/git/glibc.git" | |||
15 | UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+\.\d+(\.\d+)*)" | 15 | UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+\.\d+(\.\d+)*)" |
16 | 16 | ||
17 | SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \ | 17 | SRC_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 | ||
54 | SRC_URI += "\ | 41 | SRC_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 | ||
66 | S = "${WORKDIR}/git" | 53 | S = "${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 | ||
95 | EXTRA_OECONF += "${@get_libc_fpu_setting(bb, d)}" | 81 | EXTRA_OECONF += "${@get_libc_fpu_setting(bb, d)}" |
diff --git a/meta/recipes-devtools/gcc/gcc-5.3.inc b/meta/recipes-devtools/gcc/gcc-5.3.inc index 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 = "\ | |||
118 | EXTRA_OECONF_INITIAL = "\ | 118 | EXTRA_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 | ||
130 | EXTRA_OECONF_append_libc-uclibc = " --disable-decimal-float " | 130 | EXTRA_OECONF_append_libc-uclibc = " --disable-decimal-float " |