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 " |
