diff options
author | Tudor Florea <tudor.florea@enea.com> | 2015-10-08 22:46:13 +0200 |
---|---|---|
committer | Tudor Florea <tudor.florea@enea.com> | 2015-10-08 22:46:13 +0200 |
commit | 8d89651ef729e560ad96dcfc002fcde6ff7f923b (patch) | |
tree | eb5be01c25f735d12fe9881ee6327c9b7e8bbe39 /meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20 | |
download | meta-linaro-dizzy-enea.tar.gz |
initial commit for Enea Linux 5.0 armdizzy-enea
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Diffstat (limited to 'meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20')
30 files changed, 22222 insertions, 0 deletions
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/0001-R_ARM_TLS_DTPOFF32.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/0001-R_ARM_TLS_DTPOFF32.patch new file mode 100644 index 0000000..3922cb8 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/0001-R_ARM_TLS_DTPOFF32.patch | |||
@@ -0,0 +1,56 @@ | |||
1 | |||
2 | Quote from bug 1443 which explains what the patch does : | ||
3 | |||
4 | We build some random program and link it with -lust. When we run it, | ||
5 | it dies with a SIGSEGV before reaching main(). | ||
6 | |||
7 | Libust.so depends on liburcu-bp.so from the usermode-rcu package. | ||
8 | Although libust.so is not prelinked, liburcu-bp.so IS prelinked; this | ||
9 | is critical. | ||
10 | |||
11 | Libust.so uses a TLS / __thread variable that is defined in liburcu- | ||
12 | bp.so. There are special ARM-specific relocation types that allow two | ||
13 | shared libraries to share thread-specific data. This is critical too. | ||
14 | |||
15 | One more critical issue: although liburcu-bp.so is prelinked, we can't | ||
16 | load it at its prelinked address, because we also link against | ||
17 | librt.so, and librt.so uses that address. | ||
18 | |||
19 | The dynamic linker is forced to relink liburcu-bp.so at a different | ||
20 | address. In the course of relinking, it processes the special ARM | ||
21 | relocation record mentioned above. The prelinker has already filled | ||
22 | in the information, which is a short offset into a table of thread- | ||
23 | specific data that is allocated per-thread for each library that uses | ||
24 | TLS. Because the normal behavior of a relocation is to add the symbol | ||
25 | value to an addend stored at the address being relocated, we end up | ||
26 | adding the short offset to itself, doubling it. | ||
27 | |||
28 | Now we have an awkward situation. The libust.so library doesn't know | ||
29 | about the addend, so its TLS data for this element is correct. The | ||
30 | liburcu-bp.so library has a different offset for the element. When we | ||
31 | go to initialize the element for the first time in liburcu-bp.so, we | ||
32 | write the address of the result at the doubled (broken) offset. | ||
33 | Later, when we refer to the address from libust.so, we check the value | ||
34 | at the correct offset, but it's NULL, so we eat hot SIGSEGV. | ||
35 | |||
36 | Upstream-Status: Pending | ||
37 | |||
38 | Signed-off-by: Andrei Dinu <andrei.adrianx.dinu@intel.com> | ||
39 | --- | ||
40 | .../libc/ports/sysdeps/arm/dl-machine.h | 2 +- | ||
41 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
42 | |||
43 | ndex 8d905e8..dcfa71e 100644 | ||
44 | Index: git/sysdeps/arm/dl-machine.h | ||
45 | =================================================================== | ||
46 | --- git.orig/sysdeps/arm/dl-machine.h 2014-08-27 05:30:47.748070587 +0000 | ||
47 | +++ git/sysdeps/arm/dl-machine.h 2014-08-27 05:30:47.740070587 +0000 | ||
48 | @@ -495,7 +495,7 @@ | ||
49 | |||
50 | case R_ARM_TLS_DTPOFF32: | ||
51 | if (sym != NULL) | ||
52 | - *reloc_addr += sym->st_value; | ||
53 | + *reloc_addr = sym->st_value; | ||
54 | break; | ||
55 | |||
56 | case R_ARM_TLS_TPOFF32: | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/0001-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/0001-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch new file mode 100644 index 0000000..f341282 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/0001-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch | |||
@@ -0,0 +1,33 @@ | |||
1 | From 713d822908d1b2ae8403af7f9375c7054ed3dd49 Mon Sep 17 00:00:00 2001 | ||
2 | From: Ting Liu <b28495@freescale.com> | ||
3 | Date: Wed, 19 Dec 2012 04:39:57 -0600 | ||
4 | Subject: [PATCH] eglibc: run libm-err-tab.pl with specific dirs in ${S} | ||
5 | |||
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 | ||
8 | ${S}/.pc/ (it does exist after eglibc adds aarch64 support, | ||
9 | ${S}/.pc/aarch64-0001-glibc-fsf-v1-eaf6f205.patch/ports/sysdeps/ | ||
10 | aarch64/libm-test-ulps), run libm-err-tab.pl with specific dirs | ||
11 | in ${S}. | ||
12 | |||
13 | Upstream-Status: inappropriate [OE specific] | ||
14 | |||
15 | Signed-off-by: Ting Liu <b28495@freescale.com> | ||
16 | --- | ||
17 | manual/Makefile | 3 ++- | ||
18 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
19 | |||
20 | Index: git/manual/Makefile | ||
21 | =================================================================== | ||
22 | --- git.orig/manual/Makefile 2014-08-29 10:35:18.728070587 -0700 | ||
23 | +++ git/manual/Makefile 2014-08-29 10:35:18.720070587 -0700 | ||
24 | @@ -105,7 +105,8 @@ | ||
25 | $(objpfx)stamp-libm-err: libm-err-tab.pl $(wildcard $(foreach dir,$(sysdirs),\ | ||
26 | $(dir)/libm-test-ulps)) | ||
27 | pwd=`pwd`; \ | ||
28 | - $(PERL) $< $$pwd/.. > $(objpfx)libm-err-tmp | ||
29 | + $(PERL) $< $$pwd/../ports > $(objpfx)libm-err-tmp | ||
30 | + $(PERL) $< $$pwd/../sysdeps >> $(objpfx)libm-err-tmp | ||
31 | $(move-if-change) $(objpfx)libm-err-tmp $(objpfx)libm-err.texi | ||
32 | touch $@ | ||
33 | |||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/GLRO_dl_debug_mask.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/GLRO_dl_debug_mask.patch new file mode 100644 index 0000000..e858bfa --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/GLRO_dl_debug_mask.patch | |||
@@ -0,0 +1,529 @@ | |||
1 | Its controlled by __OPTION_EGLIBC_RTLD_DEBUG | ||
2 | so we should use GLRO_dl_debug_mask | ||
3 | |||
4 | Singed-off-by: Khem Raj <raj.khem@gmail.com> | ||
5 | |||
6 | Upstream-Status: Pending | ||
7 | Index: git/elf/dl-open.c | ||
8 | =================================================================== | ||
9 | --- git.orig/elf/dl-open.c 2014-08-27 05:03:59.732070587 +0000 | ||
10 | +++ git/elf/dl-open.c 2014-08-27 05:05:25.656070587 +0000 | ||
11 | @@ -147,7 +147,7 @@ | ||
12 | ns->_ns_main_searchlist->r_list[new_nlist++] = map; | ||
13 | |||
14 | /* We modify the global scope. Report this. */ | ||
15 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) | ||
16 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES)) | ||
17 | _dl_debug_printf ("\nadd %s [%lu] to global scope\n", | ||
18 | map->l_name, map->l_ns); | ||
19 | } | ||
20 | @@ -243,7 +243,7 @@ | ||
21 | if (__glibc_unlikely (new->l_searchlist.r_list != NULL)) | ||
22 | { | ||
23 | /* Let the user know about the opencount. */ | ||
24 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) | ||
25 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) | ||
26 | _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", | ||
27 | new->l_name, new->l_ns, new->l_direct_opencount); | ||
28 | |||
29 | @@ -294,7 +294,7 @@ | ||
30 | LIBC_PROBE (map_complete, 3, args->nsid, r, new); | ||
31 | |||
32 | /* Print scope information. */ | ||
33 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) | ||
34 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES)) | ||
35 | _dl_show_scope (new, 0); | ||
36 | |||
37 | /* Only do lazy relocation if `LD_BIND_NOW' is not set. */ | ||
38 | @@ -511,7 +511,7 @@ | ||
39 | } | ||
40 | |||
41 | /* Print scope information. */ | ||
42 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) | ||
43 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES)) | ||
44 | _dl_show_scope (imap, from_scope); | ||
45 | } | ||
46 | |||
47 | @@ -584,7 +584,7 @@ | ||
48 | #endif | ||
49 | |||
50 | /* Let the user know about the opencount. */ | ||
51 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) | ||
52 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) | ||
53 | _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", | ||
54 | new->l_name, new->l_ns, new->l_direct_opencount); | ||
55 | } | ||
56 | Index: git/elf/rtld.c | ||
57 | =================================================================== | ||
58 | --- git.orig/elf/rtld.c 2014-08-27 05:03:59.732070587 +0000 | ||
59 | +++ git/elf/rtld.c 2014-08-27 05:12:33.812070587 +0000 | ||
60 | @@ -321,7 +321,7 @@ | ||
61 | } | ||
62 | #endif | ||
63 | |||
64 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS)) | ||
65 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS)) | ||
66 | { | ||
67 | #ifndef HP_TIMING_NONAVAIL | ||
68 | print_statistics (&rtld_total_time); | ||
69 | @@ -1699,7 +1699,7 @@ | ||
70 | after relocation. */ | ||
71 | struct link_map *l; | ||
72 | |||
73 | - if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) | ||
74 | + if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK) | ||
75 | { | ||
76 | struct r_scope_elem *scope = &main_map->l_searchlist; | ||
77 | |||
78 | @@ -1729,7 +1729,7 @@ | ||
79 | _dl_printf ("\n"); | ||
80 | } | ||
81 | } | ||
82 | - else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) | ||
83 | + else if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED) | ||
84 | { | ||
85 | /* Look through the dependencies of the main executable | ||
86 | and determine which of them is not actually | ||
87 | @@ -1837,7 +1837,7 @@ | ||
88 | } | ||
89 | } | ||
90 | |||
91 | - if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) | ||
92 | + if ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK) | ||
93 | && rtld_multiple_ref) | ||
94 | { | ||
95 | /* Mark the link map as not yet relocated again. */ | ||
96 | @@ -1970,7 +1970,7 @@ | ||
97 | if (r_list == r_listend && liblist == liblistend) | ||
98 | prelinked = true; | ||
99 | |||
100 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) | ||
101 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) | ||
102 | _dl_debug_printf ("\nprelink checking: %s\n", | ||
103 | prelinked ? "ok" : "failed"); | ||
104 | } | ||
105 | @@ -1988,7 +1988,7 @@ | ||
106 | GLRO(dl_init_all_dirs) = GL(dl_all_dirs); | ||
107 | |||
108 | /* Print scope information. */ | ||
109 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) | ||
110 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES)) | ||
111 | { | ||
112 | _dl_debug_printf ("\nInitial object scopes\n"); | ||
113 | |||
114 | @@ -2262,7 +2262,7 @@ | ||
115 | if (debopts[cnt].len == len | ||
116 | && memcmp (dl_debug, debopts[cnt].name, len) == 0) | ||
117 | { | ||
118 | - GLRO(dl_debug_mask) |= debopts[cnt].mask; | ||
119 | + GLRO_dl_debug_mask |= debopts[cnt].mask; | ||
120 | any_debug = 1; | ||
121 | break; | ||
122 | } | ||
123 | @@ -2283,7 +2283,7 @@ | ||
124 | ++dl_debug; | ||
125 | } | ||
126 | |||
127 | - if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) | ||
128 | + if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED) | ||
129 | { | ||
130 | /* In order to get an accurate picture of whether a particular | ||
131 | DT_NEEDED entry is actually used we have to process both | ||
132 | @@ -2291,7 +2291,7 @@ | ||
133 | GLRO(dl_lazy) = 0; | ||
134 | } | ||
135 | |||
136 | - if (GLRO(dl_debug_mask) & DL_DEBUG_HELP) | ||
137 | + if (GLRO_dl_debug_mask & DL_DEBUG_HELP) | ||
138 | { | ||
139 | size_t cnt; | ||
140 | |||
141 | @@ -2490,7 +2490,7 @@ | ||
142 | { | ||
143 | mode = trace; | ||
144 | GLRO(dl_verbose) = 1; | ||
145 | - GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK; | ||
146 | + GLRO_dl_debug_mask |= DL_DEBUG_PRELINK; | ||
147 | GLRO(dl_trace_prelink) = &envline[17]; | ||
148 | } | ||
149 | break; | ||
150 | @@ -2537,7 +2537,7 @@ | ||
151 | if (__access ("/etc/suid-debug", F_OK) != 0) | ||
152 | { | ||
153 | unsetenv ("MALLOC_CHECK_"); | ||
154 | - GLRO(dl_debug_mask) = 0; | ||
155 | + GLRO_dl_debug_mask = 0; | ||
156 | } | ||
157 | |||
158 | if (mode != normal) | ||
159 | Index: git/elf/dl-lookup.c | ||
160 | =================================================================== | ||
161 | --- git.orig/elf/dl-lookup.c 2014-08-27 05:03:59.732070587 +0000 | ||
162 | +++ git/elf/dl-lookup.c 2014-08-27 05:13:07.644070587 +0000 | ||
163 | @@ -300,7 +300,7 @@ | ||
164 | hash table. */ | ||
165 | if (__glibc_unlikely (tab->size)) | ||
166 | { | ||
167 | - assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK); | ||
168 | + assert (GLRO_dl_debug_mask & DL_DEBUG_PRELINK); | ||
169 | goto success; | ||
170 | } | ||
171 | #endif | ||
172 | @@ -375,7 +375,7 @@ | ||
173 | continue; | ||
174 | |||
175 | /* Print some debugging info if wanted. */ | ||
176 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS)) | ||
177 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SYMBOLS)) | ||
178 | _dl_debug_printf ("symbol=%s; lookup in file=%s [%lu]\n", | ||
179 | undef_name, DSO_FILENAME (map->l_name), | ||
180 | map->l_ns); | ||
181 | @@ -698,7 +698,7 @@ | ||
182 | } | ||
183 | |||
184 | /* Display information if we are debugging. */ | ||
185 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) | ||
186 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) | ||
187 | _dl_debug_printf ("\ | ||
188 | \nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n", | ||
189 | DSO_FILENAME (map->l_name), | ||
190 | @@ -802,7 +802,7 @@ | ||
191 | { | ||
192 | if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) | ||
193 | && skip_map == NULL | ||
194 | - && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)) | ||
195 | + && !(GLRO_dl_debug_mask & DL_DEBUG_UNUSED)) | ||
196 | { | ||
197 | /* We could find no value for a strong reference. */ | ||
198 | const char *reference_name = undef_map ? undef_map->l_name : ""; | ||
199 | @@ -873,7 +873,7 @@ | ||
200 | if (__glibc_unlikely (current_value.m->l_used == 0)) | ||
201 | current_value.m->l_used = 1; | ||
202 | |||
203 | - if (__glibc_unlikely (GLRO(dl_debug_mask) | ||
204 | + if (__glibc_unlikely (GLRO_dl_debug_mask | ||
205 | & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK))) | ||
206 | _dl_debug_bindings (undef_name, undef_map, ref, | ||
207 | ¤t_value, version, type_class, protected); | ||
208 | @@ -938,7 +938,7 @@ | ||
209 | { | ||
210 | const char *reference_name = undef_map->l_name; | ||
211 | |||
212 | - if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS) | ||
213 | + if (GLRO_dl_debug_mask & DL_DEBUG_BINDINGS) | ||
214 | { | ||
215 | _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'", | ||
216 | DSO_FILENAME (reference_name), | ||
217 | @@ -952,7 +952,7 @@ | ||
218 | _dl_debug_printf_c ("\n"); | ||
219 | } | ||
220 | #ifdef SHARED | ||
221 | - if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) | ||
222 | + if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK) | ||
223 | { | ||
224 | int conflict = 0; | ||
225 | struct sym_val val = { NULL, NULL }; | ||
226 | Index: git/elf/get-dynamic-info.h | ||
227 | =================================================================== | ||
228 | --- git.orig/elf/get-dynamic-info.h 2014-08-27 05:03:59.732070587 +0000 | ||
229 | +++ git/elf/get-dynamic-info.h 2014-08-27 05:03:59.728070587 +0000 | ||
230 | @@ -157,7 +157,7 @@ | ||
231 | them. Therefore to avoid breaking existing applications the | ||
232 | best we can do is add a warning during debugging with the | ||
233 | intent of notifying the user of the problem. */ | ||
234 | - if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0) | ||
235 | + if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0) | ||
236 | && l->l_flags_1 & ~DT_1_SUPPORTED_MASK) | ||
237 | _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.\n", | ||
238 | l->l_flags_1 & ~DT_1_SUPPORTED_MASK); | ||
239 | Index: git/csu/libc-start.c | ||
240 | =================================================================== | ||
241 | --- git.orig/csu/libc-start.c 2014-08-27 04:59:01.412070587 +0000 | ||
242 | +++ git/csu/libc-start.c 2014-08-27 05:09:28.936070587 +0000 | ||
243 | @@ -238,7 +238,7 @@ | ||
244 | |||
245 | /* Call the initializer of the program, if any. */ | ||
246 | #ifdef SHARED | ||
247 | - if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) | ||
248 | + if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) | ||
249 | GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]); | ||
250 | #endif | ||
251 | if (init) | ||
252 | @@ -261,7 +261,7 @@ | ||
253 | #endif | ||
254 | |||
255 | #ifdef SHARED | ||
256 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) | ||
257 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS)) | ||
258 | GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]); | ||
259 | #endif | ||
260 | |||
261 | Index: git/elf/dl-cache.c | ||
262 | =================================================================== | ||
263 | --- git.orig/elf/dl-cache.c 2014-08-27 04:59:01.568070587 +0000 | ||
264 | +++ git/elf/dl-cache.c 2014-08-27 05:10:14.384070587 +0000 | ||
265 | @@ -187,7 +187,7 @@ | ||
266 | const char *best; | ||
267 | |||
268 | /* Print a message if the loading of libs is traced. */ | ||
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 (" search cache=%s\n", LD_SO_CACHE); | ||
272 | |||
273 | if (cache == NULL) | ||
274 | @@ -285,7 +285,7 @@ | ||
275 | } | ||
276 | |||
277 | /* Print our result if wanted. */ | ||
278 | - if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0) | ||
279 | + if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0) | ||
280 | && best != NULL) | ||
281 | _dl_debug_printf (" trying file=%s\n", best); | ||
282 | |||
283 | Index: git/elf/dl-close.c | ||
284 | =================================================================== | ||
285 | --- git.orig/elf/dl-close.c 2014-08-27 04:59:01.568070587 +0000 | ||
286 | +++ git/elf/dl-close.c 2014-08-27 05:10:26.456070587 +0000 | ||
287 | @@ -125,7 +125,7 @@ | ||
288 | dl_close_state = rerun; | ||
289 | |||
290 | /* There are still references to this object. Do nothing more. */ | ||
291 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) | ||
292 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) | ||
293 | _dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n", | ||
294 | map->l_name, map->l_direct_opencount); | ||
295 | |||
296 | @@ -257,7 +257,7 @@ | ||
297 | if (imap->l_init_called) | ||
298 | { | ||
299 | /* When debugging print a message first. */ | ||
300 | - if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, | ||
301 | + if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, | ||
302 | 0)) | ||
303 | _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n", | ||
304 | imap->l_name, nsid); | ||
305 | @@ -664,7 +664,7 @@ | ||
306 | free (imap->l_reldeps); | ||
307 | |||
308 | /* Print debugging message. */ | ||
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 ("\nfile=%s [%lu]; destroying link map\n", | ||
312 | imap->l_name, imap->l_ns); | ||
313 | |||
314 | Index: git/elf/dl-conflict.c | ||
315 | =================================================================== | ||
316 | --- git.orig/elf/dl-conflict.c 2014-08-27 04:59:01.568070587 +0000 | ||
317 | +++ git/elf/dl-conflict.c 2014-08-27 05:10:37.652070587 +0000 | ||
318 | @@ -32,7 +32,7 @@ | ||
319 | ElfW(Rela) *conflictend) | ||
320 | { | ||
321 | #if ! ELF_MACHINE_NO_RELA | ||
322 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) | ||
323 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC)) | ||
324 | _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name)); | ||
325 | |||
326 | { | ||
327 | Index: git/elf/dl-deps.c | ||
328 | =================================================================== | ||
329 | --- git.orig/elf/dl-deps.c 2014-08-27 04:59:01.568070587 +0000 | ||
330 | +++ git/elf/dl-deps.c 2014-08-27 05:10:48.260070587 +0000 | ||
331 | @@ -127,7 +127,7 @@ | ||
332 | else \ | ||
333 | { \ | ||
334 | /* This is for DT_AUXILIARY. */ \ | ||
335 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) \ | ||
336 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) \ | ||
337 | _dl_debug_printf (N_("\ | ||
338 | cannot load auxiliary `%s' because of empty dynamic string token " \ | ||
339 | "substitution\n"), __str); \ | ||
340 | @@ -303,7 +303,7 @@ | ||
341 | args.name = name; | ||
342 | |||
343 | /* Say that we are about to load an auxiliary library. */ | ||
344 | - if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, | ||
345 | + if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, | ||
346 | 0)) | ||
347 | _dl_debug_printf ("load auxiliary object=%s" | ||
348 | " requested by file=%s\n", | ||
349 | @@ -520,7 +520,7 @@ | ||
350 | runp->map->l_reserved = 0; | ||
351 | } | ||
352 | |||
353 | - if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0 | ||
354 | + if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_PRELINK, 0) != 0 | ||
355 | && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded) | ||
356 | { | ||
357 | /* If we are to compute conflicts, we have to build local scope | ||
358 | Index: git/elf/dl-error.c | ||
359 | =================================================================== | ||
360 | --- git.orig/elf/dl-error.c 2014-08-27 04:59:01.568070587 +0000 | ||
361 | +++ git/elf/dl-error.c 2014-08-27 05:11:06.752070587 +0000 | ||
362 | @@ -139,7 +139,7 @@ | ||
363 | _dl_signal_cerror (int errcode, const char *objname, const char *occation, | ||
364 | const char *errstring) | ||
365 | { | ||
366 | - if (__builtin_expect (GLRO(dl_debug_mask) | ||
367 | + if (__builtin_expect (GLRO_dl_debug_mask | ||
368 | & ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0)) | ||
369 | _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation, | ||
370 | errstring, receiver ? "continued" : "fatal"); | ||
371 | Index: git/elf/dl-fini.c | ||
372 | =================================================================== | ||
373 | --- git.orig/elf/dl-fini.c 2014-08-27 04:59:01.568070587 +0000 | ||
374 | +++ git/elf/dl-fini.c 2014-08-27 05:11:17.544070587 +0000 | ||
375 | @@ -234,7 +234,7 @@ | ||
376 | || l->l_info[DT_FINI] != NULL) | ||
377 | { | ||
378 | /* When debugging print a message first. */ | ||
379 | - if (__builtin_expect (GLRO(dl_debug_mask) | ||
380 | + if (__builtin_expect (GLRO_dl_debug_mask | ||
381 | & DL_DEBUG_IMPCALLS, 0)) | ||
382 | _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n", | ||
383 | DSO_FILENAME (l->l_name), | ||
384 | @@ -286,7 +286,7 @@ | ||
385 | goto again; | ||
386 | } | ||
387 | |||
388 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS)) | ||
389 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS)) | ||
390 | _dl_debug_printf ("\nruntime linker statistics:\n" | ||
391 | " final number of relocations: %lu\n" | ||
392 | "final number of relocations from cache: %lu\n", | ||
393 | Index: git/elf/dl-init.c | ||
394 | =================================================================== | ||
395 | --- git.orig/elf/dl-init.c 2014-08-27 04:59:01.568070587 +0000 | ||
396 | +++ git/elf/dl-init.c 2014-08-27 05:11:28.372070587 +0000 | ||
397 | @@ -52,7 +52,7 @@ | ||
398 | return; | ||
399 | |||
400 | /* Print a debug message if wanted. */ | ||
401 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) | ||
402 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS)) | ||
403 | _dl_debug_printf ("\ncalling init: %s\n\n", | ||
404 | DSO_FILENAME (l->l_name)); | ||
405 | |||
406 | @@ -102,7 +102,7 @@ | ||
407 | ElfW(Addr) *addrs; | ||
408 | unsigned int cnt; | ||
409 | |||
410 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) | ||
411 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS)) | ||
412 | _dl_debug_printf ("\ncalling preinit: %s\n\n", | ||
413 | DSO_FILENAME (main_map->l_name)); | ||
414 | |||
415 | Index: git/elf/dl-load.c | ||
416 | =================================================================== | ||
417 | --- git.orig/elf/dl-load.c 2014-08-27 04:59:01.572070587 +0000 | ||
418 | +++ git/elf/dl-load.c 2014-08-27 05:11:41.156070587 +0000 | ||
419 | @@ -957,7 +957,7 @@ | ||
420 | } | ||
421 | |||
422 | /* Print debugging message. */ | ||
423 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) | ||
424 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) | ||
425 | _dl_debug_printf ("file=%s [%lu]; generating link map\n", name, nsid); | ||
426 | |||
427 | /* This is the ELF header. We read it in `open_verify'. */ | ||
428 | @@ -1361,7 +1361,7 @@ | ||
429 | |||
430 | l->l_entry += l->l_addr; | ||
431 | |||
432 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) | ||
433 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)) | ||
434 | _dl_debug_printf ("\ | ||
435 | dynamic: 0x%0*lx base: 0x%0*lx size: 0x%0*Zx\n\ | ||
436 | entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u\n\n", | ||
437 | @@ -1787,7 +1787,7 @@ | ||
438 | |||
439 | /* If we are debugging the search for libraries print the path | ||
440 | now if it hasn't happened now. */ | ||
441 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS) | ||
442 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS) | ||
443 | && current_what != this_dir->what) | ||
444 | { | ||
445 | current_what = this_dir->what; | ||
446 | @@ -1808,7 +1808,7 @@ | ||
447 | - buf); | ||
448 | |||
449 | /* Print name we try if this is wanted. */ | ||
450 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) | ||
451 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) | ||
452 | _dl_debug_printf (" trying file=%s\n", buf); | ||
453 | |||
454 | fd = open_verify (buf, fbp, loader, whatcode, mode, | ||
455 | @@ -1953,7 +1953,7 @@ | ||
456 | } | ||
457 | |||
458 | /* Display information if we are debugging. */ | ||
459 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES) | ||
460 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES) | ||
461 | && loader != NULL) | ||
462 | _dl_debug_printf ((mode & __RTLD_CALLMAP) == 0 | ||
463 | ? "\nfile=%s [%lu]; needed by %s [%lu]\n" | ||
464 | @@ -1995,7 +1995,7 @@ | ||
465 | |||
466 | size_t namelen = strlen (name) + 1; | ||
467 | |||
468 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) | ||
469 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) | ||
470 | _dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid); | ||
471 | |||
472 | fd = -1; | ||
473 | @@ -2122,7 +2122,7 @@ | ||
474 | &realname, &fb, l, LA_SER_DEFAULT, &found_other_class); | ||
475 | |||
476 | /* Add another newline when we are tracing the library loading. */ | ||
477 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) | ||
478 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) | ||
479 | _dl_debug_printf ("\n"); | ||
480 | } | ||
481 | else | ||
482 | @@ -2155,7 +2155,7 @@ | ||
483 | if (__glibc_unlikely (fd == -1)) | ||
484 | { | ||
485 | if (trace_mode | ||
486 | - && __glibc_likely ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) == 0)) | ||
487 | + && __glibc_likely ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK) == 0)) | ||
488 | { | ||
489 | /* We haven't found an appropriate library. But since we | ||
490 | are only interested in the list of libraries this isn't | ||
491 | Index: git/elf/dl-object.c | ||
492 | =================================================================== | ||
493 | --- git.orig/elf/dl-object.c 2014-08-27 04:59:01.572070587 +0000 | ||
494 | +++ git/elf/dl-object.c 2014-08-27 05:11:51.756070587 +0000 | ||
495 | @@ -98,7 +98,7 @@ | ||
496 | new->l_type = type; | ||
497 | /* If we set the bit now since we know it is never used we avoid | ||
498 | dirtying the cache line later. */ | ||
499 | - if ((GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) == 0) | ||
500 | + if ((GLRO_dl_debug_mask & DL_DEBUG_UNUSED) == 0) | ||
501 | new->l_used = 1; | ||
502 | new->l_loader = loader; | ||
503 | #if NO_TLS_OFFSET != 0 | ||
504 | Index: git/elf/dl-reloc.c | ||
505 | =================================================================== | ||
506 | --- git.orig/elf/dl-reloc.c 2014-08-27 04:59:01.572070587 +0000 | ||
507 | +++ git/elf/dl-reloc.c 2014-08-27 05:12:07.056070587 +0000 | ||
508 | @@ -183,7 +183,7 @@ | ||
509 | && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0)) | ||
510 | lazy = 0; | ||
511 | |||
512 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) | ||
513 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC)) | ||
514 | _dl_debug_printf ("\nrelocation processing: %s%s\n", | ||
515 | DSO_FILENAME (l->l_name), lazy ? " (lazy)" : ""); | ||
516 | |||
517 | Index: git/elf/dl-version.c | ||
518 | =================================================================== | ||
519 | --- git.orig/elf/dl-version.c 2014-08-27 04:59:01.608070587 +0000 | ||
520 | +++ git/elf/dl-version.c 2014-08-27 05:12:19.568070587 +0000 | ||
521 | @@ -82,7 +82,7 @@ | ||
522 | int result = 0; | ||
523 | |||
524 | /* Display information about what we are doing while debugging. */ | ||
525 | - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS)) | ||
526 | + if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_VERSIONS)) | ||
527 | _dl_debug_printf ("\ | ||
528 | checking for version `%s' in file %s [%lu] required by file %s [%lu]\n", | ||
529 | string, DSO_FILENAME (map->l_name), | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/IO-acquire-lock-fix.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/IO-acquire-lock-fix.patch new file mode 100644 index 0000000..ffbaba1 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/IO-acquire-lock-fix.patch | |||
@@ -0,0 +1,17 @@ | |||
1 | import http://sourceware.org/ml/libc-ports/2007-12/msg00000.html | ||
2 | |||
3 | Upstream-Status: Pending | ||
4 | |||
5 | Index: git/bits/stdio-lock.h | ||
6 | =================================================================== | ||
7 | --- git.orig/bits/stdio-lock.h 2014-08-29 10:33:57.960070587 -0700 | ||
8 | +++ git/bits/stdio-lock.h 2014-08-29 10:33:57.952070587 -0700 | ||
9 | @@ -49,6 +49,8 @@ | ||
10 | _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, (_fp)); \ | ||
11 | _IO_flockfile (_fp) | ||
12 | |||
13 | +# define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp) | ||
14 | + | ||
15 | # define _IO_release_lock(_fp) \ | ||
16 | _IO_funlockfile (_fp); \ | ||
17 | _IO_cleanup_region_end (0) | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/add_resource_h_to_wait_h.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/add_resource_h_to_wait_h.patch new file mode 100644 index 0000000..4559de7 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/add_resource_h_to_wait_h.patch | |||
@@ -0,0 +1,20 @@ | |||
1 | The older versions of perf still require sys/resource.h to be | ||
2 | present in this header, the newer version of perf in 3.2 and | ||
3 | beyond directly include sys/resource.h | ||
4 | |||
5 | Upstream-Status: Inapproriate [older kernel/perf specific] | ||
6 | |||
7 | Signed-off-by: Saul Wold <sgw@linux.intel.com> | ||
8 | |||
9 | Index: git/posix/sys/wait.h | ||
10 | =================================================================== | ||
11 | --- git.orig/posix/sys/wait.h 2014-08-29 10:35:10.432070587 -0700 | ||
12 | +++ git/posix/sys/wait.h 2014-08-29 10:35:10.424070587 -0700 | ||
13 | @@ -27,6 +27,7 @@ | ||
14 | __BEGIN_DECLS | ||
15 | |||
16 | #include <signal.h> | ||
17 | +#include <sys/resource.h> | ||
18 | |||
19 | /* These macros could also be defined in <stdlib.h>. */ | ||
20 | #if !defined _STDLIB_H || (!defined __USE_XOPEN && !defined __USE_XOPEN2K8) | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-header-bootstrap.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-header-bootstrap.patch new file mode 100644 index 0000000..e1aa139 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-header-bootstrap.patch | |||
@@ -0,0 +1,85 @@ | |||
1 | Taken from EGLIBC, r1484 + r1525 | ||
2 | |||
3 | 2007-02-20 Jim Blandy <jimb@codesourcery.com> | ||
4 | |||
5 | * Makefile (install-headers): Preserve old behavior: depend on | ||
6 | $(inst_includedir)/gnu/stubs.h only if install-bootstrap-headers | ||
7 | is set; otherwise, place gnu/stubs.h on the 'install-others' list. | ||
8 | |||
9 | 2007-02-16 Jim Blandy <jimb@codesourcery.com> | ||
10 | |||
11 | * Makefile: Amend make install-headers to install everything | ||
12 | necessary for building a cross-compiler. Install gnu/stubs.h as | ||
13 | part of 'install-headers', not 'install-others'. | ||
14 | If install-bootstrap-headers is 'yes', install a dummy copy of | ||
15 | gnu/stubs.h, instead of computing the real thing. | ||
16 | * include/stubs-bootstrap.h: New file. | ||
17 | |||
18 | Upstream-Status: Pending | ||
19 | |||
20 | Index: git/Makefile | ||
21 | =================================================================== | ||
22 | --- git.orig/Makefile 2014-08-27 18:35:18.908070587 +0000 | ||
23 | +++ git/Makefile 2014-08-27 18:35:19.340070587 +0000 | ||
24 | @@ -69,9 +69,18 @@ | ||
25 | vpath %.h $(subdir-dirs) | ||
26 | |||
27 | # What to install. | ||
28 | -install-others = $(inst_includedir)/gnu/stubs.h | ||
29 | install-bin-script = | ||
30 | |||
31 | +# If we're bootstrapping, install a dummy gnu/stubs.h along with the | ||
32 | +# other headers, so 'make install-headers' produces a useable include | ||
33 | +# tree. Otherwise, install gnu/stubs.h later, after the rest of the | ||
34 | +# build is done. | ||
35 | +ifeq ($(install-bootstrap-headers),yes) | ||
36 | +install-headers: $(inst_includedir)/gnu/stubs.h | ||
37 | +else | ||
38 | +install-others = $(inst_includedir)/gnu/stubs.h | ||
39 | +endif | ||
40 | + | ||
41 | ifeq (yes,$(build-shared)) | ||
42 | headers += gnu/lib-names.h | ||
43 | endif | ||
44 | @@ -151,6 +160,16 @@ | ||
45 | |||
46 | subdir-stubs := $(foreach dir,$(subdirs),$(common-objpfx)$(dir)/stubs) | ||
47 | |||
48 | +# gnu/stubs.h depends (via the subdir 'stubs' targets) on all the .o | ||
49 | +# files in EGLIBC. For bootstrapping a GCC/EGLIBC pair, an empty | ||
50 | +# gnu/stubs.h is good enough. | ||
51 | +ifeq ($(install-bootstrap-headers),yes) | ||
52 | +$(inst_includedir)/gnu/stubs.h: include/stubs-bootstrap.h $(+force) | ||
53 | + $(make-target-directory) | ||
54 | + $(INSTALL_DATA) $< $@ | ||
55 | + | ||
56 | +installed-stubs = | ||
57 | +else | ||
58 | ifndef abi-variants | ||
59 | installed-stubs = $(inst_includedir)/gnu/stubs.h | ||
60 | else | ||
61 | @@ -177,6 +196,7 @@ | ||
62 | |||
63 | install-others-nosubdir: $(installed-stubs) | ||
64 | endif | ||
65 | +endif | ||
66 | |||
67 | |||
68 | # Since stubs.h is never needed when building the library, we simplify the | ||
69 | Index: git/include/stubs-bootstrap.h | ||
70 | =================================================================== | ||
71 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
72 | +++ git/include/stubs-bootstrap.h 2014-08-27 18:35:19.340070587 +0000 | ||
73 | @@ -0,0 +1,12 @@ | ||
74 | +/* Placeholder stubs.h file for bootstrapping. | ||
75 | + | ||
76 | + When bootstrapping a GCC/EGLIBC pair, GCC requires that the EGLIBC | ||
77 | + headers be installed, but we can't fully build EGLIBC without that | ||
78 | + GCC. So we run the command: | ||
79 | + | ||
80 | + make install-headers install-bootstrap-headers=yes | ||
81 | + | ||
82 | + to install the headers GCC needs, but avoid building certain | ||
83 | + difficult headers. The <gnu/stubs.h> header depends, via the | ||
84 | + EGLIBC subdir 'stubs' make targets, on every .o file in EGLIBC, but | ||
85 | + an empty stubs.h like this will do fine for GCC. */ | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-install-pic-archives.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-install-pic-archives.patch new file mode 100644 index 0000000..9a31255 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-install-pic-archives.patch | |||
@@ -0,0 +1,109 @@ | |||
1 | 2008-02-07 Joseph Myers <joseph@codesourcery.com> | ||
2 | |||
3 | * Makerules (install-extras, install-map): New variables. | ||
4 | (installed-libcs): Add libc_pic.a. | ||
5 | (install-lib): Include _pic.a files for versioned shared | ||
6 | libraries. | ||
7 | (install-map-nosubdir, install-extras-nosubdir): Add rules for | ||
8 | installing extra files. | ||
9 | (install-no-libc.a-nosubdir): Depend on install-map-nosubdir and | ||
10 | install-extras-nosubdir. | ||
11 | |||
12 | |||
13 | 2008-04-01 Maxim Kuvyrkov <maxim@codesourcery.com> | ||
14 | |||
15 | * Makerules (install-lib): Don't install libpthread_pic.a. | ||
16 | (install-map): Don't install libpthread_pic.map. | ||
17 | |||
18 | Upstream-Status: Pending | ||
19 | |||
20 | Index: git/Makerules | ||
21 | =================================================================== | ||
22 | --- git.orig/Makerules 2014-08-27 18:49:22.552070587 +0000 | ||
23 | +++ git/Makerules 2014-08-27 18:49:27.308070587 +0000 | ||
24 | @@ -612,6 +631,9 @@ | ||
25 | $(common-objpfx)libc.so: $(common-objpfx)libc.map | ||
26 | endif | ||
27 | common-generated += libc.so libc_pic.os | ||
28 | +ifndef subdir | ||
29 | +install-extras := soinit.o sofini.o | ||
30 | +endif | ||
31 | ifdef libc.so-version | ||
32 | $(common-objpfx)libc.so$(libc.so-version): $(common-objpfx)libc.so | ||
33 | $(make-link) | ||
34 | @@ -834,6 +856,7 @@ | ||
35 | installed-libcs := $(foreach o,$(filter-out .os,$(object-suffixes-for-libc)),\ | ||
36 | $(inst_libdir)/$(patsubst %,$(libtype$o),\ | ||
37 | $(libprefix)$(libc-name))) | ||
38 | +installed-libcs := $(installed-libcs) $(inst_libdir)/libc_pic.a | ||
39 | install: $(installed-libcs) | ||
40 | $(installed-libcs): $(inst_libdir)/lib$(libprefix)%: lib $(+force) | ||
41 | $(make-target-directory) | ||
42 | @@ -862,6 +885,22 @@ | ||
43 | install-lib.so-versioned := $(filter $(versioned), $(install-lib.so)) | ||
44 | install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so)) | ||
45 | |||
46 | +# Install the _pic.a files for versioned libraries, and corresponding | ||
47 | +# .map files. | ||
48 | +# libpthread_pic.a breaks mklibs, so don't install it and its map. | ||
49 | +install-lib := $(install-lib) $(install-lib.so-versioned:%.so=%_pic.a) | ||
50 | +install-lib := $(filter-out libpthread_pic.a,$(install-lib)) | ||
51 | +# Despite having a soname libhurduser and libmachuser do not use symbol | ||
52 | +# versioning, so don't install the corresponding .map files. | ||
53 | +ifeq ($(build-shared),yes) | ||
54 | +install-map := $(patsubst %.so,%.map,\ | ||
55 | + $(foreach L,$(install-lib.so-versioned),$(notdir $L))) | ||
56 | +install-map := $(filter-out libhurduser.map libmachuser.map libpthread.map,$(install-map)) | ||
57 | +ifndef subdir | ||
58 | +install-map := $(install-map) libc.map | ||
59 | +endif | ||
60 | +endif | ||
61 | + | ||
62 | # For versioned libraries, we install three files: | ||
63 | # $(inst_libdir)/libfoo.so -- for linking, symlink or ld script | ||
64 | # $(inst_slibdir)/libfoo.so.NN -- for loading by SONAME, symlink | ||
65 | @@ -1103,9 +1142,22 @@ | ||
66 | endif # headers-nonh | ||
67 | endif # headers | ||
68 | |||
69 | +ifdef install-map | ||
70 | +$(addprefix $(inst_libdir)/,$(patsubst lib%.map,lib%_pic.map,$(install-map))): \ | ||
71 | + $(inst_libdir)/lib%_pic.map: $(common-objpfx)lib%.map $(+force) | ||
72 | + $(do-install) | ||
73 | +endif | ||
74 | + | ||
75 | +ifdef install-extras | ||
76 | +$(addprefix $(inst_libdir)/libc_pic/,$(install-extras)): \ | ||
77 | + $(inst_libdir)/libc_pic/%.o: $(elfobjdir)/%.os $(+force) | ||
78 | + $(do-install) | ||
79 | +endif | ||
80 | + | ||
81 | .PHONY: install-bin-nosubdir install-bin-script-nosubdir \ | ||
82 | install-rootsbin-nosubdir install-sbin-nosubdir install-lib-nosubdir \ | ||
83 | - install-data-nosubdir install-headers-nosubdir | ||
84 | + install-data-nosubdir install-headers-nosubdir install-map-nosubdir \ | ||
85 | + install-extras-nosubdir | ||
86 | install-bin-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin)) | ||
87 | install-bin-script-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin-script)) | ||
88 | install-rootsbin-nosubdir: \ | ||
89 | @@ -1118,6 +1170,10 @@ | ||
90 | install-headers-nosubdir: $(addprefix $(inst_includedir)/,$(headers)) | ||
91 | install-others-nosubdir: $(install-others) | ||
92 | install-others-programs-nosubdir: $(install-others-programs) | ||
93 | +install-map-nosubdir: $(addprefix $(inst_libdir)/,\ | ||
94 | + $(patsubst lib%.map,lib%_pic.map,$(install-map))) | ||
95 | +install-extras-nosubdir: $(addprefix $(inst_libdir)/libc_pic/,\ | ||
96 | + $(install-extras)) | ||
97 | |||
98 | # We need all the `-nosubdir' targets so that `install' in the parent | ||
99 | # doesn't depend on several things which each iterate over the subdirs. | ||
100 | @@ -1127,7 +1183,8 @@ | ||
101 | |||
102 | .PHONY: install install-no-libc.a-nosubdir | ||
103 | install-no-libc.a-nosubdir: install-headers-nosubdir install-data-nosubdir \ | ||
104 | - install-lib-nosubdir install-others-nosubdir | ||
105 | + install-lib-nosubdir install-others-nosubdir \ | ||
106 | + install-map-nosubdir install-extras-nosubdir | ||
107 | ifeq ($(build-programs),yes) | ||
108 | install-no-libc.a-nosubdir: install-bin-nosubdir install-bin-script-nosubdir \ | ||
109 | install-rootsbin-nosubdir install-sbin-nosubdir \ | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-ppc8xx-cache-line-workaround.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-ppc8xx-cache-line-workaround.patch new file mode 100644 index 0000000..bb83d6d --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-ppc8xx-cache-line-workaround.patch | |||
@@ -0,0 +1,68 @@ | |||
1 | 2007-06-13 Nathan Sidwell <nathan@codesourcery.com> | ||
2 | Mark Shinwell <shinwell@codesourcery.com> | ||
3 | |||
4 | * sysdeps/unix/sysv/linux/powerpc/libc-start.c | ||
5 | (__libc_start_main): Detect 8xx parts and clear | ||
6 | __cache_line_size if detected. | ||
7 | * sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c | ||
8 | (DL_PLATFORM_AUXV): Likewise. | ||
9 | |||
10 | Upstream-Status: Pending | ||
11 | |||
12 | Index: git/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c | ||
13 | =================================================================== | ||
14 | --- git.orig/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c 2014-08-27 18:49:23.996070587 +0000 | ||
15 | +++ git/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c 2014-08-27 18:49:27.332070587 +0000 | ||
16 | @@ -24,9 +24,21 @@ | ||
17 | /* Scan the Aux Vector for the "Data Cache Block Size" entry. If found | ||
18 | verify that the static extern __cache_line_size is defined by checking | ||
19 | for not NULL. If it is defined then assign the cache block size | ||
20 | - value to __cache_line_size. */ | ||
21 | + value to __cache_line_size. This is used by memset to | ||
22 | + optimize setting to zero. We have to detect 8xx processors, which | ||
23 | + have buggy dcbz implementations that cannot report page faults | ||
24 | + correctly. That requires reading SPR, which is a privileged | ||
25 | + operation. Fortunately 2.2.18 and later emulates PowerPC mfspr | ||
26 | + reads from the PVR register. */ | ||
27 | #define DL_PLATFORM_AUXV \ | ||
28 | case AT_DCACHEBSIZE: \ | ||
29 | + if (__LINUX_KERNEL_VERSION >= 0x020218) \ | ||
30 | + { \ | ||
31 | + unsigned pvr = 0; \ | ||
32 | + asm ("mfspr %0, 287" : "=r" (pvr)); \ | ||
33 | + if ((pvr & 0xffff0000) == 0x00500000) \ | ||
34 | + break; \ | ||
35 | + } \ | ||
36 | __cache_line_size = av->a_un.a_val; \ | ||
37 | break; | ||
38 | |||
39 | Index: git/sysdeps/unix/sysv/linux/powerpc/libc-start.c | ||
40 | =================================================================== | ||
41 | --- git.orig/sysdeps/unix/sysv/linux/powerpc/libc-start.c 2014-08-27 18:49:23.996070587 +0000 | ||
42 | +++ git/sysdeps/unix/sysv/linux/powerpc/libc-start.c 2014-08-27 18:49:27.332070587 +0000 | ||
43 | @@ -68,11 +68,24 @@ | ||
44 | rtld_fini = NULL; | ||
45 | } | ||
46 | |||
47 | - /* Initialize the __cache_line_size variable from the aux vector. */ | ||
48 | + /* Initialize the __cache_line_size variable from the aux vector. | ||
49 | + This is used by memset to optimize setting to zero. We have to | ||
50 | + detect 8xx processors, which have buggy dcbz implementations that | ||
51 | + cannot report page faults correctly. That requires reading SPR, | ||
52 | + which is a privileged operation. Fortunately 2.2.18 and later | ||
53 | + emulates PowerPC mfspr reads from the PVR register. */ | ||
54 | for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av) | ||
55 | switch (av->a_type) | ||
56 | { | ||
57 | case AT_DCACHEBSIZE: | ||
58 | + if (__LINUX_KERNEL_VERSION >= 0x020218) | ||
59 | + { | ||
60 | + unsigned pvr = 0; | ||
61 | + | ||
62 | + asm ("mfspr %0, 287" : "=r" (pvr) :); | ||
63 | + if ((pvr & 0xffff0000) == 0x00500000) | ||
64 | + break; | ||
65 | + } | ||
66 | __cache_line_size = av->a_un.a_val; | ||
67 | break; | ||
68 | } | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-resolv-dynamic.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-resolv-dynamic.patch new file mode 100644 index 0000000..a73bceb --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-resolv-dynamic.patch | |||
@@ -0,0 +1,54 @@ | |||
1 | cherry-picked from http://www.eglibc.org/archives/patches/msg00772.html | ||
2 | |||
3 | It hasnt yet been merged into glibc | ||
4 | |||
5 | Signed-off-by: Khem Raj | ||
6 | |||
7 | Upstream-Status: Pending | ||
8 | |||
9 | Index: git/resolv/res_libc.c | ||
10 | =================================================================== | ||
11 | --- git.orig/resolv/res_libc.c 2014-08-27 18:35:15.492070587 +0000 | ||
12 | +++ git/resolv/res_libc.c 2014-08-27 18:35:19.204070587 +0000 | ||
13 | @@ -22,12 +22,13 @@ | ||
14 | #include <arpa/nameser.h> | ||
15 | #include <resolv.h> | ||
16 | #include <bits/libc-lock.h> | ||
17 | - | ||
18 | +#include <sys/stat.h> | ||
19 | |||
20 | /* The following bit is copied from res_data.c (where it is #ifdef'ed | ||
21 | out) since res_init() should go into libc.so but the rest of that | ||
22 | file should not. */ | ||
23 | |||
24 | +__libc_lock_define_initialized (static, lock); | ||
25 | extern unsigned long long int __res_initstamp attribute_hidden; | ||
26 | /* We have atomic increment operations on 64-bit platforms. */ | ||
27 | #if __WORDSIZE == 64 | ||
28 | @@ -35,7 +36,6 @@ | ||
29 | # define atomicincunlock(lock) (void) 0 | ||
30 | # define atomicinc(var) catomic_increment (&(var)) | ||
31 | #else | ||
32 | -__libc_lock_define_initialized (static, lock); | ||
33 | # define atomicinclock(lock) __libc_lock_lock (lock) | ||
34 | # define atomicincunlock(lock) __libc_lock_unlock (lock) | ||
35 | # define atomicinc(var) ++var | ||
36 | @@ -94,7 +94,18 @@ | ||
37 | int | ||
38 | __res_maybe_init (res_state resp, int preinit) | ||
39 | { | ||
40 | + static time_t last_mtime; | ||
41 | + struct stat statbuf; | ||
42 | + int ret; | ||
43 | + | ||
44 | if (resp->options & RES_INIT) { | ||
45 | + ret = stat (_PATH_RESCONF, &statbuf); | ||
46 | + __libc_lock_lock (lock); | ||
47 | + if ((ret == 0) && (last_mtime != statbuf.st_mtime)) { | ||
48 | + last_mtime = statbuf.st_mtime; | ||
49 | + atomicinc (__res_initstamp); | ||
50 | + } | ||
51 | + __libc_lock_unlock (lock); | ||
52 | if (__res_initstamp != resp->_u._ext.initstamp) { | ||
53 | if (resp->nscount > 0) | ||
54 | __res_iclose (resp, true); | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-sh4-fpscr_values.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-sh4-fpscr_values.patch new file mode 100644 index 0000000..bfb813e --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-sh4-fpscr_values.patch | |||
@@ -0,0 +1,42 @@ | |||
1 | 2010-09-29 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> | ||
2 | Andrew Stubbs <ams@codesourcery.com> | ||
3 | |||
4 | Resolve SH's __fpscr_values to symbol in libc.so. | ||
5 | |||
6 | * sysdeps/sh/sh4/fpu/fpu_control.h: Add C++ __set_fpscr prototype. | ||
7 | * sysdeps/unix/sysv/linux/sh/Versions (GLIBC_2.2): Add __fpscr_values. | ||
8 | * sysdeps/unix/sysv/linux/sh/sysdep.S (___fpscr_values): New constant. | ||
9 | |||
10 | Upstream-Status: Pending | ||
11 | |||
12 | Index: git/sysdeps/unix/sysv/linux/sh/sysdep.S | ||
13 | =================================================================== | ||
14 | --- git.orig/sysdeps/unix/sysv/linux/sh/sysdep.S 2014-08-27 18:49:24.036070587 +0000 | ||
15 | +++ git/sysdeps/unix/sysv/linux/sh/sysdep.S 2014-08-27 18:49:27.332070587 +0000 | ||
16 | @@ -30,3 +30,14 @@ | ||
17 | |||
18 | #define __syscall_error __syscall_error_1 | ||
19 | #include <sysdeps/unix/sh/sysdep.S> | ||
20 | + | ||
21 | + .data | ||
22 | + .align 3 | ||
23 | + .globl ___fpscr_values | ||
24 | + .type ___fpscr_values, @object | ||
25 | + .size ___fpscr_values, 8 | ||
26 | +___fpscr_values: | ||
27 | + .long 0 | ||
28 | + .long 0x80000 | ||
29 | +weak_alias (___fpscr_values, __fpscr_values) | ||
30 | + | ||
31 | Index: git/sysdeps/unix/sysv/linux/sh/Versions | ||
32 | =================================================================== | ||
33 | --- git.orig/sysdeps/unix/sysv/linux/sh/Versions 2014-08-27 18:49:24.028070587 +0000 | ||
34 | +++ git/sysdeps/unix/sysv/linux/sh/Versions 2014-08-27 18:49:27.332070587 +0000 | ||
35 | @@ -2,6 +2,7 @@ | ||
36 | GLIBC_2.2 { | ||
37 | # functions used in other libraries | ||
38 | __xstat64; __fxstat64; __lxstat64; | ||
39 | + __fpscr_values; | ||
40 | |||
41 | # a* | ||
42 | alphasort64; | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-use-option-groups.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-use-option-groups.patch new file mode 100644 index 0000000..40c7832 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc-use-option-groups.patch | |||
@@ -0,0 +1,16577 @@ | |||
1 | Forward port eglibc options groups support | ||
2 | |||
3 | Upstream-Status: Pending | ||
4 | |||
5 | Index: git/argp/argp-fmtstream.c | ||
6 | =================================================================== | ||
7 | --- git.orig/argp/argp-fmtstream.c 2014-08-29 20:00:42.976070587 -0700 | ||
8 | +++ git/argp/argp-fmtstream.c 2014-08-29 20:01:15.188070587 -0700 | ||
9 | @@ -42,6 +42,7 @@ | ||
10 | #ifdef _LIBC | ||
11 | # include <wchar.h> | ||
12 | # include <libio/libioP.h> | ||
13 | +# include <gnu/option-groups.h> | ||
14 | # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) | ||
15 | #endif | ||
16 | |||
17 | @@ -100,7 +101,11 @@ | ||
18 | __argp_fmtstream_update (fs); | ||
19 | if (fs->p > fs->buf) | ||
20 | { | ||
21 | +#ifdef _LIBC | ||
22 | __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); | ||
23 | +#else | ||
24 | + fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); | ||
25 | +#endif | ||
26 | } | ||
27 | free (fs->buf); | ||
28 | free (fs); | ||
29 | @@ -145,9 +150,17 @@ | ||
30 | size_t i; | ||
31 | for (i = 0; i < pad; i++) | ||
32 | { | ||
33 | +#ifdef _LIBC | ||
34 | if (_IO_fwide (fs->stream, 0) > 0) | ||
35 | - putwc_unlocked (L' ', fs->stream); | ||
36 | + { | ||
37 | +#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
38 | + putwc_unlocked (L' ', fs->stream); | ||
39 | +#else | ||
40 | + abort (); | ||
41 | +#endif | ||
42 | + } | ||
43 | else | ||
44 | +#endif | ||
45 | putc_unlocked (' ', fs->stream); | ||
46 | } | ||
47 | } | ||
48 | @@ -308,9 +321,17 @@ | ||
49 | *nl++ = ' '; | ||
50 | else | ||
51 | for (i = 0; i < fs->wmargin; ++i) | ||
52 | +#ifdef _LIBC | ||
53 | if (_IO_fwide (fs->stream, 0) > 0) | ||
54 | - putwc_unlocked (L' ', fs->stream); | ||
55 | + { | ||
56 | +#ifdef OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
57 | + putwc_unlocked (L' ', fs->stream); | ||
58 | +#else | ||
59 | + abort (); | ||
60 | +#endif | ||
61 | + } | ||
62 | else | ||
63 | +#endif | ||
64 | putc_unlocked (' ', fs->stream); | ||
65 | |||
66 | /* Copy the tail of the original buffer into the current buffer | ||
67 | Index: git/argp/argp-help.c | ||
68 | =================================================================== | ||
69 | --- git.orig/argp/argp-help.c 2014-08-29 20:00:42.976070587 -0700 | ||
70 | +++ git/argp/argp-help.c 2014-08-29 20:01:15.188070587 -0700 | ||
71 | @@ -51,6 +51,7 @@ | ||
72 | #ifdef _LIBC | ||
73 | # include <../libio/libioP.h> | ||
74 | # include <wchar.h> | ||
75 | +# include <gnu/option-groups.h> | ||
76 | #endif | ||
77 | |||
78 | #ifndef _ | ||
79 | @@ -1702,7 +1703,7 @@ | ||
80 | } | ||
81 | |||
82 | char * | ||
83 | -__argp_short_program_name (void) | ||
84 | +(__argp_short_program_name) (void) | ||
85 | { | ||
86 | # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME | ||
87 | return program_invocation_short_name; | ||
88 | @@ -1873,9 +1874,17 @@ | ||
89 | #endif | ||
90 | } | ||
91 | |||
92 | +#ifdef _LIBC | ||
93 | if (_IO_fwide (stream, 0) > 0) | ||
94 | - putwc_unlocked (L'\n', stream); | ||
95 | + { | ||
96 | +#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
97 | + putwc_unlocked (L'\n', stream); | ||
98 | +#else | ||
99 | + abort (); | ||
100 | +#endif | ||
101 | + } | ||
102 | else | ||
103 | +#endif | ||
104 | putc_unlocked ('\n', stream); | ||
105 | |||
106 | #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) | ||
107 | Index: git/argp/argp-namefrob.h | ||
108 | =================================================================== | ||
109 | --- git.orig/argp/argp-namefrob.h 2014-08-29 20:00:42.976070587 -0700 | ||
110 | +++ git/argp/argp-namefrob.h 2014-08-29 20:01:15.192070587 -0700 | ||
111 | @@ -76,10 +76,12 @@ | ||
112 | #undef __argp_fmtstream_wmargin | ||
113 | #define __argp_fmtstream_wmargin argp_fmtstream_wmargin | ||
114 | |||
115 | +#if 0 | ||
116 | #include "mempcpy.h" | ||
117 | #include "strcase.h" | ||
118 | #include "strchrnul.h" | ||
119 | #include "strndup.h" | ||
120 | +#endif | ||
121 | |||
122 | /* normal libc functions we call */ | ||
123 | #undef __flockfile | ||
124 | Index: git/argp/Makefile | ||
125 | =================================================================== | ||
126 | --- git.orig/argp/Makefile 2014-08-29 20:00:42.976070587 -0700 | ||
127 | +++ git/argp/Makefile 2014-08-29 20:01:15.192070587 -0700 | ||
128 | @@ -18,6 +18,8 @@ | ||
129 | # | ||
130 | # Makefile for argp. | ||
131 | # | ||
132 | +include ../option-groups.mak | ||
133 | + | ||
134 | subdir := argp | ||
135 | |||
136 | include ../Makeconfig | ||
137 | Index: git/catgets/Makefile | ||
138 | =================================================================== | ||
139 | --- git.orig/catgets/Makefile 2014-08-29 20:00:43.008070587 -0700 | ||
140 | +++ git/catgets/Makefile 2014-08-29 20:01:15.192070587 -0700 | ||
141 | @@ -22,20 +22,23 @@ | ||
142 | |||
143 | include ../Makeconfig | ||
144 | |||
145 | +include ../option-groups.mak | ||
146 | + | ||
147 | headers = nl_types.h | ||
148 | -routines = catgets open_catalog | ||
149 | -others = gencat | ||
150 | -install-bin = gencat | ||
151 | -extra-objs = $(gencat-modules:=.o) | ||
152 | +routines-$(OPTION_EGLIBC_CATGETS) := catgets open_catalog | ||
153 | +others-$(OPTION_EGLIBC_CATGETS) := gencat | ||
154 | +install-bin-$(OPTION_EGLIBC_CATGETS) := gencat | ||
155 | +extra-objs-$(OPTION_EGLIBC_CATGETS) := $(gencat-modules:=.o) | ||
156 | |||
157 | -tests = tst-catgets | ||
158 | -test-srcs = test-gencat | ||
159 | +tests-$(OPTION_EGLIBC_CATGETS) := tst-catgets | ||
160 | +test-srcs-$(OPTION_EGLIBC_CATGETS) := test-gencat | ||
161 | |||
162 | +ifeq (y,$(OPTION_EGLIBC_CATGETS)) | ||
163 | ifeq ($(run-built-tests),yes) | ||
164 | tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \ | ||
165 | $(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out | ||
166 | endif | ||
167 | - | ||
168 | +endif | ||
169 | gencat-modules = xmalloc | ||
170 | |||
171 | # To find xmalloc.c | ||
172 | Index: git/crypt/crypt-entry.c | ||
173 | =================================================================== | ||
174 | --- git.orig/crypt/crypt-entry.c 2014-08-29 20:00:43.028070587 -0700 | ||
175 | +++ git/crypt/crypt-entry.c 2014-08-29 20:01:15.192070587 -0700 | ||
176 | @@ -27,6 +27,7 @@ | ||
177 | #include <stdio.h> | ||
178 | #endif | ||
179 | #include <string.h> | ||
180 | +#include <gnu/option-groups.h> | ||
181 | #include <errno.h> | ||
182 | #include <fips-private.h> | ||
183 | |||
184 | @@ -76,9 +77,11 @@ | ||
185 | const char *salt; | ||
186 | struct crypt_data * __restrict data; | ||
187 | { | ||
188 | +#if __OPTION_EGLIBC_CRYPT_UFC | ||
189 | ufc_long res[4]; | ||
190 | char ktab[9]; | ||
191 | ufc_long xx = 25; /* to cope with GCC long long compiler bugs */ | ||
192 | +#endif /*__OPTION_EGLIBC_CRYPT_UFC*/ | ||
193 | |||
194 | #ifdef _LIBC | ||
195 | /* Try to find out whether we have to use MD5 encryption replacement. */ | ||
196 | @@ -105,6 +108,7 @@ | ||
197 | sizeof (struct crypt_data)); | ||
198 | #endif | ||
199 | |||
200 | +#if __OPTION_EGLIBC_CRYPT_UFC | ||
201 | /* | ||
202 | * Hack DES tables according to salt | ||
203 | */ | ||
204 | @@ -144,6 +148,10 @@ | ||
205 | */ | ||
206 | _ufc_output_conversion_r (res[0], res[1], salt, data); | ||
207 | return data->crypt_3_buf; | ||
208 | +#else /* __OPTION_EGLIBC_CRYPT_UFC */ | ||
209 | + __set_errno (ENOSYS); | ||
210 | + return NULL; | ||
211 | +#endif /* __OPTION_EGLIBC_CRYPT_UFC */ | ||
212 | } | ||
213 | weak_alias (__crypt_r, crypt_r) | ||
214 | |||
215 | @@ -168,7 +176,12 @@ | ||
216 | return __sha512_crypt (key, salt); | ||
217 | #endif | ||
218 | |||
219 | +#if __OPTION_EGLIBC_CRYPT_UFC | ||
220 | return __crypt_r (key, salt, &_ufc_foobar); | ||
221 | +#else /* __OPTION_EGLIBC_CRYPT_UFC */ | ||
222 | + __set_errno (ENOSYS); | ||
223 | + return NULL; | ||
224 | +#endif /* __OPTION_EGLIBC_CRYPT_UFC */ | ||
225 | } | ||
226 | |||
227 | |||
228 | Index: git/crypt/Makefile | ||
229 | =================================================================== | ||
230 | --- git.orig/crypt/Makefile 2014-08-29 20:00:43.024070587 -0700 | ||
231 | +++ git/crypt/Makefile 2014-08-29 20:01:15.192070587 -0700 | ||
232 | @@ -18,21 +18,25 @@ | ||
233 | # | ||
234 | # Sub-makefile for crypt() portion of the library. | ||
235 | # | ||
236 | +include ../option-groups.mak | ||
237 | + | ||
238 | subdir := crypt | ||
239 | |||
240 | include ../Makeconfig | ||
241 | |||
242 | headers := crypt.h | ||
243 | |||
244 | -extra-libs := libcrypt | ||
245 | -extra-libs-others := $(extra-libs) | ||
246 | +extra-libs-$(OPTION_EGLIBC_CRYPT) := libcrypt | ||
247 | +extra-libs-others-y := $(extra-libs-y) | ||
248 | |||
249 | -libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \ | ||
250 | - crypt_util | ||
251 | +libcrypt-routines :=crypt-entry md5-crypt sha256-crypt sha512-crypt crypt_common | ||
252 | +libcrypt-routines-$(OPTION_EGLIBC_CRYPT_UFC) := crypt crypt_util | ||
253 | +libcrypt-routines += $(libcrypt-routines-y) | ||
254 | |||
255 | -tests := cert md5c-test sha256c-test sha512c-test badsalttest | ||
256 | +tests-$(OPTION_EGLIBC_CRYPT) := md5c-test sha256c-test sha512c-test badsalttest | ||
257 | +tests-$(OPTION_EGLIBC_CRYPT_UFC) += cert | ||
258 | |||
259 | -ifeq ($(crypt-in-libc),yes) | ||
260 | +ifeq ($(crypt-in-libc)$(OPTION_EGLIBC_CRYPT),yesy) | ||
261 | routines += $(libcrypt-routines) | ||
262 | endif | ||
263 | |||
264 | @@ -44,7 +48,7 @@ | ||
265 | else | ||
266 | libcrypt-routines += md5 sha256 sha512 | ||
267 | |||
268 | -tests += md5test sha256test sha512test | ||
269 | +tests-$(OPTION_EGLIBC_CRYPT) += md5test sha256test sha512test | ||
270 | |||
271 | # The test md5test-giant uses up to 400 MB of RSS and runs on a fast | ||
272 | # machine over a minute. | ||
273 | @@ -64,8 +68,10 @@ | ||
274 | $(objpfx)sha512test: $(patsubst %, $(objpfx)%.o,$(sha512-routines)) | ||
275 | endif | ||
276 | |||
277 | +ifeq ($(OPTION_EGLIBC_CRYPT),y) | ||
278 | ifeq (yes,$(build-shared)) | ||
279 | $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.so | ||
280 | else | ||
281 | $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.a | ||
282 | endif | ||
283 | +endif # eglibc: OPTION_EGLIBC_CRYPT | ||
284 | Index: git/csu/Makefile | ||
285 | =================================================================== | ||
286 | --- git.orig/csu/Makefile 2014-08-29 20:00:43.032070587 -0700 | ||
287 | +++ git/csu/Makefile 2014-08-29 20:01:15.192070587 -0700 | ||
288 | @@ -22,6 +22,8 @@ | ||
289 | # crtn.o, special "initializer" and "finalizer" files used in the link | ||
290 | # to make the .init and .fini sections work right. | ||
291 | |||
292 | +include ../option-groups.mak | ||
293 | + | ||
294 | subdir := csu | ||
295 | |||
296 | include ../Makeconfig | ||
297 | Index: git/debug/Makefile | ||
298 | =================================================================== | ||
299 | --- git.orig/debug/Makefile 2014-08-29 20:00:43.036070587 -0700 | ||
300 | +++ git/debug/Makefile 2014-08-29 20:01:15.192070587 -0700 | ||
301 | @@ -18,6 +18,8 @@ | ||
302 | # | ||
303 | # Sub-makefile for debug portion of the library. | ||
304 | # | ||
305 | +include ../option-groups.mak | ||
306 | + | ||
307 | subdir := debug | ||
308 | |||
309 | include ../Makeconfig | ||
310 | @@ -27,7 +29,7 @@ | ||
311 | # Note that ptsname_r_chk and getlogin_r are not here, but in | ||
312 | # login/Makefile instead. If that subdir is omitted from the | ||
313 | # build, its _FORTIFY_SOURCE support will be too. | ||
314 | -routines = backtrace backtracesyms backtracesymsfd noophooks \ | ||
315 | +routines = noophooks \ | ||
316 | memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \ | ||
317 | strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \ | ||
318 | sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \ | ||
319 | @@ -36,20 +38,27 @@ | ||
320 | read_chk pread_chk pread64_chk recv_chk recvfrom_chk \ | ||
321 | readlink_chk readlinkat_chk getwd_chk getcwd_chk \ | ||
322 | realpath_chk fread_chk fread_u_chk \ | ||
323 | - wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \ | ||
324 | - wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \ | ||
325 | - wcpncpy_chk \ | ||
326 | - swprintf_chk vswprintf_chk wprintf_chk fwprintf_chk \ | ||
327 | - vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk \ | ||
328 | confstr_chk getgroups_chk ttyname_r_chk \ | ||
329 | - gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \ | ||
330 | - wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \ | ||
331 | - wcstombs_chk asprintf_chk vasprintf_chk dprintf_chk \ | ||
332 | + gethostname_chk getdomainname_chk \ | ||
333 | + asprintf_chk vasprintf_chk dprintf_chk \ | ||
334 | vdprintf_chk obprintf_chk \ | ||
335 | longjmp_chk ____longjmp_chk \ | ||
336 | fdelt_chk poll_chk ppoll_chk \ | ||
337 | stack_chk_fail fortify_fail \ | ||
338 | $(static-only-routines) | ||
339 | +routines-$(OPTION_EGLIBC_BACKTRACE) += backtrace backtracesyms backtracesymsfd | ||
340 | +routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \ | ||
341 | + += wprintf_chk fwprintf_chk \ | ||
342 | + vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk | ||
343 | +routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ | ||
344 | + += wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \ | ||
345 | + wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \ | ||
346 | + wcpncpy_chk \ | ||
347 | + swprintf_chk vswprintf_chk \ | ||
348 | + wcrtomb_chk mbsnrtowcs_chk \ | ||
349 | + wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \ | ||
350 | + wcstombs_chk | ||
351 | + | ||
352 | static-only-routines := warning-nop stack_chk_fail_local | ||
353 | |||
354 | CFLAGS-backtrace.c = -fno-omit-frame-pointer | ||
355 | @@ -129,11 +138,15 @@ | ||
356 | LDFLAGS-tst-backtrace5 = -rdynamic | ||
357 | LDFLAGS-tst-backtrace6 = -rdynamic | ||
358 | |||
359 | -tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \ | ||
360 | - tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \ | ||
361 | - tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \ | ||
362 | - tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \ | ||
363 | - tst-backtrace5 tst-backtrace6 | ||
364 | +tests = tst-longjmp_chk test-strcpy_chk test-stpcpy_chk tst-longjmp_chk2 | ||
365 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
366 | + += tst-chk1 tst-chk2 tst-chk3 tst-lfschk1 tst-lfschk2 tst-lfschk3 | ||
367 | +tests-$(OPTION_EGLIBC_BACKTRACE) \ | ||
368 | + += backtrace-tst tst-backtrace2 tst-backtrace3 tst-backtrace4 \ | ||
369 | + tst-backtrace5 tst-backtrace6 | ||
370 | +ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_EGLIBC_CXX_TESTS)) | ||
371 | +tests += tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 | ||
372 | +endif | ||
373 | |||
374 | tests-ifunc := $(stpcpy_chk strcpy_chk:%=test-%-ifunc) | ||
375 | tests += $(tests-ifunc) | ||
376 | Index: git/debug/segfault.c | ||
377 | =================================================================== | ||
378 | --- git.orig/debug/segfault.c 2014-08-29 20:00:46.280070587 -0700 | ||
379 | +++ git/debug/segfault.c 2014-08-29 20:01:15.192070587 -0700 | ||
380 | @@ -30,6 +30,7 @@ | ||
381 | #include <unistd.h> | ||
382 | #include <_itoa.h> | ||
383 | #include <ldsodefs.h> | ||
384 | +#include <gnu/option-groups.h> | ||
385 | |||
386 | /* This file defines macros to access the content of the sigcontext element | ||
387 | passed up by the signal handler. */ | ||
388 | @@ -91,6 +92,7 @@ | ||
389 | REGISTER_DUMP; | ||
390 | #endif | ||
391 | |||
392 | +#if __OPTION_EGLIBC_BACKTRACE | ||
393 | WRITE_STRING ("\nBacktrace:\n"); | ||
394 | |||
395 | /* Get the backtrace. */ | ||
396 | @@ -113,6 +115,7 @@ | ||
397 | |||
398 | /* Now generate nicely formatted output. */ | ||
399 | __backtrace_symbols_fd (arr + i, cnt - i, fd); | ||
400 | +#endif | ||
401 | |||
402 | #ifdef HAVE_PROC_SELF | ||
403 | /* Now the link map. */ | ||
404 | Index: git/debug/tst-chk1.c | ||
405 | =================================================================== | ||
406 | --- git.orig/debug/tst-chk1.c 2014-08-29 20:00:46.288070587 -0700 | ||
407 | +++ git/debug/tst-chk1.c 2014-08-29 20:01:15.192070587 -0700 | ||
408 | @@ -31,6 +31,7 @@ | ||
409 | #include <sys/select.h> | ||
410 | #include <sys/socket.h> | ||
411 | #include <sys/un.h> | ||
412 | +#include <gnu/option-groups.h> | ||
413 | |||
414 | |||
415 | #define obstack_chunk_alloc malloc | ||
416 | @@ -307,6 +308,7 @@ | ||
417 | snprintf (buf + 8, l0 + 3, "%d", num2); | ||
418 | CHK_FAIL_END | ||
419 | |||
420 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
421 | CHK_FAIL_START | ||
422 | swprintf (wbuf + 8, 3, L"%d", num1); | ||
423 | CHK_FAIL_END | ||
424 | @@ -314,6 +316,7 @@ | ||
425 | CHK_FAIL_START | ||
426 | swprintf (wbuf + 8, l0 + 3, L"%d", num1); | ||
427 | CHK_FAIL_END | ||
428 | +#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ | ||
429 | # endif | ||
430 | |||
431 | memcpy (buf, str1 + 2, l0 + 9); | ||
432 | @@ -381,6 +384,7 @@ | ||
433 | CHK_FAIL_END | ||
434 | #endif | ||
435 | |||
436 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
437 | |||
438 | /* These ops can be done without runtime checking of object size. */ | ||
439 | wmemcpy (wbuf, L"abcdefghij", 10); | ||
440 | @@ -605,6 +609,7 @@ | ||
441 | CHK_FAIL_END | ||
442 | #endif | ||
443 | |||
444 | +#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ | ||
445 | |||
446 | /* Now checks for %n protection. */ | ||
447 | |||
448 | @@ -1192,6 +1197,7 @@ | ||
449 | # endif | ||
450 | #endif | ||
451 | |||
452 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
453 | if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL) | ||
454 | { | ||
455 | assert (MB_CUR_MAX <= 10); | ||
456 | @@ -1348,6 +1354,7 @@ | ||
457 | puts ("cannot set locale"); | ||
458 | ret = 1; | ||
459 | } | ||
460 | +#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ | ||
461 | |||
462 | int fd = posix_openpt (O_RDWR); | ||
463 | if (fd != -1) | ||
464 | Index: git/dlfcn/Makefile | ||
465 | =================================================================== | ||
466 | --- git.orig/dlfcn/Makefile 2014-08-29 20:00:46.312070587 -0700 | ||
467 | +++ git/dlfcn/Makefile 2014-08-29 20:01:15.192070587 -0700 | ||
468 | @@ -15,6 +15,8 @@ | ||
469 | # License along with the GNU C Library; if not, see | ||
470 | # <http://www.gnu.org/licenses/>. | ||
471 | |||
472 | +include ../option-groups.mak | ||
473 | + | ||
474 | subdir := dlfcn | ||
475 | |||
476 | include ../Makeconfig | ||
477 | @@ -36,7 +38,9 @@ | ||
478 | ifeq (yes,$(build-shared)) | ||
479 | tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \ | ||
480 | bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \ | ||
481 | - bug-atexit3 tstatexit bug-dl-leaf | ||
482 | + tstatexit bug-dl-leaf | ||
483 | + | ||
484 | +tests-$(OPTION_EGLIBC_CXX_TESTS) += bug-atexit3 | ||
485 | endif | ||
486 | modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \ | ||
487 | defaultmod2 errmsg1mod modatexit modcxaatexit \ | ||
488 | Index: git/elf/dl-support.c | ||
489 | =================================================================== | ||
490 | --- git.orig/elf/dl-support.c 2014-08-29 20:00:46.384070587 -0700 | ||
491 | +++ git/elf/dl-support.c 2014-08-29 20:01:15.192070587 -0700 | ||
492 | @@ -19,6 +19,7 @@ | ||
493 | /* This file defines some things that for the dynamic linker are defined in | ||
494 | rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */ | ||
495 | |||
496 | +#include <gnu/option-groups.h> | ||
497 | #include <errno.h> | ||
498 | #include <libintl.h> | ||
499 | #include <stdlib.h> | ||
500 | @@ -42,7 +43,9 @@ | ||
501 | const char *_dl_platform; | ||
502 | size_t _dl_platformlen; | ||
503 | |||
504 | +#if __OPTION_EGLIBC_RTLD_DEBUG | ||
505 | int _dl_debug_mask; | ||
506 | +#endif | ||
507 | int _dl_lazy; | ||
508 | ElfW(Addr) _dl_use_load_bias = -2; | ||
509 | int _dl_dynamic_weak; | ||
510 | Index: git/elf/rtld.c | ||
511 | =================================================================== | ||
512 | --- git.orig/elf/rtld.c 2014-08-29 20:01:14.708070587 -0700 | ||
513 | +++ git/elf/rtld.c 2014-08-29 20:01:15.196070587 -0700 | ||
514 | @@ -16,6 +16,7 @@ | ||
515 | License along with the GNU C Library; if not, see | ||
516 | <http://www.gnu.org/licenses/>. */ | ||
517 | |||
518 | +#include <gnu/option-groups.h> | ||
519 | #include <errno.h> | ||
520 | #include <dlfcn.h> | ||
521 | #include <fcntl.h> | ||
522 | @@ -2200,6 +2201,7 @@ | ||
523 | objname, errstring); | ||
524 | } | ||
525 | |||
526 | +#if __OPTION_EGLIBC_RTLD_DEBUG | ||
527 | /* Nonzero if any of the debugging options is enabled. */ | ||
528 | static int any_debug attribute_relro; | ||
529 | |||
530 | @@ -2309,6 +2311,7 @@ | ||
531 | _exit (0); | ||
532 | } | ||
533 | } | ||
534 | +#endif /* __OPTION_EGLIBC_RTLD_DEBUG */ | ||
535 | |||
536 | static void | ||
537 | process_dl_audit (char *str) | ||
538 | @@ -2376,12 +2379,14 @@ | ||
539 | break; | ||
540 | |||
541 | case 5: | ||
542 | +#if __OPTION_EGLIBC_RTLD_DEBUG | ||
543 | /* Debugging of the dynamic linker? */ | ||
544 | if (memcmp (envline, "DEBUG", 5) == 0) | ||
545 | { | ||
546 | process_dl_debug (&envline[6]); | ||
547 | break; | ||
548 | } | ||
549 | +#endif | ||
550 | if (memcmp (envline, "AUDIT", 5) == 0) | ||
551 | process_dl_audit (&envline[6]); | ||
552 | break; | ||
553 | @@ -2490,7 +2495,9 @@ | ||
554 | { | ||
555 | mode = trace; | ||
556 | GLRO(dl_verbose) = 1; | ||
557 | +#if __OPTION_EGLIBC_RTLD_DEBUG | ||
558 | GLRO_dl_debug_mask |= DL_DEBUG_PRELINK; | ||
559 | +#endif | ||
560 | GLRO(dl_trace_prelink) = &envline[17]; | ||
561 | } | ||
562 | break; | ||
563 | @@ -2537,12 +2544,15 @@ | ||
564 | if (__access ("/etc/suid-debug", F_OK) != 0) | ||
565 | { | ||
566 | unsetenv ("MALLOC_CHECK_"); | ||
567 | +#if __OPTION_EGLIBC_RTLD_DEBUG | ||
568 | GLRO_dl_debug_mask = 0; | ||
569 | +#endif | ||
570 | } | ||
571 | |||
572 | if (mode != normal) | ||
573 | _exit (5); | ||
574 | } | ||
575 | +#if __OPTION_EGLIBC_RTLD_DEBUG | ||
576 | /* If we have to run the dynamic linker in debugging mode and the | ||
577 | LD_DEBUG_OUTPUT environment variable is given, we write the debug | ||
578 | messages to this file. */ | ||
579 | @@ -2567,6 +2577,7 @@ | ||
580 | /* We use standard output if opening the file failed. */ | ||
581 | GLRO(dl_debug_fd) = STDOUT_FILENO; | ||
582 | } | ||
583 | +#endif /* __OPTION_EGLIBC_RTLD_DEBUG */ | ||
584 | } | ||
585 | |||
586 | |||
587 | Index: git/extra-lib.mk | ||
588 | =================================================================== | ||
589 | --- git.orig/extra-lib.mk 2014-08-29 20:00:46.544070587 -0700 | ||
590 | +++ git/extra-lib.mk 2014-08-29 20:01:15.196070587 -0700 | ||
591 | @@ -25,7 +25,9 @@ | ||
592 | extra-objs := $(extra-objs) | ||
593 | |||
594 | # The modules that go in $(lib). | ||
595 | -all-$(lib)-routines := $($(lib)-routines) $($(lib)-sysdep_routines) | ||
596 | +all-$(lib)-routines := $($(lib)-routines) \ | ||
597 | + $($(lib)-routines-y) \ | ||
598 | + $($(lib)-sysdep_routines) | ||
599 | |||
600 | # Add each flavor of library to the lists of things to build and install. | ||
601 | install-lib += $(foreach o,$(object-suffixes-$(lib)),$(lib:lib%=$(libtype$o))) | ||
602 | @@ -101,7 +103,7 @@ | ||
603 | endif | ||
604 | |||
605 | # This will define `libof-ROUTINE := LIB' for each of the routines. | ||
606 | -cpp-srcs-left := $($(lib)-routines) $($(lib)-sysdep_routines) | ||
607 | +cpp-srcs-left := $(all-$(lib)-routines) | ||
608 | ifneq (,$(cpp-srcs-left)) | ||
609 | include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) | ||
610 | endif | ||
611 | Index: git/grp/Makefile | ||
612 | =================================================================== | ||
613 | --- git.orig/grp/Makefile 2014-08-29 20:00:46.556070587 -0700 | ||
614 | +++ git/grp/Makefile 2014-08-29 20:01:15.196070587 -0700 | ||
615 | @@ -18,6 +18,8 @@ | ||
616 | # | ||
617 | # Sub-makefile for grp portion of the library. | ||
618 | # | ||
619 | +include ../option-groups.mak | ||
620 | + | ||
621 | subdir := grp | ||
622 | |||
623 | include ../Makeconfig | ||
624 | @@ -29,6 +31,9 @@ | ||
625 | getgrent_r getgrgid_r getgrnam_r fgetgrent_r | ||
626 | |||
627 | tests := testgrp | ||
628 | +ifneq (y,$(OPTION_EGLIBC_NSSWITCH)) | ||
629 | +LDLIBS-testgrp += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs) | ||
630 | +endif | ||
631 | |||
632 | ifeq (yes,$(build-shared)) | ||
633 | test-srcs := tst_fgetgrent | ||
634 | Index: git/hesiod/Makefile | ||
635 | =================================================================== | ||
636 | --- git.orig/hesiod/Makefile 2014-08-29 20:00:46.580070587 -0700 | ||
637 | +++ git/hesiod/Makefile 2014-08-29 20:01:15.196070587 -0700 | ||
638 | @@ -18,12 +18,14 @@ | ||
639 | # | ||
640 | # Sub-makefile for hesiod portion of the library. | ||
641 | # | ||
642 | +include ../option-groups.mak | ||
643 | + | ||
644 | subdir := hesiod | ||
645 | |||
646 | include ../Makeconfig | ||
647 | |||
648 | -extra-libs := libnss_hesiod | ||
649 | -extra-libs-others = $(extra-libs) | ||
650 | +extra-libs-$(OPTION_EGLIBC_INET) += libnss_hesiod | ||
651 | +extra-libs-others-y += $(extra-libs-y) | ||
652 | |||
653 | subdir-dirs = nss_hesiod | ||
654 | vpath %.c nss_hesiod | ||
655 | Index: git/iconv/gconv_db.c | ||
656 | =================================================================== | ||
657 | --- git.orig/iconv/gconv_db.c 2014-08-29 20:00:46.604070587 -0700 | ||
658 | +++ git/iconv/gconv_db.c 2014-08-29 20:01:15.196070587 -0700 | ||
659 | @@ -25,6 +25,7 @@ | ||
660 | #include <sys/param.h> | ||
661 | #include <bits/libc-lock.h> | ||
662 | #include <locale/localeinfo.h> | ||
663 | +#include <gnu/option-groups.h> | ||
664 | |||
665 | #include <dlfcn.h> | ||
666 | #include <gconv_int.h> | ||
667 | @@ -828,9 +829,11 @@ | ||
668 | /* Free all resources if necessary. */ | ||
669 | libc_freeres_fn (free_mem) | ||
670 | { | ||
671 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
672 | /* First free locale memory. This needs to be done before freeing derivations, | ||
673 | as ctype cleanup functions dereference steps arrays which we free below. */ | ||
674 | _nl_locale_subfreeres (); | ||
675 | +#endif | ||
676 | |||
677 | /* finddomain.c has similar problem. */ | ||
678 | extern void _nl_finddomain_subfreeres (void) attribute_hidden; | ||
679 | Index: git/iconv/gconv_trans.c | ||
680 | =================================================================== | ||
681 | --- git.orig/iconv/gconv_trans.c 2014-08-29 20:00:46.612070587 -0700 | ||
682 | +++ git/iconv/gconv_trans.c 2014-08-29 20:01:15.196070587 -0700 | ||
683 | @@ -23,6 +23,7 @@ | ||
684 | #include <stdint.h> | ||
685 | #include <string.h> | ||
686 | #include <stdlib.h> | ||
687 | +#include <gnu/option-groups.h> | ||
688 | |||
689 | #include <bits/libc-lock.h> | ||
690 | #include "gconv_int.h" | ||
691 | @@ -59,6 +60,7 @@ | ||
692 | PTR_DEMANGLE (fct); | ||
693 | #endif | ||
694 | |||
695 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
696 | /* If there is no transliteration information in the locale don't do | ||
697 | anything and return the error. */ | ||
698 | size = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_TAB_SIZE); | ||
699 | @@ -194,6 +196,7 @@ | ||
700 | sorted. */ | ||
701 | break; | ||
702 | } | ||
703 | +#endif | ||
704 | |||
705 | /* One last chance: use the default replacement. */ | ||
706 | if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN) != 0) | ||
707 | Index: git/iconv/iconv_prog.c | ||
708 | =================================================================== | ||
709 | --- git.orig/iconv/iconv_prog.c 2014-08-29 20:00:46.612070587 -0700 | ||
710 | +++ git/iconv/iconv_prog.c 2014-08-29 20:01:15.196070587 -0700 | ||
711 | @@ -35,6 +35,7 @@ | ||
712 | #ifdef _POSIX_MAPPED_FILES | ||
713 | # include <sys/mman.h> | ||
714 | #endif | ||
715 | +#include <gnu/option-groups.h> | ||
716 | #include <charmap.h> | ||
717 | #include <gconv_int.h> | ||
718 | #include "iconv_prog.h" | ||
719 | @@ -221,10 +222,17 @@ | ||
720 | bool to_wrong = | ||
721 | (iconv_open (to_code, "UTF-8") == (iconv_t) -1 | ||
722 | && errno == EINVAL); | ||
723 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
724 | const char *from_pretty = | ||
725 | (from_code[0] ? from_code : nl_langinfo (CODESET)); | ||
726 | const char *to_pretty = | ||
727 | (orig_to_code[0] ? orig_to_code : nl_langinfo (CODESET)); | ||
728 | +#else | ||
729 | + const char *from_pretty = | ||
730 | + (from_code[0] ? from_code : "ANSI_X3.4-1968"); | ||
731 | + const char *to_pretty = | ||
732 | + (orig_to_code[0] ? orig_to_code : "ANSI_X3.4-1968"); | ||
733 | +#endif | ||
734 | |||
735 | if (from_wrong) | ||
736 | { | ||
737 | Index: git/iconv/Makefile | ||
738 | =================================================================== | ||
739 | --- git.orig/iconv/Makefile 2014-08-29 20:00:46.600070587 -0700 | ||
740 | +++ git/iconv/Makefile 2014-08-29 20:01:15.196070587 -0700 | ||
741 | @@ -18,6 +18,8 @@ | ||
742 | # | ||
743 | # Makefile for iconv. | ||
744 | # | ||
745 | +include ../option-groups.mak | ||
746 | + | ||
747 | subdir := iconv | ||
748 | |||
749 | include ../Makeconfig | ||
750 | @@ -57,6 +59,9 @@ | ||
751 | CPPFLAGS-strtab = -DNOT_IN_libc | ||
752 | CPPFLAGS-charmap = -DNOT_IN_libc | ||
753 | CPPFLAGS-charmap-dir = -DNOT_IN_libc | ||
754 | +ifneq (y,$(OPTION_EGLIBC_SPAWN)) | ||
755 | +CPPFLAGS-charmap-dir.c += -DNO_UNCOMPRESS | ||
756 | +endif | ||
757 | |||
758 | ifeq ($(run-built-tests),yes) | ||
759 | xtests-special += $(objpfx)test-iconvconfig.out | ||
760 | Index: git/iconvdata/Makefile | ||
761 | =================================================================== | ||
762 | --- git.orig/iconvdata/Makefile 2014-08-29 20:00:46.628070587 -0700 | ||
763 | +++ git/iconvdata/Makefile 2014-08-29 20:01:15.196070587 -0700 | ||
764 | @@ -18,12 +18,15 @@ | ||
765 | # | ||
766 | # Makefile for iconv data and code. | ||
767 | # | ||
768 | +include ../option-groups.mak | ||
769 | + | ||
770 | subdir := iconvdata | ||
771 | |||
772 | include ../Makeconfig | ||
773 | |||
774 | # Names of all the shared objects which implement the transformations. | ||
775 | -modules := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \ | ||
776 | +modules-$(OPTION_EGLIBC_CHARSETS) \ | ||
777 | + := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \ | ||
778 | ISO8859-6 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-10 \ | ||
779 | ISO8859-11 ISO8859-13 ISO8859-14 ISO8859-15 ISO8859-16 \ | ||
780 | T.61 ISO_6937 SJIS KOI-8 HP-ROMAN8 HP-ROMAN9 EBCDIC-AT-DE \ | ||
781 | @@ -63,11 +66,13 @@ | ||
782 | MAC-CENTRALEUROPE KOI8-RU ISO8859-9E \ | ||
783 | CP770 CP771 CP772 CP773 CP774 | ||
784 | |||
785 | -modules.so := $(addsuffix .so, $(modules)) | ||
786 | +modules.so := $(addsuffix .so, $(modules-y)) | ||
787 | |||
788 | ifeq (yes,$(build-shared)) | ||
789 | tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ | ||
790 | - tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 | ||
791 | + tst-iconv6 bug-iconv5 bug-iconv8 bug-iconv9 | ||
792 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) += bug-iconv6 tst-iconv7 | ||
793 | + | ||
794 | ifeq ($(have-thread-library),yes) | ||
795 | tests += bug-iconv3 | ||
796 | endif | ||
797 | @@ -130,13 +135,13 @@ | ||
798 | # Rule to generate the shared objects. | ||
799 | charmaps = ../localedata/charmaps | ||
800 | -include $(objpfx)iconv-rules | ||
801 | -extra-modules-left := $(modules) | ||
802 | +extra-modules-left := $(modules-y) | ||
803 | include extra-module.mk | ||
804 | |||
805 | |||
806 | extra-objs += $(modules.so) | ||
807 | -install-others = $(addprefix $(inst_gconvdir)/, $(modules.so)) \ | ||
808 | - $(inst_gconvdir)/gconv-modules | ||
809 | +install-others-y += $(addprefix $(inst_gconvdir)/, $(modules.so)) | ||
810 | +install-others-$(OPTION_EGLIBC_CHARSETS) += $(inst_gconvdir)/gconv-modules | ||
811 | |||
812 | # We can build the conversion tables for numerous charsets automatically. | ||
813 | |||
814 | @@ -204,7 +209,7 @@ | ||
815 | ifndef avoid-generated | ||
816 | $(objpfx)iconv-rules: Makefile | ||
817 | $(make-target-directory) | ||
818 | - { echo $(filter-out lib%, $(modules)); \ | ||
819 | + { echo $(filter-out lib%, $(modules-y)); \ | ||
820 | echo 8bit $(gen-8bit-modules); \ | ||
821 | echo 8bit-gap $(gen-8bit-gap-modules); } | \ | ||
822 | LC_ALL=C \ | ||
823 | @@ -247,7 +252,7 @@ | ||
824 | $(do-install-program) | ||
825 | $(inst_gconvdir)/gconv-modules: gconv-modules $(+force) | ||
826 | $(do-install) | ||
827 | -ifeq (no,$(cross-compiling)) | ||
828 | +# eglibc: ifeq (no,$(cross-compiling)) | ||
829 | # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary | ||
830 | # if this libc has more gconv modules than the previously installed one. | ||
831 | if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \ | ||
832 | @@ -256,9 +261,9 @@ | ||
833 | $(common-objpfx)iconv/iconvconfig \ | ||
834 | $(addprefix --prefix=,$(install_root)); \ | ||
835 | fi | ||
836 | -else | ||
837 | - @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache' | ||
838 | -endif | ||
839 | +# eglibc: else | ||
840 | +# eglibc: @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache' | ||
841 | +# eglibc: endif | ||
842 | |||
843 | endif # build-shared = yes | ||
844 | |||
845 | Index: git/include/netdb.h | ||
846 | =================================================================== | ||
847 | --- git.orig/include/netdb.h 2014-08-29 20:00:47.152070587 -0700 | ||
848 | +++ git/include/netdb.h 2014-08-29 20:01:15.196070587 -0700 | ||
849 | @@ -232,6 +232,10 @@ | ||
850 | (const char *name, int af, struct hostent *host, \ | ||
851 | char *buffer, size_t buflen, int *errnop, \ | ||
852 | int *h_errnop); \ | ||
853 | +extern enum nss_status _nss_ ## service ## _gethostbyname3_r \ | ||
854 | + (const char *name, int af, struct hostent *result, \ | ||
855 | + char *buffer, size_t buflen, int *errnop, \ | ||
856 | + int *h_errnop, int32_t *ttlp, char **canonp); \ | ||
857 | extern enum nss_status _nss_ ## service ## _gethostbyname_r \ | ||
858 | (const char *name, struct hostent *host, char *buffer, \ | ||
859 | size_t buflen, int *errnop, int *h_errnop); \ | ||
860 | Index: git/inet/Makefile | ||
861 | =================================================================== | ||
862 | --- git.orig/inet/Makefile 2014-08-29 20:00:47.176070587 -0700 | ||
863 | +++ git/inet/Makefile 2014-08-29 20:01:15.200070587 -0700 | ||
864 | @@ -18,6 +18,8 @@ | ||
865 | # | ||
866 | # Sub-makefile for inet portion of the library. | ||
867 | # | ||
868 | +include ../option-groups.mak | ||
869 | + | ||
870 | subdir := inet | ||
871 | |||
872 | include ../Makeconfig | ||
873 | @@ -27,7 +29,8 @@ | ||
874 | netinet/tcp.h netinet/ip.h $(wildcard arpa/*.h protocols/*.h) \ | ||
875 | aliases.h ifaddrs.h netinet/ip6.h netinet/icmp6.h bits/in.h | ||
876 | |||
877 | -routines := htonl htons \ | ||
878 | +routines-$(OPTION_EGLIBC_INET) \ | ||
879 | + += htonl htons \ | ||
880 | inet_lnaof inet_mkadr \ | ||
881 | inet_netof inet_ntoa inet_net herrno herrno-loc \ | ||
882 | gethstbyad gethstbyad_r gethstbynm gethstbynm2 gethstbynm2_r \ | ||
883 | @@ -41,18 +44,23 @@ | ||
884 | getrpcent_r getrpcbyname_r getrpcbynumber_r \ | ||
885 | ether_aton ether_aton_r ether_hton ether_line \ | ||
886 | ether_ntoa ether_ntoa_r ether_ntoh \ | ||
887 | - rcmd rexec ruserpass \ | ||
888 | getnetgrent_r getnetgrent \ | ||
889 | - getaliasent_r getaliasent getaliasname getaliasname_r \ | ||
890 | - in6_addr getnameinfo if_index ifaddrs inet6_option \ | ||
891 | + in6_addr getnameinfo if_index ifaddrs \ | ||
892 | getipv4sourcefilter setipv4sourcefilter \ | ||
893 | - getsourcefilter setsourcefilter inet6_opt inet6_rth | ||
894 | + getsourcefilter setsourcefilter | ||
895 | +routines-$(OPTION_EGLIBC_RCMD) \ | ||
896 | + += rcmd rexec ruserpass | ||
897 | +routines-$(OPTION_EGLIBC_DB_ALIASES) \ | ||
898 | + += getaliasent_r getaliasent getaliasname getaliasname_r | ||
899 | +routines-$(OPTION_EGLIBC_ADVANCED_INET6) \ | ||
900 | + += inet6_option inet6_opt inet6_rth | ||
901 | |||
902 | -aux := check_pf check_native ifreq | ||
903 | +aux-$(OPTION_EGLIBC_INET) += check_pf check_native ifreq | ||
904 | |||
905 | tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ | ||
906 | - tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \ | ||
907 | + tst-gethnm test-ifaddrs bug-if1 tst-ether_line \ | ||
908 | tst-getni1 tst-getni2 tst-inet6_rth tst-checks | ||
909 | +tests-$(OPTION_EGLIBC_ADVANCED_INET6) += test-inet6_opt | ||
910 | |||
911 | include ../Rules | ||
912 | |||
913 | Index: git/intl/dcigettext.c | ||
914 | =================================================================== | ||
915 | --- git.orig/intl/dcigettext.c 2014-08-29 20:00:47.224070587 -0700 | ||
916 | +++ git/intl/dcigettext.c 2014-08-29 20:01:15.200070587 -0700 | ||
917 | @@ -77,6 +77,10 @@ | ||
918 | #endif | ||
919 | #include "hash-string.h" | ||
920 | |||
921 | +#ifdef _LIBC | ||
922 | +# include <gnu/option-groups.h> | ||
923 | +#endif | ||
924 | + | ||
925 | /* Thread safetyness. */ | ||
926 | #ifdef _LIBC | ||
927 | # include <bits/libc-lock.h> | ||
928 | @@ -449,9 +453,11 @@ | ||
929 | #endif | ||
930 | |||
931 | #ifdef _LIBC | ||
932 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
933 | __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden) | ||
934 | __libc_rwlock_rdlock (__libc_setlocale_lock); | ||
935 | #endif | ||
936 | +#endif | ||
937 | |||
938 | __libc_rwlock_rdlock (_nl_state_lock); | ||
939 | |||
940 | @@ -470,7 +476,11 @@ | ||
941 | search.category = category; | ||
942 | # ifdef HAVE_PER_THREAD_LOCALE | ||
943 | # ifdef _LIBC | ||
944 | +# if __OPTION_EGLIBC_LOCALE_CODE | ||
945 | localename = strdupa (__current_locale_name (category)); | ||
946 | +# else | ||
947 | + localename = "C"; | ||
948 | +# endif | ||
949 | # endif | ||
950 | search.localename = localename; | ||
951 | # endif | ||
952 | @@ -494,7 +504,9 @@ | ||
953 | retval = (char *) (*foundp)->translation; | ||
954 | |||
955 | # ifdef _LIBC | ||
956 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
957 | __libc_rwlock_unlock (__libc_setlocale_lock); | ||
958 | +#endif | ||
959 | # endif | ||
960 | __libc_rwlock_unlock (_nl_state_lock); | ||
961 | return retval; | ||
962 | @@ -611,7 +623,9 @@ | ||
963 | { | ||
964 | no_translation: | ||
965 | FREE_BLOCKS (block_list); | ||
966 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
967 | __libc_rwlock_unlock (__libc_setlocale_lock); | ||
968 | +#endif | ||
969 | __libc_rwlock_unlock (_nl_state_lock); | ||
970 | __set_errno (saved_errno); | ||
971 | return (plural == 0 | ||
972 | @@ -730,7 +744,9 @@ | ||
973 | if (plural) | ||
974 | retval = plural_lookup (domain, n, retval, retlen); | ||
975 | |||
976 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
977 | __libc_rwlock_unlock (__libc_setlocale_lock); | ||
978 | +#endif | ||
979 | __libc_rwlock_unlock (_nl_state_lock); | ||
980 | return retval; | ||
981 | } | ||
982 | @@ -1361,7 +1377,11 @@ | ||
983 | `LC_xxx', and `LANG'. On some systems this can be done by the | ||
984 | `setlocale' function itself. */ | ||
985 | #ifdef _LIBC | ||
986 | +# if __OPTION_EGLIBC_LOCALE_CODE | ||
987 | retval = __current_locale_name (category); | ||
988 | +# else | ||
989 | + retval = "C"; | ||
990 | +# endif | ||
991 | #else | ||
992 | retval = _nl_locale_name (category, categoryname); | ||
993 | #endif | ||
994 | Index: git/intl/Makefile | ||
995 | =================================================================== | ||
996 | --- git.orig/intl/Makefile 2014-08-29 20:00:47.220070587 -0700 | ||
997 | +++ git/intl/Makefile 2014-08-29 20:01:15.200070587 -0700 | ||
998 | @@ -16,6 +16,7 @@ | ||
999 | # <http://www.gnu.org/licenses/>. | ||
1000 | |||
1001 | # Makefile for intl subdirectory: message handling code from GNU gettext. | ||
1002 | +include ../option-groups.mak | ||
1003 | |||
1004 | subdir = intl | ||
1005 | |||
1006 | @@ -48,7 +49,7 @@ | ||
1007 | $(objpfx)plural.o: plural.c | ||
1008 | |||
1009 | ifeq ($(run-built-tests),yes) | ||
1010 | -ifeq (yes,$(build-shared)) | ||
1011 | +ifeq (yyyes,$(OPTION_EGLIBC_LOCALES)$(OPTION_EGLIBC_LOCALE_CODE)$(build-shared)) | ||
1012 | ifneq ($(strip $(MSGFMT)),:) | ||
1013 | tests-special += $(objpfx)tst-translit.out $(objpfx)tst-gettext.out \ | ||
1014 | $(objpfx)tst-gettext2.out $(objpfx)tst-codeset.out \ | ||
1015 | Index: git/io/Makefile | ||
1016 | =================================================================== | ||
1017 | --- git.orig/io/Makefile 2014-08-29 20:00:47.244070587 -0700 | ||
1018 | +++ git/io/Makefile 2014-08-29 20:01:15.200070587 -0700 | ||
1019 | @@ -18,6 +18,8 @@ | ||
1020 | # | ||
1021 | # Sub-makefile for I/O portion of the library. | ||
1022 | # | ||
1023 | +include ../option-groups.mak | ||
1024 | + | ||
1025 | subdir := io | ||
1026 | |||
1027 | include ../Makeconfig | ||
1028 | @@ -36,7 +38,7 @@ | ||
1029 | fxstatat fxstatat64 \ | ||
1030 | statfs fstatfs statfs64 fstatfs64 \ | ||
1031 | statvfs fstatvfs statvfs64 fstatvfs64 \ | ||
1032 | - umask chmod fchmod lchmod fchmodat \ | ||
1033 | + umask chmod fchmod fchmodat \ | ||
1034 | mkdir mkdirat \ | ||
1035 | open open_2 open64 open64_2 openat openat_2 openat64 openat64_2 \ | ||
1036 | read write lseek lseek64 access euidaccess faccessat \ | ||
1037 | @@ -49,11 +51,13 @@ | ||
1038 | ttyname ttyname_r isatty \ | ||
1039 | link linkat symlink symlinkat readlink readlinkat \ | ||
1040 | unlink unlinkat rmdir \ | ||
1041 | - ftw ftw64 fts poll ppoll \ | ||
1042 | + poll ppoll \ | ||
1043 | posix_fadvise posix_fadvise64 \ | ||
1044 | posix_fallocate posix_fallocate64 \ | ||
1045 | sendfile sendfile64 \ | ||
1046 | utimensat futimens | ||
1047 | +routines-$(OPTION_EGLIBC_BSD) += lchmod | ||
1048 | +routines-$(OPTION_EGLIBC_FTRAVERSE) += ftw ftw64 fts | ||
1049 | |||
1050 | aux := have_o_cloexec | ||
1051 | |||
1052 | @@ -64,18 +68,22 @@ | ||
1053 | fstatat fstatat64 mknod mknodat | ||
1054 | |||
1055 | others := pwd | ||
1056 | -test-srcs := ftwtest | ||
1057 | +test-srcs-$(OPTION_EGLIBC_FTRAVERSE) := ftwtest | ||
1058 | tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ | ||
1059 | - tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 tst-statvfs \ | ||
1060 | + tst-fcntl tst-statvfs \ | ||
1061 | tst-openat tst-unlinkat tst-fstatat tst-futimesat \ | ||
1062 | tst-renameat tst-fchownat tst-fchmodat tst-faccessat \ | ||
1063 | tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \ | ||
1064 | - tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \ | ||
1065 | + tst-mknodat tst-mkfifoat tst-ttyname_r \ | ||
1066 | tst-posix_fallocate | ||
1067 | +tests-$(OPTION_EGLIBC_FTRAVERSE) += bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 \ | ||
1068 | + bug-ftw5 | ||
1069 | |||
1070 | ifeq ($(run-built-tests),yes) | ||
1071 | +ifeq (y,$(OPTION_EGLIBC_FTRAVERSE)) | ||
1072 | tests-special += $(objpfx)ftwtest.out | ||
1073 | endif | ||
1074 | +endif | ||
1075 | |||
1076 | include ../Rules | ||
1077 | |||
1078 | Index: git/libidn/Makefile | ||
1079 | =================================================================== | ||
1080 | --- git.orig/libidn/Makefile 2014-08-29 20:00:47.316070587 -0700 | ||
1081 | +++ git/libidn/Makefile 2014-08-29 20:01:15.200070587 -0700 | ||
1082 | @@ -16,6 +16,7 @@ | ||
1083 | # <http://www.gnu.org/licenses/>. | ||
1084 | |||
1085 | # Makefile for libidn subdirectory of GNU C Library. | ||
1086 | +include ../option-groups.mak | ||
1087 | |||
1088 | subdir := libidn | ||
1089 | |||
1090 | @@ -23,8 +24,8 @@ | ||
1091 | |||
1092 | routines = idn-stub | ||
1093 | |||
1094 | -extra-libs = libcidn | ||
1095 | -extra-libs-others = $(extra-libs) | ||
1096 | +extra-libs-$(OPTION_EGLIBC_IDN) = libcidn | ||
1097 | +extra-libs-others-y = $(extra-libs-y) | ||
1098 | |||
1099 | libcidn-routines := punycode toutf8 nfkc stringprep rfc3454 profiles idna \ | ||
1100 | iconvme | ||
1101 | Index: git/libidn/toutf8.c | ||
1102 | =================================================================== | ||
1103 | --- git.orig/libidn/toutf8.c 2014-08-29 20:00:47.332070587 -0700 | ||
1104 | +++ git/libidn/toutf8.c 2014-08-29 20:01:15.200070587 -0700 | ||
1105 | @@ -33,6 +33,11 @@ | ||
1106 | /* Get strlen. */ | ||
1107 | #include <string.h> | ||
1108 | |||
1109 | +/* Get __OPTION_EGLIBC_LOCALE_CODE. */ | ||
1110 | +#ifdef _LIBC | ||
1111 | +# include <gnu/option-groups.h> | ||
1112 | +#endif | ||
1113 | + | ||
1114 | /* Get iconv_string. */ | ||
1115 | #include "iconvme.h" | ||
1116 | |||
1117 | @@ -47,7 +52,11 @@ | ||
1118 | #endif | ||
1119 | |||
1120 | #ifdef _LIBC | ||
1121 | -# define stringprep_locale_charset() nl_langinfo (CODESET) | ||
1122 | +# if __OPTION_EGLIBC_LOCALE_CODE | ||
1123 | +# define stringprep_locale_charset() nl_langinfo (CODESET) | ||
1124 | +# else | ||
1125 | +# define stringprep_locale_charset() "ANSI_X3.4-1968" | ||
1126 | +# endif | ||
1127 | #else | ||
1128 | /** | ||
1129 | * stringprep_locale_charset - return charset used in current locale | ||
1130 | Index: git/libio/fileops.c | ||
1131 | =================================================================== | ||
1132 | --- git.orig/libio/fileops.c 2014-08-29 20:00:47.352070587 -0700 | ||
1133 | +++ git/libio/fileops.c 2014-08-29 20:01:15.200070587 -0700 | ||
1134 | @@ -38,6 +38,7 @@ | ||
1135 | #include <string.h> | ||
1136 | #include <errno.h> | ||
1137 | #include <unistd.h> | ||
1138 | +#include <gnu/option-groups.h> | ||
1139 | #include <stdlib.h> | ||
1140 | #if _LIBC | ||
1141 | # include "../wcsmbs/wcsmbsload.h" | ||
1142 | @@ -174,7 +175,7 @@ | ||
1143 | |||
1144 | /* Free buffer. */ | ||
1145 | #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T | ||
1146 | - if (fp->_mode > 0) | ||
1147 | + if (_IO_is_wide (fp)) | ||
1148 | { | ||
1149 | if (_IO_have_wbackup (fp)) | ||
1150 | _IO_free_wbackup_area (fp); | ||
1151 | @@ -359,6 +360,7 @@ | ||
1152 | cs = strstr (last_recognized + 1, ",ccs="); | ||
1153 | if (cs != NULL) | ||
1154 | { | ||
1155 | +#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
1156 | /* Yep. Load the appropriate conversions and set the orientation | ||
1157 | to wide. */ | ||
1158 | struct gconv_fcts fcts; | ||
1159 | @@ -423,6 +425,12 @@ | ||
1160 | |||
1161 | /* Set the mode now. */ | ||
1162 | result->_mode = 1; | ||
1163 | +#else | ||
1164 | + /* Treat this as if we couldn't find the given character set. */ | ||
1165 | + (void) _IO_file_close_it (fp); | ||
1166 | + __set_errno (EINVAL); | ||
1167 | + return NULL; | ||
1168 | +#endif | ||
1169 | } | ||
1170 | } | ||
1171 | |||
1172 | Index: git/libio/__fpurge.c | ||
1173 | =================================================================== | ||
1174 | --- git.orig/libio/__fpurge.c 2014-08-29 20:00:47.336070587 -0700 | ||
1175 | +++ git/libio/__fpurge.c 2014-08-29 20:01:15.200070587 -0700 | ||
1176 | @@ -21,7 +21,7 @@ | ||
1177 | void | ||
1178 | __fpurge (FILE *fp) | ||
1179 | { | ||
1180 | - if (fp->_mode > 0) | ||
1181 | + if (_IO_is_wide (fp)) | ||
1182 | { | ||
1183 | /* Wide-char stream. */ | ||
1184 | if (_IO_in_backup (fp)) | ||
1185 | Index: git/libio/iofwide.c | ||
1186 | =================================================================== | ||
1187 | --- git.orig/libio/iofwide.c 2014-08-29 20:00:47.360070587 -0700 | ||
1188 | +++ git/libio/iofwide.c 2014-08-29 20:01:15.200070587 -0700 | ||
1189 | @@ -26,6 +26,7 @@ | ||
1190 | |||
1191 | #include <libioP.h> | ||
1192 | #ifdef _LIBC | ||
1193 | +# include <gnu/option-groups.h> | ||
1194 | # include <dlfcn.h> | ||
1195 | # include <wchar.h> | ||
1196 | #endif | ||
1197 | @@ -43,6 +44,8 @@ | ||
1198 | #endif | ||
1199 | |||
1200 | |||
1201 | +#if ! defined _LIBC || __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
1202 | + | ||
1203 | /* Prototypes of libio's codecvt functions. */ | ||
1204 | static enum __codecvt_result do_out (struct _IO_codecvt *codecvt, | ||
1205 | __mbstate_t *statep, | ||
1206 | @@ -513,3 +516,26 @@ | ||
1207 | return MB_CUR_MAX; | ||
1208 | #endif | ||
1209 | } | ||
1210 | + | ||
1211 | +#else | ||
1212 | +/* OPTION_POSIX_C_LANG_WIDE_CHAR is disabled. */ | ||
1213 | + | ||
1214 | +#undef _IO_fwide | ||
1215 | +int | ||
1216 | +_IO_fwide (fp, mode) | ||
1217 | + _IO_FILE *fp; | ||
1218 | + int mode; | ||
1219 | +{ | ||
1220 | + /* Die helpfully if the user tries to create a wide stream; I | ||
1221 | + disbelieve that most users check the return value from | ||
1222 | + 'fwide (fp, 1)'. */ | ||
1223 | + assert (mode <= 0); | ||
1224 | + | ||
1225 | + /* We can only make streams byte-oriented, which is trivial. */ | ||
1226 | + if (mode < 0) | ||
1227 | + fp->_mode = -1; | ||
1228 | + | ||
1229 | + return fp->_mode; | ||
1230 | +} | ||
1231 | + | ||
1232 | +#endif | ||
1233 | Index: git/libio/ioseekoff.c | ||
1234 | =================================================================== | ||
1235 | --- git.orig/libio/ioseekoff.c 2014-08-29 20:00:47.364070587 -0700 | ||
1236 | +++ git/libio/ioseekoff.c 2014-08-29 20:01:15.200070587 -0700 | ||
1237 | @@ -60,7 +60,7 @@ | ||
1238 | else | ||
1239 | abort (); | ||
1240 | } | ||
1241 | - if (_IO_fwide (fp, 0) < 0) | ||
1242 | + if (! _IO_is_wide (fp)) | ||
1243 | _IO_free_backup_area (fp); | ||
1244 | else | ||
1245 | _IO_free_wbackup_area (fp); | ||
1246 | Index: git/libio/ioseekpos.c | ||
1247 | =================================================================== | ||
1248 | --- git.orig/libio/ioseekpos.c 2014-08-29 20:00:47.364070587 -0700 | ||
1249 | +++ git/libio/ioseekpos.c 2014-08-29 20:01:15.200070587 -0700 | ||
1250 | @@ -35,7 +35,7 @@ | ||
1251 | /* If we have a backup buffer, get rid of it, since the __seekoff | ||
1252 | callback may not know to do the right thing about it. | ||
1253 | This may be over-kill, but it'll do for now. TODO */ | ||
1254 | - if (_IO_fwide (fp, 0) <= 0) | ||
1255 | + if (! _IO_is_wide (fp)) | ||
1256 | { | ||
1257 | if (_IO_have_backup (fp)) | ||
1258 | _IO_free_backup_area (fp); | ||
1259 | Index: git/libio/iosetbuffer.c | ||
1260 | =================================================================== | ||
1261 | --- git.orig/libio/iosetbuffer.c 2014-08-29 20:00:47.364070587 -0700 | ||
1262 | +++ git/libio/iosetbuffer.c 2014-08-29 20:01:15.204070587 -0700 | ||
1263 | @@ -24,6 +24,8 @@ | ||
1264 | This exception applies to code released by its copyright holders | ||
1265 | in files containing the exception. */ | ||
1266 | |||
1267 | +#include <gnu/option-groups.h> | ||
1268 | + | ||
1269 | #include "libioP.h" | ||
1270 | |||
1271 | void | ||
1272 | @@ -38,9 +40,11 @@ | ||
1273 | if (!buf) | ||
1274 | size = 0; | ||
1275 | (void) _IO_SETBUF (fp, buf, size); | ||
1276 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
1277 | if (_IO_vtable_offset (fp) == 0 && fp->_mode == 0 && _IO_CHECK_WIDE (fp)) | ||
1278 | /* We also have to set the buffer using the wide char function. */ | ||
1279 | (void) _IO_WSETBUF (fp, buf, size); | ||
1280 | +#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ | ||
1281 | _IO_release_lock (fp); | ||
1282 | } | ||
1283 | libc_hidden_def (_IO_setbuffer) | ||
1284 | Index: git/libio/libioP.h | ||
1285 | =================================================================== | ||
1286 | --- git.orig/libio/libioP.h 2014-08-29 20:00:47.372070587 -0700 | ||
1287 | +++ git/libio/libioP.h 2014-08-29 20:01:15.204070587 -0700 | ||
1288 | @@ -42,6 +42,10 @@ | ||
1289 | /*# include <comthread.h>*/ | ||
1290 | #endif | ||
1291 | |||
1292 | +#if defined _LIBC | ||
1293 | +# include <gnu/option-groups.h> | ||
1294 | +#endif | ||
1295 | + | ||
1296 | #include <math_ldbl_opt.h> | ||
1297 | |||
1298 | #include "iolibio.h" | ||
1299 | @@ -508,8 +512,20 @@ | ||
1300 | |||
1301 | |||
1302 | #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T | ||
1303 | + | ||
1304 | +/* _IO_is_wide (fp) is roughly equivalent to '_IO_fwide (fp, 0) > 0', | ||
1305 | + except that when OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, it | ||
1306 | + expands to a constant, allowing the compiler to realize that it can | ||
1307 | + eliminate code that references wide stream handling functions. | ||
1308 | + This, in turn, allows us to omit them. */ | ||
1309 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
1310 | +# define _IO_is_wide(_f) ((_f)->_mode > 0) | ||
1311 | +#else | ||
1312 | +# define _IO_is_wide(_f) (0) | ||
1313 | +#endif | ||
1314 | + | ||
1315 | # define _IO_do_flush(_f) \ | ||
1316 | - ((_f)->_mode <= 0 \ | ||
1317 | + (! _IO_is_wide (_f) \ | ||
1318 | ? _IO_do_write(_f, (_f)->_IO_write_base, \ | ||
1319 | (_f)->_IO_write_ptr-(_f)->_IO_write_base) \ | ||
1320 | : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base, \ | ||
1321 | Index: git/libio/Makefile | ||
1322 | =================================================================== | ||
1323 | --- git.orig/libio/Makefile 2014-08-29 20:00:47.332070587 -0700 | ||
1324 | +++ git/libio/Makefile 2014-08-29 20:01:15.204070587 -0700 | ||
1325 | @@ -18,6 +18,8 @@ | ||
1326 | # | ||
1327 | # Specific makefile for libio. | ||
1328 | # | ||
1329 | +include ../option-groups.mak | ||
1330 | + | ||
1331 | subdir := libio | ||
1332 | |||
1333 | include ../Makeconfig | ||
1334 | @@ -27,16 +29,13 @@ | ||
1335 | |||
1336 | routines := \ | ||
1337 | filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen \ | ||
1338 | - iofopncook iofputs iofread iofsetpos ioftell wfiledoalloc \ | ||
1339 | + iofopncook iofputs iofread iofsetpos ioftell \ | ||
1340 | iofwrite iogetdelim iogetline iogets iopadn iopopen ioputs \ | ||
1341 | ioseekoff ioseekpos iosetbuffer iosetvbuf ioungetc \ | ||
1342 | iovsprintf iovsscanf \ | ||
1343 | iofgetpos64 iofopen64 iofsetpos64 \ | ||
1344 | - fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \ | ||
1345 | - iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u \ | ||
1346 | - putwchar putwchar_u putchar putchar_u fwprintf swprintf vwprintf \ | ||
1347 | - wprintf wscanf fwscanf vwscanf vswprintf iovswscanf swscanf wgenops \ | ||
1348 | - wstrops wfileops iofwide fwide wmemstream \ | ||
1349 | + putchar putchar_u \ | ||
1350 | + iofwide \ | ||
1351 | \ | ||
1352 | clearerr feof ferror fileno fputc freopen fseek getc getchar \ | ||
1353 | memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \ | ||
1354 | @@ -47,25 +46,48 @@ | ||
1355 | __fpurge __fpending __fsetlocking \ | ||
1356 | \ | ||
1357 | libc_fatal fmemopen | ||
1358 | - | ||
1359 | -tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ | ||
1360 | - tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \ | ||
1361 | - tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf \ | ||
1362 | - tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof \ | ||
1363 | - tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \ | ||
1364 | - tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \ | ||
1365 | - tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \ | ||
1366 | - bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4 tst-fopenloc2 \ | ||
1367 | - tst-memstream1 tst-memstream2 \ | ||
1368 | - tst-wmemstream1 tst-wmemstream2 \ | ||
1369 | - bug-memstream1 bug-wmemstream1 \ | ||
1370 | - tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ | ||
1371 | - tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \ | ||
1372 | - tst-ftell-append | ||
1373 | +routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += \ | ||
1374 | + wfiledoalloc \ | ||
1375 | + iowpadn \ | ||
1376 | + swprintf \ | ||
1377 | + vswprintf iovswscanf swscanf wgenops \ | ||
1378 | + wstrops wfileops wmemstream | ||
1379 | +routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) += \ | ||
1380 | + wdummyfileops | ||
1381 | +routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += \ | ||
1382 | + fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \ | ||
1383 | + iofputws iofputws_u iogetwline ioungetwc putwc putwc_u \ | ||
1384 | + putwchar putwchar_u fwprintf vwprintf \ | ||
1385 | + wprintf wscanf fwscanf vwscanf \ | ||
1386 | + fwide | ||
1387 | + | ||
1388 | +tests = test-fmemopen tst-ext tst-ext2 \ | ||
1389 | + tst-mmap-setvbuf tst-atime tst-eof \ | ||
1390 | + tst-freopen bug-ungetc bug-fseek \ | ||
1391 | + tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \ | ||
1392 | + tst-mmap2-eofsync tst-mmap-offend bug-fopena+ \ | ||
1393 | + bug-ungetc2 bug-ungetc3 bug-ungetc4 \ | ||
1394 | + tst-memstream1 tst-memstream2 \ | ||
1395 | + bug-memstream1 tst-popen1 tst-fwrite-error \ | ||
1396 | + tst-ftell-active-handler tst-ftell-append | ||
1397 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
1398 | + += tst-swscanf tst-fgetws tst-setvbuf1 \ | ||
1399 | + tst-ungetwc1 tst-ungetwc2 bug-ftell bug-ungetwc2 \ | ||
1400 | + tst-widetext | ||
1401 | +tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \ | ||
1402 | + += bug-rewind bug-rewind2 bug-ungetwc1 \ | ||
1403 | + bug-wfflush bug-wmemstream1 tst-fopenloc2 \ | ||
1404 | + tst_getwc \ | ||
1405 | + tst_putwc tst_wprintf tst_wprintf2 tst_wscanf \ | ||
1406 | + tst-fgetwc bug-wsetpos tst-fseek tst-ftell-partial-wide | ||
1407 | +tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ | ||
1408 | + += tst_swprintf tst_swscanf \ | ||
1409 | + tst-sscanf \ | ||
1410 | + tst-wmemstream1 tst-wmemstream2 | ||
1411 | ifeq (yes,$(build-shared)) | ||
1412 | # Add test-fopenloc only if shared library is enabled since it depends on | ||
1413 | # shared localedata objects. | ||
1414 | -tests += tst-fopenloc | ||
1415 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-fopenloc | ||
1416 | endif | ||
1417 | test-srcs = test-freopen | ||
1418 | |||
1419 | @@ -164,13 +186,17 @@ | ||
1420 | oldiofsetpos64 | ||
1421 | |||
1422 | ifeq ($(run-built-tests),yes) | ||
1423 | +ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)) | ||
1424 | tests-special += $(objpfx)test-freopen.out | ||
1425 | +endif | ||
1426 | +ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE)) | ||
1427 | ifeq (yes,$(build-shared)) | ||
1428 | # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared | ||
1429 | # library is enabled since they depend on tst-fopenloc.out. | ||
1430 | tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out | ||
1431 | endif | ||
1432 | endif | ||
1433 | +endif | ||
1434 | |||
1435 | include ../Rules | ||
1436 | |||
1437 | Index: git/libio/wdummyfileops.c | ||
1438 | =================================================================== | ||
1439 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1440 | +++ git/libio/wdummyfileops.c 2014-08-29 20:01:15.204070587 -0700 | ||
1441 | @@ -0,0 +1,161 @@ | ||
1442 | +/* Copyright (C) 2007 Free Software Foundation, Inc. | ||
1443 | + This file is part of the GNU C Library. | ||
1444 | + | ||
1445 | + The GNU C Library is free software; you can redistribute it and/or | ||
1446 | + modify it under the terms of the GNU Lesser General Public | ||
1447 | + License as published by the Free Software Foundation; either | ||
1448 | + version 2.1 of the License, or (at your option) any later version. | ||
1449 | + | ||
1450 | + The GNU C Library is distributed in the hope that it will be useful, | ||
1451 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1452 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1453 | + Lesser General Public License for more details. | ||
1454 | + | ||
1455 | + You should have received a copy of the GNU Lesser General Public | ||
1456 | + License along with the GNU C Library; if not, write to the Free | ||
1457 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
1458 | + 02111-1307 USA. | ||
1459 | + | ||
1460 | + As a special exception, if you link the code in this file with | ||
1461 | + files compiled with a GNU compiler to produce an executable, | ||
1462 | + that does not cause the resulting executable to be covered by | ||
1463 | + the GNU Lesser General Public License. This exception does not | ||
1464 | + however invalidate any other reasons why the executable file | ||
1465 | + might be covered by the GNU Lesser General Public License. | ||
1466 | + This exception applies to code released by its copyright holders | ||
1467 | + in files containing the exception. */ | ||
1468 | + | ||
1469 | +#include <assert.h> | ||
1470 | +#include <stdio.h> | ||
1471 | +#include <stdlib.h> | ||
1472 | +#include <libioP.h> | ||
1473 | + | ||
1474 | +static void __THROW __attribute__ ((__noreturn__)) | ||
1475 | +_IO_wfile_wide_char_support_disabled (void) | ||
1476 | +{ | ||
1477 | + static const char errstr[] | ||
1478 | + = ("The application tried to use wide character I/O, but libc.so" | ||
1479 | + " was compiled\n" | ||
1480 | + "with the OPTION_POSIX_C_LANG_WIDE_CHAR option group disabled.\n"); | ||
1481 | + __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1); | ||
1482 | + abort (); | ||
1483 | +} | ||
1484 | + | ||
1485 | +static void | ||
1486 | +_IO_wfile_disabled_void_int (_IO_FILE *fp, int x) | ||
1487 | +{ | ||
1488 | + _IO_wfile_wide_char_support_disabled (); | ||
1489 | +} | ||
1490 | + | ||
1491 | +static int | ||
1492 | +_IO_wfile_disabled_int_int (_IO_FILE *fp, int x) | ||
1493 | +{ | ||
1494 | + _IO_wfile_wide_char_support_disabled (); | ||
1495 | +} | ||
1496 | + | ||
1497 | +static int | ||
1498 | +_IO_wfile_disabled_int_none (_IO_FILE *fp) | ||
1499 | +{ | ||
1500 | + _IO_wfile_wide_char_support_disabled (); | ||
1501 | +} | ||
1502 | + | ||
1503 | +static _IO_size_t | ||
1504 | +_IO_wfile_disabled_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n) | ||
1505 | +{ | ||
1506 | + _IO_wfile_wide_char_support_disabled (); | ||
1507 | +} | ||
1508 | + | ||
1509 | +static _IO_size_t | ||
1510 | +_IO_wfile_disabled_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) | ||
1511 | +{ | ||
1512 | + _IO_wfile_wide_char_support_disabled (); | ||
1513 | +} | ||
1514 | + | ||
1515 | +static _IO_off64_t | ||
1516 | +_IO_wfile_disabled_seekoff (_IO_FILE *fp, _IO_off64_t off, int dir, int mode) | ||
1517 | +{ | ||
1518 | + _IO_wfile_wide_char_support_disabled (); | ||
1519 | +} | ||
1520 | + | ||
1521 | +static _IO_off64_t | ||
1522 | +_IO_wfile_disabled_seekpos (_IO_FILE *fp, _IO_off64_t pos, int flags) | ||
1523 | +{ | ||
1524 | + _IO_wfile_wide_char_support_disabled (); | ||
1525 | +} | ||
1526 | + | ||
1527 | +static _IO_FILE * | ||
1528 | +_IO_wfile_disabled_setbuf (_IO_FILE *fp, char *buffer, _IO_ssize_t length) | ||
1529 | +{ | ||
1530 | + _IO_wfile_wide_char_support_disabled (); | ||
1531 | +} | ||
1532 | + | ||
1533 | +static _IO_ssize_t | ||
1534 | +_IO_wfile_disabled_read (_IO_FILE *fp, void *buffer, _IO_ssize_t length) | ||
1535 | +{ | ||
1536 | + _IO_wfile_wide_char_support_disabled (); | ||
1537 | +} | ||
1538 | + | ||
1539 | +static _IO_ssize_t | ||
1540 | +_IO_wfile_disabled_write (_IO_FILE *fp, const void *buffer, _IO_ssize_t length) | ||
1541 | +{ | ||
1542 | + _IO_wfile_wide_char_support_disabled (); | ||
1543 | +} | ||
1544 | + | ||
1545 | +static _IO_off64_t | ||
1546 | +_IO_wfile_disabled_seek (_IO_FILE *fp, _IO_off64_t offset, int mode) | ||
1547 | +{ | ||
1548 | + _IO_wfile_wide_char_support_disabled (); | ||
1549 | +} | ||
1550 | + | ||
1551 | +static int | ||
1552 | +_IO_wfile_disabled_close (_IO_FILE *fp) | ||
1553 | +{ | ||
1554 | + _IO_wfile_wide_char_support_disabled (); | ||
1555 | +} | ||
1556 | + | ||
1557 | +static int | ||
1558 | +_IO_wfile_disabled_stat (_IO_FILE *fp, void *buf) | ||
1559 | +{ | ||
1560 | + _IO_wfile_wide_char_support_disabled (); | ||
1561 | +} | ||
1562 | + | ||
1563 | +static int | ||
1564 | +_IO_wfile_disabled_showmanyc (_IO_FILE *fp) | ||
1565 | +{ | ||
1566 | + _IO_wfile_wide_char_support_disabled (); | ||
1567 | +} | ||
1568 | + | ||
1569 | +static void | ||
1570 | +_IO_wfile_disabled_imbue (_IO_FILE *fp, void *locale) | ||
1571 | +{ | ||
1572 | + _IO_wfile_wide_char_support_disabled (); | ||
1573 | +} | ||
1574 | + | ||
1575 | +static const struct _IO_jump_t _IO_wfile_jumps_disabled = | ||
1576 | +{ | ||
1577 | + JUMP_INIT_DUMMY, | ||
1578 | + JUMP_INIT(finish, _IO_wfile_disabled_void_int), | ||
1579 | + JUMP_INIT(overflow, _IO_wfile_disabled_int_int), | ||
1580 | + JUMP_INIT(underflow, _IO_wfile_disabled_int_none), | ||
1581 | + JUMP_INIT(uflow, _IO_wfile_disabled_int_none), | ||
1582 | + JUMP_INIT(pbackfail, _IO_wfile_disabled_int_int), | ||
1583 | + JUMP_INIT(xsputn, _IO_wfile_disabled_xsputn), | ||
1584 | + JUMP_INIT(xsgetn, _IO_wfile_disabled_xsgetn), | ||
1585 | + JUMP_INIT(seekoff, _IO_wfile_disabled_seekoff), | ||
1586 | + JUMP_INIT(seekpos, _IO_wfile_disabled_seekpos), | ||
1587 | + JUMP_INIT(setbuf, _IO_wfile_disabled_setbuf), | ||
1588 | + JUMP_INIT(sync, _IO_wfile_disabled_int_none), | ||
1589 | + JUMP_INIT(doallocate, _IO_wfile_disabled_int_none), | ||
1590 | + JUMP_INIT(read, _IO_wfile_disabled_read), | ||
1591 | + JUMP_INIT(write, _IO_wfile_disabled_write), | ||
1592 | + JUMP_INIT(seek, _IO_wfile_disabled_seek), | ||
1593 | + JUMP_INIT(close, _IO_wfile_disabled_close), | ||
1594 | + JUMP_INIT(stat, _IO_wfile_disabled_stat), | ||
1595 | + JUMP_INIT(showmanyc, _IO_wfile_disabled_showmanyc), | ||
1596 | + JUMP_INIT(imbue, _IO_wfile_disabled_imbue) | ||
1597 | +}; | ||
1598 | + | ||
1599 | +strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps) | ||
1600 | +libc_hidden_data_def (_IO_wfile_jumps) | ||
1601 | +strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_mmap) | ||
1602 | +strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_maybe_mmap) | ||
1603 | Index: git/locale/catnames.c | ||
1604 | =================================================================== | ||
1605 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1606 | +++ git/locale/catnames.c 2014-08-29 20:01:15.204070587 -0700 | ||
1607 | @@ -0,0 +1,48 @@ | ||
1608 | +/* Copyright (C) 2006 Free Software Foundation, Inc. | ||
1609 | + This file is part of the GNU C Library. | ||
1610 | + | ||
1611 | + The GNU C Library is free software; you can redistribute it and/or | ||
1612 | + modify it under the terms of the GNU Lesser General Public | ||
1613 | + License as published by the Free Software Foundation; either | ||
1614 | + version 2.1 of the License, or (at your option) any later version. | ||
1615 | + | ||
1616 | + The GNU C Library is distributed in the hope that it will be useful, | ||
1617 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1618 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1619 | + Lesser General Public License for more details. | ||
1620 | + | ||
1621 | + You should have received a copy of the GNU Lesser General Public | ||
1622 | + License along with the GNU C Library; if not, write to the Free | ||
1623 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
1624 | + 02111-1307 USA. */ | ||
1625 | + | ||
1626 | +#include "localeinfo.h" | ||
1627 | + | ||
1628 | +/* Define an array of category names (also the environment variable names). */ | ||
1629 | +const union catnamestr_t _nl_category_names attribute_hidden = | ||
1630 | + { | ||
1631 | + { | ||
1632 | +#define DEFINE_CATEGORY(category, category_name, items, a) \ | ||
1633 | + category_name, | ||
1634 | +#include "categories.def" | ||
1635 | +#undef DEFINE_CATEGORY | ||
1636 | + } | ||
1637 | + }; | ||
1638 | + | ||
1639 | +const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden = | ||
1640 | + { | ||
1641 | +#define DEFINE_CATEGORY(category, category_name, items, a) \ | ||
1642 | + [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)), | ||
1643 | +#include "categories.def" | ||
1644 | +#undef DEFINE_CATEGORY | ||
1645 | + }; | ||
1646 | + | ||
1647 | +/* An array of their lengths, for convenience. */ | ||
1648 | +const uint8_t _nl_category_name_sizes[] attribute_hidden = | ||
1649 | + { | ||
1650 | +#define DEFINE_CATEGORY(category, category_name, items, a) \ | ||
1651 | + [category] = sizeof (category_name) - 1, | ||
1652 | +#include "categories.def" | ||
1653 | +#undef DEFINE_CATEGORY | ||
1654 | + [LC_ALL] = sizeof ("LC_ALL") - 1 | ||
1655 | + }; | ||
1656 | Index: git/locale/C-ctype.c | ||
1657 | =================================================================== | ||
1658 | --- git.orig/locale/C-ctype.c 2014-08-29 20:00:47.396070587 -0700 | ||
1659 | +++ git/locale/C-ctype.c 2014-08-29 20:01:15.204070587 -0700 | ||
1660 | @@ -19,8 +19,11 @@ | ||
1661 | #include "localeinfo.h" | ||
1662 | #include <endian.h> | ||
1663 | #include <stdint.h> | ||
1664 | +#include <gnu/option-groups.h> | ||
1665 | |||
1666 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
1667 | #include "C-translit.h" | ||
1668 | +#endif | ||
1669 | |||
1670 | /* This table's entries are taken from POSIX.2 Table 2-6 | ||
1671 | ``LC_CTYPE Category Definition in the POSIX Locale''. | ||
1672 | @@ -647,6 +650,7 @@ | ||
1673 | { .word = L'7' }, | ||
1674 | { .word = L'8' }, | ||
1675 | { .word = L'9' }, | ||
1676 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
1677 | /* _NL_CTYPE_TRANSLIT_TAB_SIZE */ | ||
1678 | { .word = NTRANSLIT }, | ||
1679 | /* _NL_CTYPE_TRANSLIT_FROM_IDX */ | ||
1680 | @@ -657,6 +661,22 @@ | ||
1681 | { .wstr = translit_to_idx }, | ||
1682 | /* _NL_CTYPE_TRANSLIT_TO_TBL */ | ||
1683 | { .wstr = (uint32_t *) translit_to_tbl }, | ||
1684 | +#else | ||
1685 | + /* If the locale code isn't enabled, we don't have the | ||
1686 | + transliteration code in iconv/gconv_trans.c anyway, so there's | ||
1687 | + no need for the transliteration tables here. We'll fall back | ||
1688 | + on the default missing replacement, '?'. */ | ||
1689 | + /* _NL_CTYPE_TRANSLIT_TAB_SIZE */ | ||
1690 | + { .word = 0 }, | ||
1691 | + /* _NL_CTYPE_TRANSLIT_FROM_IDX */ | ||
1692 | + { .wstr = NULL }, | ||
1693 | + /* _NL_CTYPE_TRANSLIT_FROM_TBL */ | ||
1694 | + { .wstr = NULL }, | ||
1695 | + /* _NL_CTYPE_TRANSLIT_TO_IDX */ | ||
1696 | + { .wstr = NULL }, | ||
1697 | + /* _NL_CTYPE_TRANSLIT_TO_TBL */ | ||
1698 | + { .wstr = NULL }, | ||
1699 | +#endif | ||
1700 | /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN */ | ||
1701 | { .word = 1 }, | ||
1702 | /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING */ | ||
1703 | Index: git/locale/dummy-setlocale.c | ||
1704 | =================================================================== | ||
1705 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1706 | +++ git/locale/dummy-setlocale.c 2014-08-29 20:01:15.204070587 -0700 | ||
1707 | @@ -0,0 +1,33 @@ | ||
1708 | +/* Copyright (C) 2006 Free Software Foundation, Inc. | ||
1709 | + This file is part of the GNU C Library. | ||
1710 | + | ||
1711 | + The GNU C Library is free software; you can redistribute it and/or | ||
1712 | + modify it under the terms of the GNU Lesser General Public | ||
1713 | + License as published by the Free Software Foundation; either | ||
1714 | + version 2.1 of the License, or (at your option) any later version. | ||
1715 | + | ||
1716 | + The GNU C Library is distributed in the hope that it will be useful, | ||
1717 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1718 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1719 | + Lesser General Public License for more details. | ||
1720 | + | ||
1721 | + You should have received a copy of the GNU Lesser General Public | ||
1722 | + License along with the GNU C Library; if not, write to the Free | ||
1723 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
1724 | + 02111-1307 USA. */ | ||
1725 | + | ||
1726 | +#include <string.h> | ||
1727 | +#include <locale.h> | ||
1728 | + | ||
1729 | +char * | ||
1730 | +setlocale (int category, const char *locale) | ||
1731 | +{ | ||
1732 | + if (! locale | ||
1733 | + || locale[0] == '\0' | ||
1734 | + || strcmp (locale, "C") == 0 | ||
1735 | + || strcmp (locale, "POSIX") == 0) | ||
1736 | + return (char *) "C"; | ||
1737 | + else | ||
1738 | + return NULL; | ||
1739 | +} | ||
1740 | +libc_hidden_def (setlocale) | ||
1741 | Index: git/locale/localeinfo.h | ||
1742 | =================================================================== | ||
1743 | --- git.orig/locale/localeinfo.h 2014-08-29 20:00:47.404070587 -0700 | ||
1744 | +++ git/locale/localeinfo.h 2014-08-29 20:01:15.204070587 -0700 | ||
1745 | @@ -224,7 +224,7 @@ | ||
1746 | unused. We can manage this playing some tricks with weak references. | ||
1747 | But with thread-local locale settings, it becomes quite ungainly unless | ||
1748 | we can use __thread variables. So only in that case do we attempt this. */ | ||
1749 | -#ifndef SHARED | ||
1750 | +#if !defined SHARED && !defined IN_GLIBC_LOCALEDEF | ||
1751 | # include <tls.h> | ||
1752 | # define NL_CURRENT_INDIRECT 1 | ||
1753 | #endif | ||
1754 | Index: git/locale/Makefile | ||
1755 | =================================================================== | ||
1756 | --- git.orig/locale/Makefile 2014-08-29 20:00:47.400070587 -0700 | ||
1757 | +++ git/locale/Makefile 2014-08-29 20:01:15.204070587 -0700 | ||
1758 | @@ -18,27 +18,43 @@ | ||
1759 | # | ||
1760 | # Makefile for locales. | ||
1761 | # | ||
1762 | +include ../option-groups.mak | ||
1763 | + | ||
1764 | subdir := locale | ||
1765 | |||
1766 | include ../Makeconfig | ||
1767 | |||
1768 | headers = locale.h bits/locale.h langinfo.h xlocale.h | ||
1769 | -routines = setlocale findlocale loadlocale loadarchive \ | ||
1770 | - localeconv nl_langinfo nl_langinfo_l mb_cur_max \ | ||
1771 | - newlocale duplocale freelocale uselocale | ||
1772 | -tests = tst-C-locale tst-locname tst-duplocale | ||
1773 | +# catnames is needed by OPTION_EGLIBC_LOCALE_CODE and by the 'intl' code. | ||
1774 | +# If we put the latter in an option group, too, we can omit catnames | ||
1775 | +# when both option groups are disabled. libstdc++-v3 needs mb_cur_max. | ||
1776 | +routines-y := catnames mb_cur_max | ||
1777 | +routines-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
1778 | + += setlocale findlocale loadlocale loadarchive \ | ||
1779 | + localeconv nl_langinfo nl_langinfo_l \ | ||
1780 | + newlocale duplocale freelocale uselocale | ||
1781 | +ifneq (y,$(OPTION_EGLIBC_LOCALE_CODE)) | ||
1782 | +routines-y += dummy-setlocale | ||
1783 | +endif | ||
1784 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-C-locale tst-locname tst-duplocale | ||
1785 | categories = ctype messages monetary numeric time paper name \ | ||
1786 | address telephone measurement identification collate | ||
1787 | -aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \ | ||
1788 | - xlocale localename global-locale coll-lookup | ||
1789 | -others = localedef locale | ||
1790 | +# C-messages belongs in an intl option group. | ||
1791 | +aux-y := C-ctype C-time \ | ||
1792 | + SYS_libc C_name xlocale global-locale coll-lookup | ||
1793 | +aux-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
1794 | + += $(filter-out $(aux-y), \ | ||
1795 | + $(categories:%=lc-%) $(categories:%=C-%)) \ | ||
1796 | + localename | ||
1797 | +others-$(OPTION_EGLIBC_LOCALE_CODE) = localedef locale | ||
1798 | #others-static = localedef locale | ||
1799 | -install-bin = localedef locale | ||
1800 | -extra-objs = $(localedef-modules:=.o) $(localedef-aux:=.o) \ | ||
1801 | +install-bin = $(others-y) | ||
1802 | +extra-objs-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
1803 | + = $(localedef-modules:=.o) $(localedef-aux:=.o) \ | ||
1804 | $(locale-modules:=.o) $(lib-modules:=.o) | ||
1805 | |||
1806 | -extra-libs = libBrokenLocale | ||
1807 | -extra-libs-others = $(extra-libs) | ||
1808 | +extra-libs-$(OPTION_EGLIBC_LOCALE_CODE) = libBrokenLocale | ||
1809 | +extra-libs-others = $(extra-libs-y) | ||
1810 | |||
1811 | libBrokenLocale-routines = broken_cur_max | ||
1812 | |||
1813 | @@ -94,6 +110,9 @@ | ||
1814 | CFLAGS-charmap.c = -Wno-write-strings -Wno-char-subscripts | ||
1815 | CFLAGS-locfile.c = -Wno-write-strings -Wno-char-subscripts | ||
1816 | CFLAGS-charmap-dir.c = -Wno-write-strings | ||
1817 | +ifneq (y,$(OPTION_EGLIBC_SPAWN)) | ||
1818 | +CFLAGS-charmap-dir.c += -DNO_UNCOMPRESS | ||
1819 | +endif | ||
1820 | |||
1821 | # This makes sure -DNOT_IN_libc et al are passed for all these modules. | ||
1822 | cpp-srcs-left := $(addsuffix .c,$(localedef-modules) $(localedef-aux) \ | ||
1823 | Index: git/locale/programs/charmap-dir.c | ||
1824 | =================================================================== | ||
1825 | --- git.orig/locale/programs/charmap-dir.c 2014-08-29 20:00:47.408070587 -0700 | ||
1826 | +++ git/locale/programs/charmap-dir.c 2014-08-29 20:01:15.204070587 -0700 | ||
1827 | @@ -19,7 +19,9 @@ | ||
1828 | #include <error.h> | ||
1829 | #include <fcntl.h> | ||
1830 | #include <libintl.h> | ||
1831 | +#ifndef NO_UNCOMPRESS | ||
1832 | #include <spawn.h> | ||
1833 | +#endif | ||
1834 | #include <stdio.h> | ||
1835 | #include <stdlib.h> | ||
1836 | #include <string.h> | ||
1837 | @@ -156,6 +158,7 @@ | ||
1838 | return closedir (dir); | ||
1839 | } | ||
1840 | |||
1841 | +#ifndef NO_UNCOMPRESS | ||
1842 | /* Creates a subprocess decompressing the given pathname, and returns | ||
1843 | a stream reading its output (the decompressed data). */ | ||
1844 | static | ||
1845 | @@ -204,6 +207,7 @@ | ||
1846 | } | ||
1847 | return NULL; | ||
1848 | } | ||
1849 | +#endif | ||
1850 | |||
1851 | /* Opens a charmap for reading, given its name (not an alias name). */ | ||
1852 | FILE * | ||
1853 | @@ -226,6 +230,7 @@ | ||
1854 | if (stream != NULL) | ||
1855 | return stream; | ||
1856 | |||
1857 | +#ifndef NO_UNCOMPRESS | ||
1858 | memcpy (p, ".gz", 4); | ||
1859 | stream = fopen_uncompressed (pathname, "gzip"); | ||
1860 | if (stream != NULL) | ||
1861 | @@ -235,6 +240,7 @@ | ||
1862 | stream = fopen_uncompressed (pathname, "bzip2"); | ||
1863 | if (stream != NULL) | ||
1864 | return stream; | ||
1865 | +#endif | ||
1866 | |||
1867 | return NULL; | ||
1868 | } | ||
1869 | @@ -263,8 +269,8 @@ | ||
1870 | char *alias = NULL; | ||
1871 | char junk[BUFSIZ]; | ||
1872 | |||
1873 | - if (fscanf (stream, " <code_set_name> %ms", &alias) == 1 | ||
1874 | - || fscanf (stream, "%% alias %ms", &alias) == 1) | ||
1875 | + if (fscanf (stream, " <code_set_name> %as", &alias) == 1 | ||
1876 | + || fscanf (stream, "%% alias %as", &alias) == 1) | ||
1877 | { | ||
1878 | aliases = (char **) xrealloc (aliases, | ||
1879 | (naliases + 2) * sizeof (char *)); | ||
1880 | Index: git/locale/programs/ld-collate.c | ||
1881 | =================================================================== | ||
1882 | --- git.orig/locale/programs/ld-collate.c 2014-08-29 20:00:47.408070587 -0700 | ||
1883 | +++ git/locale/programs/ld-collate.c 2014-08-29 20:01:15.208070587 -0700 | ||
1884 | @@ -350,7 +350,7 @@ | ||
1885 | } | ||
1886 | if (wcs != NULL) | ||
1887 | { | ||
1888 | - size_t nwcs = wcslen ((wchar_t *) wcs); | ||
1889 | + size_t nwcs = wcslen_uint32 (wcs); | ||
1890 | uint32_t zero = 0; | ||
1891 | /* Handle <U0000> as a single character. */ | ||
1892 | if (nwcs == 0) | ||
1893 | @@ -1776,8 +1776,7 @@ | ||
1894 | |||
1895 | if ((*eptr)->nwcs == runp->nwcs) | ||
1896 | { | ||
1897 | - int c = wmemcmp ((wchar_t *) (*eptr)->wcs, | ||
1898 | - (wchar_t *) runp->wcs, runp->nwcs); | ||
1899 | + int c = wmemcmp_uint32 ((*eptr)->wcs, runp->wcs, runp->nwcs); | ||
1900 | |||
1901 | if (c == 0) | ||
1902 | { | ||
1903 | @@ -2010,9 +2009,9 @@ | ||
1904 | one consecutive entry. */ | ||
1905 | if (runp->wcnext != NULL | ||
1906 | && runp->nwcs == runp->wcnext->nwcs | ||
1907 | - && wmemcmp ((wchar_t *) runp->wcs, | ||
1908 | - (wchar_t *)runp->wcnext->wcs, | ||
1909 | - runp->nwcs - 1) == 0 | ||
1910 | + && wmemcmp_uint32 (runp->wcs, | ||
1911 | + runp->wcnext->wcs, | ||
1912 | + runp->nwcs - 1) == 0 | ||
1913 | && (runp->wcs[runp->nwcs - 1] | ||
1914 | == runp->wcnext->wcs[runp->nwcs - 1] + 1)) | ||
1915 | { | ||
1916 | @@ -2036,9 +2035,9 @@ | ||
1917 | runp = runp->wcnext; | ||
1918 | while (runp->wcnext != NULL | ||
1919 | && runp->nwcs == runp->wcnext->nwcs | ||
1920 | - && wmemcmp ((wchar_t *) runp->wcs, | ||
1921 | - (wchar_t *)runp->wcnext->wcs, | ||
1922 | - runp->nwcs - 1) == 0 | ||
1923 | + && wmemcmp_uint32 (runp->wcs, | ||
1924 | + runp->wcnext->wcs, | ||
1925 | + runp->nwcs - 1) == 0 | ||
1926 | && (runp->wcs[runp->nwcs - 1] | ||
1927 | == runp->wcnext->wcs[runp->nwcs - 1] + 1)); | ||
1928 | |||
1929 | Index: git/locale/programs/ld-ctype.c | ||
1930 | =================================================================== | ||
1931 | --- git.orig/locale/programs/ld-ctype.c 2014-08-29 20:00:47.408070587 -0700 | ||
1932 | +++ git/locale/programs/ld-ctype.c 2014-08-29 20:01:15.208070587 -0700 | ||
1933 | @@ -957,7 +957,7 @@ | ||
1934 | allocate_arrays (ctype, charmap, ctype->repertoire); | ||
1935 | |||
1936 | default_missing_len = (ctype->default_missing | ||
1937 | - ? wcslen ((wchar_t *) ctype->default_missing) | ||
1938 | + ? wcslen_uint32 (ctype->default_missing) | ||
1939 | : 0); | ||
1940 | |||
1941 | init_locale_data (&file, nelems); | ||
1942 | @@ -1968,7 +1968,7 @@ | ||
1943 | ignore = 1; | ||
1944 | else | ||
1945 | /* This value is usable. */ | ||
1946 | - obstack_grow (ob, to_wstr, wcslen ((wchar_t *) to_wstr) * 4); | ||
1947 | + obstack_grow (ob, to_wstr, wcslen_uint32 (to_wstr) * 4); | ||
1948 | |||
1949 | first = 0; | ||
1950 | } | ||
1951 | @@ -2516,8 +2516,8 @@ | ||
1952 | } | ||
1953 | |||
1954 | handle_tok_digit: | ||
1955 | - class_bit = _ISwdigit; | ||
1956 | - class256_bit = _ISdigit; | ||
1957 | + class_bit = BITw (tok_digit); | ||
1958 | + class256_bit = BIT (tok_digit); | ||
1959 | handle_digits = 1; | ||
1960 | goto read_charclass; | ||
1961 | |||
1962 | @@ -4001,8 +4001,7 @@ | ||
1963 | |||
1964 | while (idx < number) | ||
1965 | { | ||
1966 | - int res = wcscmp ((const wchar_t *) sorted[idx]->from, | ||
1967 | - (const wchar_t *) runp->from); | ||
1968 | + int res = wcscmp_uint32 (sorted[idx]->from, runp->from); | ||
1969 | if (res == 0) | ||
1970 | { | ||
1971 | replace = 1; | ||
1972 | @@ -4039,11 +4038,11 @@ | ||
1973 | for (cnt = 0; cnt < number; ++cnt) | ||
1974 | { | ||
1975 | struct translit_to_t *srunp; | ||
1976 | - from_len += wcslen ((const wchar_t *) sorted[cnt]->from) + 1; | ||
1977 | + from_len += wcslen_uint32 (sorted[cnt]->from) + 1; | ||
1978 | srunp = sorted[cnt]->to; | ||
1979 | while (srunp != NULL) | ||
1980 | { | ||
1981 | - to_len += wcslen ((const wchar_t *) srunp->str) + 1; | ||
1982 | + to_len += wcslen_uint32 (srunp->str) + 1; | ||
1983 | srunp = srunp->next; | ||
1984 | } | ||
1985 | /* Plus one for the extra NUL character marking the end of | ||
1986 | @@ -4067,18 +4066,18 @@ | ||
1987 | ctype->translit_from_idx[cnt] = from_len; | ||
1988 | ctype->translit_to_idx[cnt] = to_len; | ||
1989 | |||
1990 | - len = wcslen ((const wchar_t *) sorted[cnt]->from) + 1; | ||
1991 | - wmemcpy ((wchar_t *) &ctype->translit_from_tbl[from_len], | ||
1992 | - (const wchar_t *) sorted[cnt]->from, len); | ||
1993 | + len = wcslen_uint32 (sorted[cnt]->from) + 1; | ||
1994 | + wmemcpy_uint32 (&ctype->translit_from_tbl[from_len], | ||
1995 | + sorted[cnt]->from, len); | ||
1996 | from_len += len; | ||
1997 | |||
1998 | ctype->translit_to_idx[cnt] = to_len; | ||
1999 | srunp = sorted[cnt]->to; | ||
2000 | while (srunp != NULL) | ||
2001 | { | ||
2002 | - len = wcslen ((const wchar_t *) srunp->str) + 1; | ||
2003 | - wmemcpy ((wchar_t *) &ctype->translit_to_tbl[to_len], | ||
2004 | - (const wchar_t *) srunp->str, len); | ||
2005 | + len = wcslen_uint32 (srunp->str) + 1; | ||
2006 | + wmemcpy_uint32 (&ctype->translit_to_tbl[to_len], | ||
2007 | + srunp->str, len); | ||
2008 | to_len += len; | ||
2009 | srunp = srunp->next; | ||
2010 | } | ||
2011 | Index: git/locale/programs/ld-messages.c | ||
2012 | =================================================================== | ||
2013 | --- git.orig/locale/programs/ld-messages.c 2014-08-29 20:00:47.412070587 -0700 | ||
2014 | +++ git/locale/programs/ld-messages.c 2014-08-29 20:01:15.208070587 -0700 | ||
2015 | @@ -25,6 +25,7 @@ | ||
2016 | #include <string.h> | ||
2017 | #include <stdint.h> | ||
2018 | #include <sys/uio.h> | ||
2019 | +#include <gnu/option-groups.h> | ||
2020 | |||
2021 | #include <assert.h> | ||
2022 | |||
2023 | @@ -124,6 +125,7 @@ | ||
2024 | } | ||
2025 | else | ||
2026 | { | ||
2027 | +#if __OPTION_POSIX_REGEXP | ||
2028 | int result; | ||
2029 | regex_t re; | ||
2030 | |||
2031 | @@ -140,6 +142,7 @@ | ||
2032 | } | ||
2033 | else if (result != 0) | ||
2034 | regfree (&re); | ||
2035 | +#endif | ||
2036 | } | ||
2037 | |||
2038 | if (messages->noexpr == NULL) | ||
2039 | @@ -158,6 +161,7 @@ | ||
2040 | } | ||
2041 | else | ||
2042 | { | ||
2043 | +#if __OPTION_POSIX_REGEXP | ||
2044 | int result; | ||
2045 | regex_t re; | ||
2046 | |||
2047 | @@ -174,6 +178,7 @@ | ||
2048 | } | ||
2049 | else if (result != 0) | ||
2050 | regfree (&re); | ||
2051 | +#endif | ||
2052 | } | ||
2053 | } | ||
2054 | |||
2055 | Index: git/locale/programs/ld-time.c | ||
2056 | =================================================================== | ||
2057 | --- git.orig/locale/programs/ld-time.c 2014-08-29 20:00:47.412070587 -0700 | ||
2058 | +++ git/locale/programs/ld-time.c 2014-08-29 20:01:15.208070587 -0700 | ||
2059 | @@ -215,8 +215,10 @@ | ||
2060 | } | ||
2061 | else | ||
2062 | { | ||
2063 | + static const uint32_t wt_fmt_ampm[] | ||
2064 | + = { '%','I',':','%','M',':','%','S',' ','%','p',0 }; | ||
2065 | time->t_fmt_ampm = "%I:%M:%S %p"; | ||
2066 | - time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p"; | ||
2067 | + time->wt_fmt_ampm = wt_fmt_ampm; | ||
2068 | } | ||
2069 | } | ||
2070 | |||
2071 | @@ -226,7 +228,7 @@ | ||
2072 | const int days_per_month[12] = { 31, 29, 31, 30, 31, 30, | ||
2073 | 31, 31, 30, 31 ,30, 31 }; | ||
2074 | size_t idx; | ||
2075 | - wchar_t *wstr; | ||
2076 | + uint32_t *wstr; | ||
2077 | |||
2078 | time->era_entries = | ||
2079 | (struct era_data *) xmalloc (time->num_era | ||
2080 | @@ -464,18 +466,18 @@ | ||
2081 | } | ||
2082 | |||
2083 | /* Now generate the wide character name and format. */ | ||
2084 | - wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */ | ||
2085 | - wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end offset */ | ||
2086 | - wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end start */ | ||
2087 | - wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end end */ | ||
2088 | + wstr = wcschr_uint32 (time->wera[idx], L':'); /* end direction */ | ||
2089 | + wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end offset */ | ||
2090 | + wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end start */ | ||
2091 | + wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end end */ | ||
2092 | if (wstr != NULL) | ||
2093 | { | ||
2094 | - time->era_entries[idx].wname = (uint32_t *) wstr + 1; | ||
2095 | - wstr = wcschr (wstr + 1, L':'); /* end name */ | ||
2096 | + time->era_entries[idx].wname = wstr + 1; | ||
2097 | + wstr = wcschr_uint32 (wstr + 1, L':'); /* end name */ | ||
2098 | if (wstr != NULL) | ||
2099 | { | ||
2100 | *wstr = L'\0'; | ||
2101 | - time->era_entries[idx].wformat = (uint32_t *) wstr + 1; | ||
2102 | + time->era_entries[idx].wformat = wstr + 1; | ||
2103 | } | ||
2104 | else | ||
2105 | time->era_entries[idx].wname = | ||
2106 | @@ -530,7 +532,16 @@ | ||
2107 | if (time->date_fmt == NULL) | ||
2108 | time->date_fmt = "%a %b %e %H:%M:%S %Z %Y"; | ||
2109 | if (time->wdate_fmt == NULL) | ||
2110 | - time->wdate_fmt = (const uint32_t *) L"%a %b %e %H:%M:%S %Z %Y"; | ||
2111 | + { | ||
2112 | + static const uint32_t wdate_fmt[] = | ||
2113 | + { '%','a',' ', | ||
2114 | + '%','b',' ', | ||
2115 | + '%','e',' ', | ||
2116 | + '%','H',':','%','M',':','%','S',' ', | ||
2117 | + '%','Z',' ', | ||
2118 | + '%','Y',0 }; | ||
2119 | + time->wdate_fmt = wdate_fmt; | ||
2120 | + } | ||
2121 | } | ||
2122 | |||
2123 | |||
2124 | Index: git/locale/programs/linereader.c | ||
2125 | =================================================================== | ||
2126 | --- git.orig/locale/programs/linereader.c 2014-08-29 20:00:47.412070587 -0700 | ||
2127 | +++ git/locale/programs/linereader.c 2014-08-29 20:01:15.208070587 -0700 | ||
2128 | @@ -595,7 +595,7 @@ | ||
2129 | { | ||
2130 | int return_widestr = lr->return_widestr; | ||
2131 | char *buf; | ||
2132 | - wchar_t *buf2 = NULL; | ||
2133 | + uint32_t *buf2 = NULL; | ||
2134 | size_t bufact; | ||
2135 | size_t bufmax = 56; | ||
2136 | |||
2137 | Index: git/locale/programs/localedef.c | ||
2138 | =================================================================== | ||
2139 | --- git.orig/locale/programs/localedef.c 2014-08-29 20:00:47.416070587 -0700 | ||
2140 | +++ git/locale/programs/localedef.c 2014-08-29 20:01:15.208070587 -0700 | ||
2141 | @@ -114,6 +114,7 @@ | ||
2142 | #define OPT_LIST_ARCHIVE 309 | ||
2143 | #define OPT_LITTLE_ENDIAN 400 | ||
2144 | #define OPT_BIG_ENDIAN 401 | ||
2145 | +#define OPT_UINT32_ALIGN 402 | ||
2146 | |||
2147 | /* Definitions of arguments for argp functions. */ | ||
2148 | static const struct argp_option options[] = | ||
2149 | @@ -150,6 +151,8 @@ | ||
2150 | N_("Generate little-endian output") }, | ||
2151 | { "big-endian", OPT_BIG_ENDIAN, NULL, 0, | ||
2152 | N_("Generate big-endian output") }, | ||
2153 | + { "uint32-align", OPT_UINT32_ALIGN, "ALIGNMENT", 0, | ||
2154 | + N_("Set the target's uint32_t alignment in bytes (default 4)") }, | ||
2155 | { NULL, 0, NULL, 0, NULL } | ||
2156 | }; | ||
2157 | |||
2158 | @@ -239,12 +242,14 @@ | ||
2159 | ctype locale. (P1003.2 4.35.5.2) */ | ||
2160 | setlocale (LC_CTYPE, "POSIX"); | ||
2161 | |||
2162 | +#ifndef NO_SYSCONF | ||
2163 | /* Look whether the system really allows locale definitions. POSIX | ||
2164 | defines error code 3 for this situation so I think it must be | ||
2165 | a fatal error (see P1003.2 4.35.8). */ | ||
2166 | if (sysconf (_SC_2_LOCALEDEF) < 0) | ||
2167 | WITH_CUR_LOCALE (error (3, 0, _("\ | ||
2168 | FATAL: system does not define `_POSIX2_LOCALEDEF'"))); | ||
2169 | +#endif | ||
2170 | |||
2171 | /* Process charmap file. */ | ||
2172 | charmap = charmap_read (charmap_file, verbose, 1, be_quiet, 1); | ||
2173 | @@ -338,6 +343,9 @@ | ||
2174 | case OPT_BIG_ENDIAN: | ||
2175 | set_big_endian (true); | ||
2176 | break; | ||
2177 | + case OPT_UINT32_ALIGN: | ||
2178 | + uint32_align_mask = strtol (arg, NULL, 0) - 1; | ||
2179 | + break; | ||
2180 | case 'c': | ||
2181 | force_output = 1; | ||
2182 | break; | ||
2183 | Index: git/locale/programs/locfile.c | ||
2184 | =================================================================== | ||
2185 | --- git.orig/locale/programs/locfile.c 2014-08-29 20:00:47.432070587 -0700 | ||
2186 | +++ git/locale/programs/locfile.c 2014-08-29 20:01:15.208070587 -0700 | ||
2187 | @@ -544,6 +544,9 @@ | ||
2188 | machine running localedef. */ | ||
2189 | bool swap_endianness_p; | ||
2190 | |||
2191 | +/* The target's value of __align__(uint32_t) - 1. */ | ||
2192 | +unsigned int uint32_align_mask = 3; | ||
2193 | + | ||
2194 | /* When called outside a start_locale_structure/end_locale_structure | ||
2195 | or start_locale_prelude/end_locale_prelude block, record that the | ||
2196 | next byte in FILE's obstack will be the first byte of a new element. | ||
2197 | @@ -621,7 +624,7 @@ | ||
2198 | void | ||
2199 | add_locale_wstring (struct locale_file *file, const uint32_t *string) | ||
2200 | { | ||
2201 | - add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1); | ||
2202 | + add_locale_uint32_array (file, string, wcslen_uint32 (string) + 1); | ||
2203 | } | ||
2204 | |||
2205 | /* Record that FILE's next element is the 32-bit integer VALUE. */ | ||
2206 | Index: git/locale/programs/locfile.h | ||
2207 | =================================================================== | ||
2208 | --- git.orig/locale/programs/locfile.h 2014-08-29 20:00:47.432070587 -0700 | ||
2209 | +++ git/locale/programs/locfile.h 2014-08-29 20:01:15.208070587 -0700 | ||
2210 | @@ -71,6 +71,8 @@ | ||
2211 | |||
2212 | extern bool swap_endianness_p; | ||
2213 | |||
2214 | +extern unsigned int uint32_align_mask; | ||
2215 | + | ||
2216 | /* Change the output to be big-endian if BIG_ENDIAN is true and | ||
2217 | little-endian otherwise. */ | ||
2218 | static inline void | ||
2219 | @@ -275,4 +277,49 @@ | ||
2220 | const struct charmap_t *charmap, | ||
2221 | const char *output_path); | ||
2222 | |||
2223 | +static inline size_t | ||
2224 | +wcslen_uint32 (const uint32_t *str) | ||
2225 | +{ | ||
2226 | + size_t len = 0; | ||
2227 | + while (str[len] != 0) | ||
2228 | + len++; | ||
2229 | + return len; | ||
2230 | +} | ||
2231 | + | ||
2232 | +static inline int | ||
2233 | +wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n) | ||
2234 | +{ | ||
2235 | + while (n-- != 0) | ||
2236 | + { | ||
2237 | + int diff = *s1++ - *s2++; | ||
2238 | + if (diff != 0) | ||
2239 | + return diff; | ||
2240 | + } | ||
2241 | + return 0; | ||
2242 | +} | ||
2243 | + | ||
2244 | +static inline int | ||
2245 | +wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2) | ||
2246 | +{ | ||
2247 | + while (*s1 != 0 && *s1 == *s2) | ||
2248 | + s1++, s2++; | ||
2249 | + return *s1 - *s2; | ||
2250 | +} | ||
2251 | + | ||
2252 | +static inline uint32_t * | ||
2253 | +wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n) | ||
2254 | +{ | ||
2255 | + return memcpy (s1, s2, n * sizeof (uint32_t)); | ||
2256 | +} | ||
2257 | + | ||
2258 | +static inline uint32_t * | ||
2259 | +wcschr_uint32 (const uint32_t *s, uint32_t ch) | ||
2260 | +{ | ||
2261 | + do | ||
2262 | + if (*s == ch) | ||
2263 | + return (uint32_t *) s; | ||
2264 | + while (*s++ != 0); | ||
2265 | + return 0; | ||
2266 | +} | ||
2267 | + | ||
2268 | #endif /* locfile.h */ | ||
2269 | Index: git/locale/setlocale.c | ||
2270 | =================================================================== | ||
2271 | --- git.orig/locale/setlocale.c 2014-08-29 20:00:47.432070587 -0700 | ||
2272 | +++ git/locale/setlocale.c 2014-08-29 20:01:15.208070587 -0700 | ||
2273 | @@ -64,36 +64,6 @@ | ||
2274 | #endif | ||
2275 | |||
2276 | |||
2277 | -/* Define an array of category names (also the environment variable names). */ | ||
2278 | -const union catnamestr_t _nl_category_names attribute_hidden = | ||
2279 | - { | ||
2280 | - { | ||
2281 | -#define DEFINE_CATEGORY(category, category_name, items, a) \ | ||
2282 | - category_name, | ||
2283 | -#include "categories.def" | ||
2284 | -#undef DEFINE_CATEGORY | ||
2285 | - } | ||
2286 | - }; | ||
2287 | - | ||
2288 | -const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden = | ||
2289 | - { | ||
2290 | -#define DEFINE_CATEGORY(category, category_name, items, a) \ | ||
2291 | - [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)), | ||
2292 | -#include "categories.def" | ||
2293 | -#undef DEFINE_CATEGORY | ||
2294 | - }; | ||
2295 | - | ||
2296 | -/* An array of their lengths, for convenience. */ | ||
2297 | -const uint8_t _nl_category_name_sizes[] attribute_hidden = | ||
2298 | - { | ||
2299 | -#define DEFINE_CATEGORY(category, category_name, items, a) \ | ||
2300 | - [category] = sizeof (category_name) - 1, | ||
2301 | -#include "categories.def" | ||
2302 | -#undef DEFINE_CATEGORY | ||
2303 | - [LC_ALL] = sizeof ("LC_ALL") - 1 | ||
2304 | - }; | ||
2305 | - | ||
2306 | - | ||
2307 | #ifdef NL_CURRENT_INDIRECT | ||
2308 | # define WEAK_POSTLOAD(postload) weak_extern (postload) | ||
2309 | #else | ||
2310 | Index: git/locale/xlocale.c | ||
2311 | =================================================================== | ||
2312 | --- git.orig/locale/xlocale.c 2014-08-29 20:00:47.436070587 -0700 | ||
2313 | +++ git/locale/xlocale.c 2014-08-29 20:01:15.208070587 -0700 | ||
2314 | @@ -18,6 +18,7 @@ | ||
2315 | <http://www.gnu.org/licenses/>. */ | ||
2316 | |||
2317 | #include <locale.h> | ||
2318 | +#include <gnu/option-groups.h> | ||
2319 | #include "localeinfo.h" | ||
2320 | |||
2321 | #define DEFINE_CATEGORY(category, category_name, items, a) \ | ||
2322 | @@ -25,6 +26,19 @@ | ||
2323 | #include "categories.def" | ||
2324 | #undef DEFINE_CATEGORY | ||
2325 | |||
2326 | +/* If the locale support code isn't enabled, don't generate strong | ||
2327 | + reference to the C locale_data structures here; let the Makefile | ||
2328 | + decide which ones to include. (In the static linking case, the | ||
2329 | + strong reference to the 'class', 'toupper', and 'tolower' tables | ||
2330 | + will cause C-ctype.o to be brought in, as it should be, even when | ||
2331 | + the reference to _nl_C_LC_CTYPE will be weak.) */ | ||
2332 | +#if ! __OPTION_EGLIBC_LOCALE_CODE | ||
2333 | +# define DEFINE_CATEGORY(category, category_name, items, a) \ | ||
2334 | + weak_extern (_nl_C_##category) | ||
2335 | +# include "categories.def" | ||
2336 | +# undef DEFINE_CATEGORY | ||
2337 | +#endif | ||
2338 | + | ||
2339 | /* Defined in locale/C-ctype.c. */ | ||
2340 | extern const char _nl_C_LC_CTYPE_class[] attribute_hidden; | ||
2341 | extern const char _nl_C_LC_CTYPE_toupper[] attribute_hidden; | ||
2342 | @@ -52,3 +66,26 @@ | ||
2343 | .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128, | ||
2344 | .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128 | ||
2345 | }; | ||
2346 | + | ||
2347 | + | ||
2348 | +#if ! __OPTION_EGLIBC_LOCALE_CODE | ||
2349 | +/* When locale code is enabled, these are each defined in the | ||
2350 | + appropriate lc-CATEGORY.c file, so that static links (when __thread | ||
2351 | + is supported) bring in only those lc-CATEGORY.o files for | ||
2352 | + categories the program actually uses; look for NL_CURRENT_INDIRECT | ||
2353 | + in localeinfo.h. | ||
2354 | + | ||
2355 | + When locale code is disabled, the _nl_C_CATEGORY objects are the | ||
2356 | + only possible referents. At the moment, there isn't a way to get | ||
2357 | + __OPTION_EGLIBC_LOCALE_CODE defined in every compilation unit that | ||
2358 | + #includes localeinfo.h, so we can't just turn off | ||
2359 | + NL_CURRENT_INDIRECT. So we'll define the _nl_current_CATEGORY | ||
2360 | + pointers here. */ | ||
2361 | +#if defined (NL_CURRENT_INDIRECT) | ||
2362 | +#define DEFINE_CATEGORY(category, category_name, items, a) \ | ||
2363 | + __thread struct __locale_data * const *_nl_current_##category \ | ||
2364 | + attribute_hidden = &_nl_C_locobj.__locales[category]; | ||
2365 | +#include "categories.def" | ||
2366 | +#undef DEFINE_CATEGORY | ||
2367 | +#endif | ||
2368 | +#endif /* __OPTION_EGLIBC_LOCALE_CODE */ | ||
2369 | Index: git/localedata/Makefile | ||
2370 | =================================================================== | ||
2371 | --- git.orig/localedata/Makefile 2014-08-29 20:00:47.444070587 -0700 | ||
2372 | +++ git/localedata/Makefile 2014-08-29 20:01:15.212070587 -0700 | ||
2373 | @@ -21,12 +21,22 @@ | ||
2374 | |||
2375 | include ../Makeconfig | ||
2376 | |||
2377 | -# List with all available character set descriptions. | ||
2378 | -charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*) | ||
2379 | +include ../option-groups.mak | ||
2380 | |||
2381 | # List with all available character set descriptions. | ||
2382 | -locales := $(wildcard locales/*) | ||
2383 | +all-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*) | ||
2384 | + | ||
2385 | +all-locales := $(wildcard locales/*) | ||
2386 | |||
2387 | +# If the EGLIBC_LOCALES option group is not enabled, trim the | ||
2388 | +# list of charmap and locale source files. | ||
2389 | +ifeq ($(OPTION_EGLIBC_LOCALES),y) | ||
2390 | +charmaps := $(all-charmaps) | ||
2391 | +locales := $(all-locales) | ||
2392 | +else | ||
2393 | +charmaps := | ||
2394 | +locales := locales/POSIX | ||
2395 | +endif | ||
2396 | |||
2397 | subdir-dirs = tests-mbwc | ||
2398 | vpath %.c tests-mbwc | ||
2399 | @@ -71,14 +81,20 @@ | ||
2400 | tst_wcsxfrm tst_wctob tst_wctomb tst_wctrans \ | ||
2401 | tst_wctype tst_wcwidth | ||
2402 | |||
2403 | -tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ | ||
2404 | +# Since these tests build their own locale files, they're not | ||
2405 | +# dependent on the OPTION_EGLIBC_LOCALES option group. But they do | ||
2406 | +# need the locale functions to be present. | ||
2407 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
2408 | + += $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ | ||
2409 | tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \ | ||
2410 | tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \ | ||
2411 | tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \ | ||
2412 | tst-wctype | ||
2413 | +ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE)) | ||
2414 | tests-static = bug-setlocale1-static | ||
2415 | tests += $(tests-static) | ||
2416 | -ifeq (yes,$(build-shared)) | ||
2417 | +endif | ||
2418 | +ifeq (yesy,$(build-shared)$(OPTION_EGLIBC_LOCALE_CODE)) | ||
2419 | ifneq (no,$(PERL)) | ||
2420 | tests-special += $(objpfx)mtrace-tst-leaks.out | ||
2421 | endif | ||
2422 | @@ -92,12 +108,14 @@ | ||
2423 | |||
2424 | tests: $(objdir)/iconvdata/gconv-modules | ||
2425 | |||
2426 | +ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE)) | ||
2427 | tests-special += $(objpfx)sort-test.out $(objpfx)tst-fmon.out \ | ||
2428 | $(objpfx)tst-locale.out $(objpfx)tst-rpmatch.out \ | ||
2429 | $(objpfx)tst-trans.out $(objpfx)tst-ctype.out \ | ||
2430 | $(objpfx)tst-langinfo.out $(objpfx)tst-langinfo-static.out \ | ||
2431 | $(objpfx)tst-numeric.out | ||
2432 | tests-static += tst-langinfo-static | ||
2433 | +endif | ||
2434 | |||
2435 | ifeq ($(run-built-tests),yes) | ||
2436 | # We have to generate locales | ||
2437 | @@ -143,9 +161,13 @@ | ||
2438 | $(addprefix $(objpfx),$(CTYPE_FILES)): %: \ | ||
2439 | gen-locale.sh $(common-objpfx)locale/localedef Makefile \ | ||
2440 | $(addprefix charmaps/,$(CHARMAPS)) $(addprefix locales/,$(LOCALE_SRCS)) | ||
2441 | - @$(SHELL) gen-locale.sh $(common-objpfx) \ | ||
2442 | - '$(built-program-cmd-before-env)' '$(run-program-env)' \ | ||
2443 | - '$(built-program-cmd-after-env)' $@; \ | ||
2444 | + @$(SHELL) gen-locale.sh $(common-objpfx) \ | ||
2445 | + '$(if $(cross-localedef), \ | ||
2446 | + $(cross-localedef), \ | ||
2447 | + $(built-program-cmd-before-env) \ | ||
2448 | + $(run-program-env) \ | ||
2449 | + $(built-program-cmd-after-env))' \ | ||
2450 | + $@; \ | ||
2451 | $(evaluate-test) | ||
2452 | |||
2453 | $(addsuffix .out,$(addprefix $(objpfx),$(tests))): %: \ | ||
2454 | @@ -213,6 +235,11 @@ | ||
2455 | |||
2456 | include SUPPORTED | ||
2457 | |||
2458 | +# Only install locale data if OPTION_EGLIBC_LOCALES is selected. | ||
2459 | +ifneq ($(OPTION_EGLIBC_LOCALES),y) | ||
2460 | +SUPPORTED-LOCALES := | ||
2461 | +endif | ||
2462 | + | ||
2463 | INSTALL-SUPPORTED-LOCALES=$(addprefix install-, $(SUPPORTED-LOCALES)) | ||
2464 | |||
2465 | # Sometimes the whole collection of locale files should be installed. | ||
2466 | Index: git/login/Makefile | ||
2467 | =================================================================== | ||
2468 | --- git.orig/login/Makefile 2014-08-29 20:00:47.736070587 -0700 | ||
2469 | +++ git/login/Makefile 2014-08-29 20:01:15.212070587 -0700 | ||
2470 | @@ -18,6 +18,7 @@ | ||
2471 | # | ||
2472 | # Sub-makefile for login portion of the library. | ||
2473 | # | ||
2474 | +include ../option-groups.mak | ||
2475 | |||
2476 | subdir := login | ||
2477 | |||
2478 | @@ -25,14 +26,16 @@ | ||
2479 | |||
2480 | headers := utmp.h bits/utmp.h lastlog.h pty.h | ||
2481 | |||
2482 | -routines := getlogin getlogin_r setlogin getlogin_r_chk \ | ||
2483 | - getutent getutent_r getutid getutline getutid_r getutline_r \ | ||
2484 | - utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \ | ||
2485 | - ptsname_r_chk | ||
2486 | +routines := getpt grantpt unlockpt ptsname ptsname_r_chk | ||
2487 | +routines-$(OPTION_EGLIBC_UTMP) \ | ||
2488 | + += getutent getutent_r getutid getutline getutid_r getutline_r \ | ||
2489 | + utmp_file utmpname updwtmp | ||
2490 | +routines-$(OPTION_EGLIBC_GETLOGIN) += getlogin getlogin_r getlogin_r_chk | ||
2491 | +routines-$(OPTION_EGLIBC_BSD) += setlogin | ||
2492 | |||
2493 | CFLAGS-grantpt.c = -DLIBEXECDIR='"$(libexecdir)"' | ||
2494 | |||
2495 | -others = utmpdump | ||
2496 | +others-$(OPTION_EGLIBC_UTMP) += utmpdump | ||
2497 | |||
2498 | ifeq (yes,$(build-pt-chown)) | ||
2499 | others += pt_chown | ||
2500 | @@ -46,8 +49,8 @@ | ||
2501 | tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname | ||
2502 | |||
2503 | # Build the -lutil library with these extra functions. | ||
2504 | -extra-libs := libutil | ||
2505 | -extra-libs-others := $(extra-libs) | ||
2506 | +extra-libs-$(OPTION_EGLIBC_UTMP) := libutil | ||
2507 | +extra-libs-others := $(extra-libs-y) | ||
2508 | |||
2509 | libutil-routines:= login login_tty logout logwtmp openpty forkpty | ||
2510 | |||
2511 | Index: git/Makeconfig | ||
2512 | =================================================================== | ||
2513 | --- git.orig/Makeconfig 2014-08-29 20:00:42.956070587 -0700 | ||
2514 | +++ git/Makeconfig 2014-08-29 20:01:15.212070587 -0700 | ||
2515 | @@ -582,7 +582,7 @@ | ||
2516 | # and run on the build system, causes that program with those | ||
2517 | # arguments to be run on the host for which the library is built. | ||
2518 | ifndef test-wrapper | ||
2519 | -test-wrapper = | ||
2520 | +test-wrapper = $(cross-test-wrapper) | ||
2521 | endif | ||
2522 | # Likewise, but the name of the program is preceded by | ||
2523 | # <variable>=<value> assignments for environment variables. | ||
2524 | @@ -1057,6 +1057,24 @@ | ||
2525 | libm = $(common-objpfx)math/libm.a | ||
2526 | endif | ||
2527 | |||
2528 | +# Generate a header file that #defines preprocessor symbols indicating | ||
2529 | +# which option groups are enabled. Note that the option-groups.config file | ||
2530 | +# may not exist at all. | ||
2531 | +before-compile += $(common-objpfx)gnu/option-groups.h | ||
2532 | +common-generated += gnu/option-groups.h gnu/option-groups.stmp | ||
2533 | +headers += gnu/option-groups.h | ||
2534 | +$(common-objpfx)gnu/option-groups.h: $(common-objpfx)gnu/option-groups.stmp; @: | ||
2535 | +$(common-objpfx)gnu/option-groups.stmp: \ | ||
2536 | + $(..)scripts/option-groups.awk \ | ||
2537 | + $(..)option-groups.defaults \ | ||
2538 | + $(wildcard $(common-objpfx)option-groups.config) | ||
2539 | + $(make-target-directory) | ||
2540 | + @rm -f ${@:stmp=T} $@ | ||
2541 | + LC_ALL=C $(AWK) -f $^ > ${@:stmp=T} | ||
2542 | + $(move-if-change) ${@:stmp=T} ${@:stmp=h} | ||
2543 | + touch $@ | ||
2544 | + | ||
2545 | + | ||
2546 | # These are the subdirectories containing the library source. The order | ||
2547 | # is more or less arbitrary. The sorting step will take care of the | ||
2548 | # dependencies. | ||
2549 | Index: git/Makerules | ||
2550 | =================================================================== | ||
2551 | --- git.orig/Makerules 2014-08-29 20:00:42.960070587 -0700 | ||
2552 | +++ git/Makerules 2014-08-29 20:01:15.212070587 -0700 | ||
2553 | @@ -379,6 +379,25 @@ | ||
2554 | endef | ||
2555 | endif | ||
2556 | |||
2557 | +# Include targets in the selected option groups. | ||
2558 | +aux += $(aux-y) | ||
2559 | +extra-libs += $(extra-libs-y) | ||
2560 | +extra-libs-others += $(extra-libs-others-y) | ||
2561 | +extra-objs += $(extra-objs-y) | ||
2562 | +install-bin += $(install-bin-y) | ||
2563 | +install-others += $(install-others-y) | ||
2564 | +install-sbin += $(install-sbin-y) | ||
2565 | +modules += $(modules-y) | ||
2566 | +others += $(others-y) | ||
2567 | +others-pie += $(others-pie-y) | ||
2568 | +routines += $(routines-y) | ||
2569 | +static-only-routines += $(static-only-routines-y) | ||
2570 | +sysdep_routines += $(sysdep_routines-y) | ||
2571 | +test-srcs += $(test-srcs-y) | ||
2572 | +tests += $(tests-y) | ||
2573 | +xtests += $(xtests-y) | ||
2574 | + | ||
2575 | + | ||
2576 | # Modify the list of routines we build for different targets | ||
2577 | |||
2578 | ifeq (yes,$(build-shared)) | ||
2579 | Index: git/malloc/Makefile | ||
2580 | =================================================================== | ||
2581 | --- git.orig/malloc/Makefile 2014-08-29 20:00:47.760070587 -0700 | ||
2582 | +++ git/malloc/Makefile 2014-08-29 20:01:15.212070587 -0700 | ||
2583 | @@ -18,6 +18,8 @@ | ||
2584 | # | ||
2585 | # Makefile for malloc routines | ||
2586 | # | ||
2587 | +include ../option-groups.mak | ||
2588 | + | ||
2589 | subdir := malloc | ||
2590 | |||
2591 | include ../Makeconfig | ||
2592 | @@ -36,9 +38,15 @@ | ||
2593 | non-lib.a := libmcheck.a | ||
2594 | |||
2595 | # Additional library. | ||
2596 | +ifeq ($(OPTION_EGLIBC_MEMUSAGE),y) | ||
2597 | extra-libs = libmemusage | ||
2598 | extra-libs-others = $(extra-libs) | ||
2599 | |||
2600 | +ifdef OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE | ||
2601 | +CPPFLAGS-memusage += -D__OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE=$(OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE) | ||
2602 | +endif | ||
2603 | +endif | ||
2604 | + | ||
2605 | libmemusage-routines = memusage | ||
2606 | libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes)) | ||
2607 | |||
2608 | @@ -67,7 +75,7 @@ | ||
2609 | # Unless we get a test for the availability of libgd which also works | ||
2610 | # for cross-compiling we disable the memusagestat generation in this | ||
2611 | # situation. | ||
2612 | -ifneq ($(cross-compiling),yes) | ||
2613 | +ifeq ($(cross-compiling)$(OPTION_EGLIBC_MEMUSAGE),noy) | ||
2614 | # If the gd library is available we build the `memusagestat' program. | ||
2615 | ifneq ($(LIBGD),no) | ||
2616 | others: $(objpfx)memusage | ||
2617 | Index: git/malloc/memusage.c | ||
2618 | =================================================================== | ||
2619 | --- git.orig/malloc/memusage.c 2014-08-29 20:00:47.768070587 -0700 | ||
2620 | +++ git/malloc/memusage.c 2014-08-29 20:01:15.212070587 -0700 | ||
2621 | @@ -33,6 +33,7 @@ | ||
2622 | #include <stdint.h> | ||
2623 | #include <sys/mman.h> | ||
2624 | #include <sys/time.h> | ||
2625 | +#include <gnu/option-groups.h> | ||
2626 | |||
2627 | #include <memusage.h> | ||
2628 | |||
2629 | @@ -93,7 +94,11 @@ | ||
2630 | #define peak_stack peak_use[1] | ||
2631 | #define peak_total peak_use[2] | ||
2632 | |||
2633 | -#define DEFAULT_BUFFER_SIZE 32768 | ||
2634 | +#ifndef __OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE | ||
2635 | +# define DEFAULT_BUFFER_SIZE 32768 | ||
2636 | +#else | ||
2637 | +# define DEFAULT_BUFFER_SIZE __OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE | ||
2638 | +#endif | ||
2639 | static size_t buffer_size; | ||
2640 | |||
2641 | static int fd = -1; | ||
2642 | Index: git/malloc/memusage.sh | ||
2643 | =================================================================== | ||
2644 | --- git.orig/malloc/memusage.sh 2014-08-29 20:00:47.768070587 -0700 | ||
2645 | +++ git/malloc/memusage.sh 2014-08-29 20:01:15.212070587 -0700 | ||
2646 | @@ -35,7 +35,7 @@ | ||
2647 | |||
2648 | # Print help message | ||
2649 | do_help() { | ||
2650 | - echo $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]... | ||
2651 | + printf $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]... | ||
2652 | Profile memory usage of PROGRAM. | ||
2653 | |||
2654 | -n,--progname=NAME Name of the program file to profile | ||
2655 | Index: git/math/Makefile | ||
2656 | =================================================================== | ||
2657 | --- git.orig/math/Makefile 2014-08-29 20:00:47.836070587 -0700 | ||
2658 | +++ git/math/Makefile 2014-08-29 20:01:15.212070587 -0700 | ||
2659 | @@ -21,6 +21,8 @@ | ||
2660 | |||
2661 | include ../Makeconfig | ||
2662 | |||
2663 | +include ../option-groups.mak | ||
2664 | + | ||
2665 | # Installed header files. | ||
2666 | headers := math.h bits/mathcalls.h bits/mathinline.h bits/huge_val.h \ | ||
2667 | bits/huge_valf.h bits/huge_vall.h bits/inf.h bits/nan.h \ | ||
2668 | @@ -33,8 +35,8 @@ | ||
2669 | |||
2670 | # Build the -lm library. | ||
2671 | |||
2672 | -extra-libs := libm | ||
2673 | -extra-libs-others = $(extra-libs) | ||
2674 | +extra-libs-$(OPTION_EGLIBC_LIBM) := libm | ||
2675 | +extra-libs-others-$(OPTION_EGLIBC_LIBM) = $(extra-libs-$(OPTION_EGLIBC_LIBM)) | ||
2676 | |||
2677 | libm-support = k_standard s_lib_version s_matherr s_signgam \ | ||
2678 | fclrexcpt fgetexcptflg fraiseexcpt fsetexcptflg \ | ||
2679 | Index: git/misc/err.c | ||
2680 | =================================================================== | ||
2681 | --- git.orig/misc/err.c 2014-08-29 20:00:48.232070587 -0700 | ||
2682 | +++ git/misc/err.c 2014-08-29 20:01:15.212070587 -0700 | ||
2683 | @@ -22,6 +22,7 @@ | ||
2684 | #include <errno.h> | ||
2685 | #include <string.h> | ||
2686 | #include <stdio.h> | ||
2687 | +#include <gnu/option-groups.h> | ||
2688 | |||
2689 | #include <wchar.h> | ||
2690 | #define flockfile(s) _IO_flockfile (s) | ||
2691 | @@ -37,6 +38,7 @@ | ||
2692 | va_end (ap); \ | ||
2693 | } | ||
2694 | |||
2695 | +#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
2696 | static void | ||
2697 | convert_and_print (const char *format, __gnuc_va_list ap) | ||
2698 | { | ||
2699 | @@ -81,6 +83,7 @@ | ||
2700 | |||
2701 | __vfwprintf (stderr, wformat, ap); | ||
2702 | } | ||
2703 | +#endif | ||
2704 | |||
2705 | void | ||
2706 | vwarnx (const char *format, __gnuc_va_list ap) | ||
2707 | @@ -88,9 +91,13 @@ | ||
2708 | flockfile (stderr); | ||
2709 | if (_IO_fwide (stderr, 0) > 0) | ||
2710 | { | ||
2711 | +#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
2712 | __fwprintf (stderr, L"%s: ", __progname); | ||
2713 | convert_and_print (format, ap); | ||
2714 | putwc_unlocked (L'\n', stderr); | ||
2715 | +#else | ||
2716 | + abort (); | ||
2717 | +#endif | ||
2718 | } | ||
2719 | else | ||
2720 | { | ||
2721 | @@ -111,6 +118,7 @@ | ||
2722 | flockfile (stderr); | ||
2723 | if (_IO_fwide (stderr, 0) > 0) | ||
2724 | { | ||
2725 | +#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
2726 | __fwprintf (stderr, L"%s: ", __progname); | ||
2727 | if (format) | ||
2728 | { | ||
2729 | @@ -119,6 +127,9 @@ | ||
2730 | } | ||
2731 | __set_errno (error); | ||
2732 | __fwprintf (stderr, L"%m\n"); | ||
2733 | +#else | ||
2734 | + abort (); | ||
2735 | +#endif | ||
2736 | } | ||
2737 | else | ||
2738 | { | ||
2739 | Index: git/misc/error.c | ||
2740 | =================================================================== | ||
2741 | --- git.orig/misc/error.c 2014-08-29 20:00:48.232070587 -0700 | ||
2742 | +++ git/misc/error.c 2014-08-29 20:01:15.212070587 -0700 | ||
2743 | @@ -35,6 +35,7 @@ | ||
2744 | #endif | ||
2745 | |||
2746 | #ifdef _LIBC | ||
2747 | +# include <gnu/option-groups.h> | ||
2748 | # include <libintl.h> | ||
2749 | # include <stdbool.h> | ||
2750 | # include <stdint.h> | ||
2751 | @@ -205,6 +206,7 @@ | ||
2752 | #if _LIBC | ||
2753 | if (_IO_fwide (stderr, 0) > 0) | ||
2754 | { | ||
2755 | +#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
2756 | size_t len = strlen (message) + 1; | ||
2757 | wchar_t *wmessage = NULL; | ||
2758 | mbstate_t st; | ||
2759 | @@ -265,6 +267,9 @@ | ||
2760 | |||
2761 | if (use_malloc) | ||
2762 | free (wmessage); | ||
2763 | +#else | ||
2764 | + abort (); | ||
2765 | +#endif | ||
2766 | } | ||
2767 | else | ||
2768 | #endif | ||
2769 | Index: git/misc/Makefile | ||
2770 | =================================================================== | ||
2771 | --- git.orig/misc/Makefile 2014-08-29 20:00:48.232070587 -0700 | ||
2772 | +++ git/misc/Makefile 2014-08-29 20:01:15.212070587 -0700 | ||
2773 | @@ -19,6 +19,10 @@ | ||
2774 | # Sub-makefile for misc portion of the library. | ||
2775 | # | ||
2776 | |||
2777 | +# Some system-dependent implementations of these functions use option | ||
2778 | +# groups (see sysdeps/unix/sysv/linux/Makefile, for example). | ||
2779 | +include ../option-groups.mak | ||
2780 | + | ||
2781 | subdir := misc | ||
2782 | |||
2783 | include ../Makeconfig | ||
2784 | @@ -46,40 +50,47 @@ | ||
2785 | select pselect \ | ||
2786 | acct chroot fsync sync fdatasync syncfs reboot \ | ||
2787 | gethostid sethostid \ | ||
2788 | - revoke vhangup \ | ||
2789 | + vhangup \ | ||
2790 | swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \ | ||
2791 | mkostemp mkostemp64 mkstemps mkstemps64 mkostemps mkostemps64 \ | ||
2792 | ualarm usleep \ | ||
2793 | gtty stty \ | ||
2794 | ptrace \ | ||
2795 | - fstab mntent mntent_r \ | ||
2796 | + mntent mntent_r \ | ||
2797 | utimes lutimes futimes futimesat \ | ||
2798 | truncate ftruncate truncate64 ftruncate64 \ | ||
2799 | - chflags fchflags \ | ||
2800 | insremque getttyent getusershell getpass ttyslot \ | ||
2801 | syslog syscall daemon \ | ||
2802 | mmap mmap64 munmap mprotect msync madvise mincore remap_file_pages\ | ||
2803 | mlock munlock mlockall munlockall \ | ||
2804 | - efgcvt efgcvt_r qefgcvt qefgcvt_r \ | ||
2805 | hsearch hsearch_r tsearch lsearch \ | ||
2806 | err error ustat \ | ||
2807 | - getsysstats dirname regexp \ | ||
2808 | + getsysstats dirname \ | ||
2809 | getloadavg getclktck \ | ||
2810 | fgetxattr flistxattr fremovexattr fsetxattr getxattr \ | ||
2811 | listxattr lgetxattr llistxattr lremovexattr lsetxattr \ | ||
2812 | removexattr setxattr getauxval ifunc-impl-list | ||
2813 | |||
2814 | +routines-$(OPTION_POSIX_REGEXP) += regexp | ||
2815 | +routines-$(OPTION_EGLIBC_FSTAB) += fstab | ||
2816 | +routines-$(OPTION_EGLIBC_BSD) += chflags fchflags revoke | ||
2817 | +routines-$(OPTION_EGLIBC_FCVT) += efgcvt efgcvt_r qefgcvt qefgcvt_r | ||
2818 | + | ||
2819 | generated += tst-error1.mtrace tst-error1-mem.out | ||
2820 | |||
2821 | aux := init-misc | ||
2822 | install-lib := libg.a | ||
2823 | gpl2lgpl := error.c error.h | ||
2824 | |||
2825 | -tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ | ||
2826 | - tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 | ||
2827 | +tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \ | ||
2828 | + tst-pselect tst-insremque tst-mntent2 bug-hsearch1 | ||
2829 | +tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += tst-error1 | ||
2830 | +tests-$(OPTION_EGLIBC_FCVT) += tst-efgcvt | ||
2831 | ifeq ($(run-built-tests),yes) | ||
2832 | +ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)) | ||
2833 | tests-special += $(objpfx)tst-error1-mem.out | ||
2834 | endif | ||
2835 | +endif | ||
2836 | |||
2837 | CFLAGS-select.c = -fexceptions -fasynchronous-unwind-tables | ||
2838 | CFLAGS-tsearch.c = $(uses-callbacks) | ||
2839 | Index: git/misc/sys/xattr.h | ||
2840 | =================================================================== | ||
2841 | --- git.orig/misc/sys/xattr.h 2014-08-29 20:00:52.644070587 -0700 | ||
2842 | +++ git/misc/sys/xattr.h 2014-08-29 20:01:15.216070587 -0700 | ||
2843 | @@ -26,7 +26,6 @@ | ||
2844 | |||
2845 | /* The following constants should be used for the fifth parameter of | ||
2846 | `*setxattr'. */ | ||
2847 | -#ifndef __USE_KERNEL_XATTR_DEFS | ||
2848 | enum | ||
2849 | { | ||
2850 | XATTR_CREATE = 1, /* set value, fail if attr already exists. */ | ||
2851 | @@ -34,7 +33,6 @@ | ||
2852 | XATTR_REPLACE = 2 /* set value, fail if attr does not exist. */ | ||
2853 | #define XATTR_REPLACE XATTR_REPLACE | ||
2854 | }; | ||
2855 | -#endif | ||
2856 | |||
2857 | /* Set the attribute NAME of the file pointed to by PATH to VALUE (which | ||
2858 | is SIZE bytes long). Return 0 on success, -1 for errors. */ | ||
2859 | Index: git/misc/tst-efgcvt.c | ||
2860 | =================================================================== | ||
2861 | --- git.orig/misc/tst-efgcvt.c 2014-08-29 20:00:52.652070587 -0700 | ||
2862 | +++ git/misc/tst-efgcvt.c 2014-08-29 20:01:15.216070587 -0700 | ||
2863 | @@ -59,7 +59,7 @@ | ||
2864 | { 123.01, -4, 3, "" }, | ||
2865 | { 126.71, -4, 3, "" }, | ||
2866 | { 0.0, 4, 1, "0000" }, | ||
2867 | -#if DBL_MANT_DIG == 53 | ||
2868 | +#if DBL_MANT_DIG == 53 && !(defined __powerpc__ && defined __NO_FPRS__ && !defined _SOFT_FLOAT && !defined _SOFT_DOUBLE) | ||
2869 | { 0x1p-1074, 3, -323, "494" }, | ||
2870 | { -0x1p-1074, 3, -323, "494" }, | ||
2871 | #endif | ||
2872 | Index: git/nis/Makefile | ||
2873 | =================================================================== | ||
2874 | --- git.orig/nis/Makefile 2014-08-29 20:00:52.660070587 -0700 | ||
2875 | +++ git/nis/Makefile 2014-08-29 20:01:15.216070587 -0700 | ||
2876 | @@ -18,6 +18,8 @@ | ||
2877 | # | ||
2878 | # Makefile for NIS/NIS+ part. | ||
2879 | # | ||
2880 | +include ../option-groups.mak | ||
2881 | + | ||
2882 | subdir := nis | ||
2883 | |||
2884 | include ../Makeconfig | ||
2885 | @@ -30,19 +32,26 @@ | ||
2886 | |||
2887 | # These are the databases available for the nis (and perhaps later nisplus) | ||
2888 | # service. This must be a superset of the services in nss. | ||
2889 | -databases = proto service hosts network grp pwd rpc ethers \ | ||
2890 | - spwd netgrp alias publickey | ||
2891 | +databases-y := proto service hosts network grp pwd rpc ethers \ | ||
2892 | + spwd netgrp publickey | ||
2893 | +databases-$(OPTION_EGLIBC_DB_ALIASES) += alias | ||
2894 | |||
2895 | # Specify rules for the nss_* modules. | ||
2896 | -services := nis nisplus compat | ||
2897 | +# The 'compat' module includes nis support, and the 'nss' directory | ||
2898 | +# includes a bare-bones "files" library, so we'll include 'compat' in | ||
2899 | +# OPTION_EGLIBC_NIS. | ||
2900 | +services-y := | ||
2901 | +services-$(OPTION_EGLIBC_NIS) += nis nisplus compat | ||
2902 | + | ||
2903 | +extra-libs-$(OPTION_EGLIBC_NIS) += libnsl | ||
2904 | +extra-libs-y += $(services-y:%=libnss_%) | ||
2905 | |||
2906 | -extra-libs = libnsl $(services:%=libnss_%) | ||
2907 | # These libraries will be built in the `others' pass rather than | ||
2908 | # the `lib' pass, because they depend on libc.so being built already. | ||
2909 | -extra-libs-others = $(extra-libs) | ||
2910 | +extra-libs-others-y += $(extra-libs-y) | ||
2911 | |||
2912 | # The sources are found in the appropriate subdir. | ||
2913 | -subdir-dirs = $(services:%=nss_%) | ||
2914 | +subdir-dirs = $(services-y:%=nss_%) | ||
2915 | vpath %.c $(subdir-dirs) | ||
2916 | |||
2917 | libnsl-routines = yp_xdr ypclnt ypupdate_xdr \ | ||
2918 | @@ -60,11 +69,11 @@ | ||
2919 | libnss_compat-routines := $(addprefix compat-,grp pwd spwd initgroups) | ||
2920 | libnss_compat-inhibit-o = $(filter-out .os,$(object-suffixes)) | ||
2921 | |||
2922 | -libnss_nis-routines := $(addprefix nis-,$(databases)) nis-initgroups \ | ||
2923 | +libnss_nis-routines := $(addprefix nis-,$(databases-y)) nis-initgroups \ | ||
2924 | nss-nis | ||
2925 | libnss_nis-inhibit-o = $(filter-out .os,$(object-suffixes)) | ||
2926 | |||
2927 | -libnss_nisplus-routines := $(addprefix nisplus-,$(databases)) nisplus-parser \ | ||
2928 | +libnss_nisplus-routines := $(addprefix nisplus-,$(databases-y)) nisplus-parser \ | ||
2929 | nss-nisplus nisplus-initgroups | ||
2930 | libnss_nisplus-inhibit-o = $(filter-out .os,$(object-suffixes)) | ||
2931 | |||
2932 | @@ -80,12 +89,12 @@ | ||
2933 | # Target-specific variable setting to link objects using deprecated | ||
2934 | # RPC interfaces with the version of libc.so that makes them available | ||
2935 | # for new links: | ||
2936 | -$(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \ | ||
2937 | +$(services-y:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \ | ||
2938 | libc-for-link = $(libnsl-libc) | ||
2939 | |||
2940 | |||
2941 | ifeq ($(build-shared),yes) | ||
2942 | -$(others:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version) | ||
2943 | +$(others-y:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version) | ||
2944 | else | ||
2945 | -$(others:%=$(objpfx)%): $(objpfx)libnsl.a | ||
2946 | +$(others-y:%=$(objpfx)%): $(objpfx)libnsl.a | ||
2947 | endif | ||
2948 | Index: git/nptl/Makefile | ||
2949 | =================================================================== | ||
2950 | --- git.orig/nptl/Makefile 2014-08-29 20:00:52.704070587 -0700 | ||
2951 | +++ git/nptl/Makefile 2014-08-29 20:01:15.216070587 -0700 | ||
2952 | @@ -18,6 +18,8 @@ | ||
2953 | # | ||
2954 | # Sub-makefile for NPTL portion of the library. | ||
2955 | # | ||
2956 | +include ../option-groups.mak | ||
2957 | + | ||
2958 | subdir := nptl | ||
2959 | |||
2960 | include ../Makeconfig | ||
2961 | @@ -116,7 +118,7 @@ | ||
2962 | pt-raise pt-system \ | ||
2963 | flockfile ftrylockfile funlockfile \ | ||
2964 | sigaction \ | ||
2965 | - herrno res pt-allocrtsig \ | ||
2966 | + pt-allocrtsig \ | ||
2967 | pthread_kill_other_threads \ | ||
2968 | pthread_getaffinity pthread_setaffinity \ | ||
2969 | pthread_attr_getaffinity pthread_attr_setaffinity \ | ||
2970 | @@ -136,6 +138,8 @@ | ||
2971 | # pthread_setgid pthread_setegid pthread_setregid \ | ||
2972 | # pthread_setresgid | ||
2973 | |||
2974 | +libpthread-routines-$(OPTION_EGLIBC_INET) := herrno res | ||
2975 | + | ||
2976 | libpthread-shared-only-routines = version pt-allocrtsig unwind-forcedunwind | ||
2977 | libpthread-static-only-routines = pthread_atfork | ||
2978 | |||
2979 | @@ -210,7 +214,7 @@ | ||
2980 | tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \ | ||
2981 | tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \ | ||
2982 | tst-mutexpi9 \ | ||
2983 | - tst-spin1 tst-spin2 tst-spin3 tst-spin4 \ | ||
2984 | + tst-spin1 tst-spin2 tst-spin3 \ | ||
2985 | tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ | ||
2986 | tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \ | ||
2987 | tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \ | ||
2988 | @@ -244,14 +248,14 @@ | ||
2989 | tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \ | ||
2990 | tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \ | ||
2991 | tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \ | ||
2992 | - tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 tst-cancel25 \ | ||
2993 | + tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel25 \ | ||
2994 | tst-cancel-self tst-cancel-self-cancelstate \ | ||
2995 | tst-cancel-self-canceltype tst-cancel-self-testcancel \ | ||
2996 | tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \ | ||
2997 | tst-flock1 tst-flock2 \ | ||
2998 | tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \ | ||
2999 | tst-signal6 tst-signal7 \ | ||
3000 | - tst-exec1 tst-exec2 tst-exec3 tst-exec4 \ | ||
3001 | + tst-exec2 tst-exec3 tst-exec4 \ | ||
3002 | tst-exit1 tst-exit2 tst-exit3 \ | ||
3003 | tst-stdio1 tst-stdio2 \ | ||
3004 | tst-stack1 tst-stack2 tst-stack3 tst-pthread-getattr \ | ||
3005 | @@ -259,13 +263,12 @@ | ||
3006 | tst-unload \ | ||
3007 | tst-dlsym1 \ | ||
3008 | tst-sysconf \ | ||
3009 | - tst-locale1 tst-locale2 \ | ||
3010 | + tst-locale2 \ | ||
3011 | tst-umask1 \ | ||
3012 | tst-popen1 \ | ||
3013 | tst-clock1 \ | ||
3014 | tst-context1 \ | ||
3015 | tst-sched1 \ | ||
3016 | - tst-backtrace1 \ | ||
3017 | tst-abstime \ | ||
3018 | tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \ | ||
3019 | tst-getpid1 tst-getpid2 tst-getpid3 \ | ||
3020 | @@ -275,6 +278,17 @@ | ||
3021 | tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 | ||
3022 | test-srcs = tst-oddstacklimit | ||
3023 | |||
3024 | +# This test uses the posix_spawn functions. | ||
3025 | +tests-$(OPTION_EGLIBC_SPAWN) += tst-exec1 | ||
3026 | + | ||
3027 | +# This test uses the 'backtrace' functions. | ||
3028 | +tests-$(OPTION_EGLIBC_BACKTRACE) += tst-backtrace1 | ||
3029 | + | ||
3030 | +# This test is written in C++. | ||
3031 | +tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24 | ||
3032 | + | ||
3033 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-locale1 | ||
3034 | + | ||
3035 | # Files which must not be linked with libpthread. | ||
3036 | tests-nolibpthread = tst-unload | ||
3037 | |||
3038 | Index: git/nptl/pthread_create.c | ||
3039 | =================================================================== | ||
3040 | --- git.orig/nptl/pthread_create.c 2014-08-29 20:00:52.764070587 -0700 | ||
3041 | +++ git/nptl/pthread_create.c 2014-08-29 20:01:15.216070587 -0700 | ||
3042 | @@ -31,6 +31,7 @@ | ||
3043 | #include <kernel-features.h> | ||
3044 | #include <exit-thread.h> | ||
3045 | |||
3046 | +#include <gnu/option-groups.h> | ||
3047 | #include <shlib-compat.h> | ||
3048 | |||
3049 | #include <stap-probe.h> | ||
3050 | @@ -240,8 +241,10 @@ | ||
3051 | THREAD_SETMEM (pd, cpuclock_offset, now); | ||
3052 | #endif | ||
3053 | |||
3054 | +#if __OPTION_EGLIBC_INET | ||
3055 | /* Initialize resolver state pointer. */ | ||
3056 | __resp = &pd->res; | ||
3057 | +#endif | ||
3058 | |||
3059 | /* Initialize pointers to locale data. */ | ||
3060 | __ctype_init (); | ||
3061 | @@ -322,8 +325,10 @@ | ||
3062 | /* Run the destructor for the thread-local data. */ | ||
3063 | __nptl_deallocate_tsd (); | ||
3064 | |||
3065 | +#if __OPTION_EGLIBC_INET | ||
3066 | /* Clean up any state libc stored in thread-local variables. */ | ||
3067 | __libc_thread_freeres (); | ||
3068 | +#endif | ||
3069 | |||
3070 | /* If this is the last thread we terminate the process now. We | ||
3071 | do not notify the debugger, it might just irritate it if there | ||
3072 | Index: git/nscd/Makefile | ||
3073 | =================================================================== | ||
3074 | --- git.orig/nscd/Makefile 2014-08-29 20:00:52.948070587 -0700 | ||
3075 | +++ git/nscd/Makefile 2014-08-29 20:01:15.216070587 -0700 | ||
3076 | @@ -18,14 +18,17 @@ | ||
3077 | # | ||
3078 | # Sub-makefile for nscd portion of the library. | ||
3079 | # | ||
3080 | +include ../option-groups.mak | ||
3081 | + | ||
3082 | subdir := nscd | ||
3083 | |||
3084 | include ../Makeconfig | ||
3085 | |||
3086 | ifneq ($(use-nscd),no) | ||
3087 | -routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \ | ||
3088 | +routines-$(OPTION_EGLIBC_INET) += \ | ||
3089 | + nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \ | ||
3090 | nscd_initgroups nscd_getserv_r nscd_netgroup | ||
3091 | -aux := nscd_helper | ||
3092 | +aux-$(OPTION_EGLIBC_INET) += nscd_helper | ||
3093 | endif | ||
3094 | |||
3095 | # To find xmalloc.c | ||
3096 | @@ -37,14 +40,18 @@ | ||
3097 | dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \ | ||
3098 | xmalloc xstrdup aicache initgrcache gai res_hconf \ | ||
3099 | netgroupcache | ||
3100 | - | ||
3101 | +ifneq (y,$(OPTION_EGLIBC_NIS)) | ||
3102 | +# If we haven't build libnsl.so, then we'll need to include our | ||
3103 | +# own copy of nis_hash. | ||
3104 | +nscd-modules += nis_hash | ||
3105 | +endif | ||
3106 | ifeq ($(build-nscd)$(have-thread-library),yesyes) | ||
3107 | |||
3108 | -others += nscd | ||
3109 | -others-pie += nscd | ||
3110 | -install-sbin := nscd | ||
3111 | +others-$(OPTION_EGLIBC_INET) += nscd | ||
3112 | +others-pie-$(OPTION_EGLIBC_INET) += nscd | ||
3113 | +install-sbin-$(OPTION_EGLIBC_INET) += nscd | ||
3114 | |||
3115 | -extra-objs = $(nscd-modules:=.o) | ||
3116 | +extra-objs-$(OPTION_EGLIBC_INET) += $(nscd-modules:=.o) | ||
3117 | |||
3118 | endif | ||
3119 | |||
3120 | @@ -101,7 +108,15 @@ | ||
3121 | $(objpfx)nscd: $(nscd-modules:%=$(objpfx)%.o) | ||
3122 | |||
3123 | ifeq ($(build-shared),yes) | ||
3124 | -$(objpfx)nscd: $(shared-thread-library) $(common-objpfx)nis/libnsl.so | ||
3125 | +$(objpfx)nscd: $(shared-thread-library) | ||
3126 | +else | ||
3127 | +$(objpfx)nscd: $(static-thread-library) | ||
3128 | +endif | ||
3129 | + | ||
3130 | +ifeq (y,$(OPTION_EGLIBC_NIS)) | ||
3131 | +ifeq ($(build-shared),yes) | ||
3132 | +$(objpfx)nscd: $(common-objpfx)nis/libnsl.so | ||
3133 | else | ||
3134 | -$(objpfx)nscd: $(static-thread-library) $(common-objpfx)nis/libnsl.a | ||
3135 | +$(objpfx)nscd: $(common-objpfx)nis/libnsl.a | ||
3136 | +endif | ||
3137 | endif | ||
3138 | Index: git/nscd/nis_hash.c | ||
3139 | =================================================================== | ||
3140 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
3141 | +++ git/nscd/nis_hash.c 2014-08-29 20:01:15.216070587 -0700 | ||
3142 | @@ -0,0 +1,3 @@ | ||
3143 | +/* If OPTION_EGLIBC_NIS is disabled, nscd can't get this from libnsl.so; | ||
3144 | + we need our own copy. */ | ||
3145 | +#include "../nis/nis_hash.c" | ||
3146 | Index: git/nss/fixed-nsswitch.conf | ||
3147 | =================================================================== | ||
3148 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
3149 | +++ git/nss/fixed-nsswitch.conf 2014-08-29 20:01:15.216070587 -0700 | ||
3150 | @@ -0,0 +1,22 @@ | ||
3151 | +# /etc/nsswitch.conf | ||
3152 | +# | ||
3153 | +# Example configuration for fixed name service. | ||
3154 | +# See the description of OPTION_EGLIBC_NSSWITCH in option-groups.def | ||
3155 | +# for details. | ||
3156 | +# | ||
3157 | + | ||
3158 | +aliases: files | ||
3159 | + | ||
3160 | +passwd: files | ||
3161 | +group: files | ||
3162 | +shadow: files | ||
3163 | + | ||
3164 | +hosts: files dns | ||
3165 | +networks: files dns | ||
3166 | + | ||
3167 | +protocols: files | ||
3168 | +services: files | ||
3169 | +ethers: files | ||
3170 | +rpc: files | ||
3171 | + | ||
3172 | +netgroup: files | ||
3173 | Index: git/nss/fixed-nsswitch.functions | ||
3174 | =================================================================== | ||
3175 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
3176 | +++ git/nss/fixed-nsswitch.functions 2014-08-29 20:01:15.216070587 -0700 | ||
3177 | @@ -0,0 +1,121 @@ | ||
3178 | +/* List of functions defined for fixed NSS in GNU C Library. | ||
3179 | + Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc. | ||
3180 | + This file is part of the GNU C Library. | ||
3181 | + | ||
3182 | + The GNU C Library is free software; you can redistribute it and/or | ||
3183 | + modify it under the terms of the GNU Lesser General Public | ||
3184 | + License as published by the Free Software Foundation; either | ||
3185 | + version 2.1 of the License, or (at your option) any later version. | ||
3186 | + | ||
3187 | + The GNU C Library is distributed in the hope that it will be useful, | ||
3188 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3189 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
3190 | + Lesser General Public License for more details. | ||
3191 | + | ||
3192 | + You should have received a copy of the GNU Lesser General Public | ||
3193 | + License along with the GNU C Library; if not, write to the Free | ||
3194 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
3195 | + 02111-1307 USA. */ | ||
3196 | + | ||
3197 | +/* When OPTION_EGLIBC_NSSWITCH is disabled (see option-groups.def), | ||
3198 | + EGLIBC does not use the 'dlopen' and 'dlsym' functions to look for | ||
3199 | + database query functions in the individual name service libraries. | ||
3200 | + Instead, it uses a set of functions chosen at compile time, as | ||
3201 | + directed by the OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS file. This | ||
3202 | + file is a sample of what you might use there. | ||
3203 | + | ||
3204 | + This file is C source code; it should only contain invocations of | ||
3205 | + the following macros: | ||
3206 | + | ||
3207 | + - DEFINE_ENT (DATABASE, SERVICE, X) | ||
3208 | + | ||
3209 | + Declare the 'setXent', 'getXent_r', and 'endXent' functions that | ||
3210 | + query DATABASE using the service library 'libnss_SERVICE.so.2'. | ||
3211 | + DATABASE should be the full name of the database as it appears in | ||
3212 | + 'nsswitch.conf', like 'passwd' or 'aliases'. | ||
3213 | + | ||
3214 | + (The non-reentrant 'getXent' functions are implemented in terms | ||
3215 | + of the reentrant 'getXent_r' functions, so there is no need to | ||
3216 | + refer to them explicitly here.) | ||
3217 | + | ||
3218 | + - DEFINE_GETBY (DATABASE, SERVICE, X, KEY) | ||
3219 | + | ||
3220 | + Declare the 'getXbyKEY_r' functions that query DATABASE using | ||
3221 | + SERVICE. DATABASE and SERVICE are as described above. | ||
3222 | + | ||
3223 | + (The non-reentrant 'getXbyKEY' functions are implemented in terms | ||
3224 | + of the reentrant 'getXbyKEY_r' functions, so there is no need to | ||
3225 | + refer to them explicitly here.) | ||
3226 | + | ||
3227 | + Use the special key 'name3' for the service library function that | ||
3228 | + implements the 'getaddrinfo' function. | ||
3229 | + | ||
3230 | + - DEFINE_GET (DATABASE, SERVICE, QUERY) | ||
3231 | + | ||
3232 | + Declare the 'getQUERY_r' functions that query DATABASE using | ||
3233 | + SERVICE. This is used for functions like 'getpwnam'. | ||
3234 | + | ||
3235 | + (The non-reentrant 'getQUERY' functions are implemented in terms | ||
3236 | + of the reentrant 'getQUERY_r' functions, so there is no need to | ||
3237 | + refer to them explicitly here.) | ||
3238 | + | ||
3239 | + This sample file only includes functions that consult the files in | ||
3240 | + '/etc', and the Domain Name System (DNS). */ | ||
3241 | + | ||
3242 | +/* aliases */ | ||
3243 | +DEFINE_ENT (aliases, files, alias) | ||
3244 | +DEFINE_GETBY (aliases, files, alias, name) | ||
3245 | + | ||
3246 | +/* ethers */ | ||
3247 | +DEFINE_ENT (ethers, files, ether) | ||
3248 | + | ||
3249 | +/* group */ | ||
3250 | +DEFINE_ENT (group, files, gr) | ||
3251 | +DEFINE_GET (group, files, grgid) | ||
3252 | +DEFINE_GET (group, files, grnam) | ||
3253 | + | ||
3254 | +/* hosts */ | ||
3255 | +DEFINE_ENT (hosts, files, host) | ||
3256 | +DEFINE_GETBY (hosts, files, host, addr) | ||
3257 | +DEFINE_GETBY (hosts, files, host, name) | ||
3258 | +DEFINE_GETBY (hosts, files, host, name2) | ||
3259 | +DEFINE_GET (hosts, files, hostton) | ||
3260 | +DEFINE_GET (hosts, files, ntohost) | ||
3261 | +DEFINE_GETBY (hosts, dns, host, addr) | ||
3262 | +DEFINE_GETBY (hosts, dns, host, name) | ||
3263 | +DEFINE_GETBY (hosts, dns, host, name2) | ||
3264 | +DEFINE_GETBY (hosts, dns, host, name3) | ||
3265 | + | ||
3266 | +/* netgroup */ | ||
3267 | +DEFINE_ENT (netgroup, files, netgr) | ||
3268 | + | ||
3269 | +/* networks */ | ||
3270 | +DEFINE_ENT (networks, files, net) | ||
3271 | +DEFINE_GETBY (networks, files, net, name) | ||
3272 | +DEFINE_GETBY (networks, files, net, addr) | ||
3273 | +DEFINE_GETBY (networks, dns, net, name) | ||
3274 | +DEFINE_GETBY (networks, dns, net, addr) | ||
3275 | + | ||
3276 | +/* protocols */ | ||
3277 | +DEFINE_ENT (protocols, files, proto) | ||
3278 | +DEFINE_GETBY (protocols, files, proto, name) | ||
3279 | +DEFINE_GETBY (protocols, files, proto, number) | ||
3280 | + | ||
3281 | +/* passwd */ | ||
3282 | +DEFINE_ENT (passwd, files, pw) | ||
3283 | +DEFINE_GET (passwd, files, pwnam) | ||
3284 | +DEFINE_GET (passwd, files, pwuid) | ||
3285 | + | ||
3286 | +/* rpc */ | ||
3287 | +DEFINE_ENT (rpc, files, rpc) | ||
3288 | +DEFINE_GETBY (rpc, files, rpc, name) | ||
3289 | +DEFINE_GETBY (rpc, files, rpc, number) | ||
3290 | + | ||
3291 | +/* services */ | ||
3292 | +DEFINE_ENT (services, files, serv) | ||
3293 | +DEFINE_GETBY (services, files, serv, name) | ||
3294 | +DEFINE_GETBY (services, files, serv, port) | ||
3295 | + | ||
3296 | +/* shadow */ | ||
3297 | +DEFINE_ENT (shadow, files, sp) | ||
3298 | +DEFINE_GET (shadow, files, spnam) | ||
3299 | Index: git/nss/gen-fixed-nsswitch.c | ||
3300 | =================================================================== | ||
3301 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
3302 | +++ git/nss/gen-fixed-nsswitch.c 2014-08-29 20:01:15.216070587 -0700 | ||
3303 | @@ -0,0 +1,803 @@ | ||
3304 | +/* gen-fixed-nsswitch.c --- generate fixed name service data structures | ||
3305 | + Copyright (C) 1996-1999, 2001-2006, 2007 Free Software Foundation, Inc. | ||
3306 | + This file is part of the GNU C Library. | ||
3307 | + | ||
3308 | + The GNU C Library is free software; you can redistribute it and/or | ||
3309 | + modify it under the terms of the GNU Lesser General Public | ||
3310 | + License as published by the Free Software Foundation; either | ||
3311 | + version 2.1 of the License, or (at your option) any later version. | ||
3312 | + | ||
3313 | + The GNU C Library is distributed in the hope that it will be useful, | ||
3314 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3315 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
3316 | + Lesser General Public License for more details. | ||
3317 | + | ||
3318 | + You should have received a copy of the GNU Lesser General Public | ||
3319 | + License along with the GNU C Library; if not, write to the Free | ||
3320 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
3321 | + 02111-1307 USA. */ | ||
3322 | + | ||
3323 | +#define _GNU_SOURCE | ||
3324 | + | ||
3325 | +#include <stdlib.h> | ||
3326 | +#include <stdio.h> | ||
3327 | +#include <errno.h> | ||
3328 | +#include <string.h> | ||
3329 | +#include <stdarg.h> | ||
3330 | +#include <assert.h> | ||
3331 | +#include <ctype.h> | ||
3332 | + | ||
3333 | +#include "gnu/lib-names.h" | ||
3334 | +#include "nss.h" | ||
3335 | + | ||
3336 | +/* Provide a fallback definition to allow this file to be compiled outside | ||
3337 | + libc. */ | ||
3338 | +#ifndef internal_function | ||
3339 | +# define internal_function | ||
3340 | +#endif | ||
3341 | + | ||
3342 | + | ||
3343 | +/* Simple utilities. */ | ||
3344 | + | ||
3345 | +void __attribute__ ((noreturn)) | ||
3346 | +error (const char *message) | ||
3347 | +{ | ||
3348 | + fprintf (stderr, "%s\n", message); | ||
3349 | + exit (1); | ||
3350 | +} | ||
3351 | + | ||
3352 | + | ||
3353 | +void * | ||
3354 | +check_alloc (void *p) | ||
3355 | +{ | ||
3356 | + if (p) | ||
3357 | + return p; | ||
3358 | + else | ||
3359 | + error ("out of memory"); | ||
3360 | +} | ||
3361 | + | ||
3362 | +void * | ||
3363 | +xmalloc (size_t size) | ||
3364 | +{ | ||
3365 | + return check_alloc (malloc (size)); | ||
3366 | +} | ||
3367 | + | ||
3368 | + | ||
3369 | +/* Format ARGS according to FORMAT, and return the result as a | ||
3370 | + malloc'ed string. */ | ||
3371 | +char * | ||
3372 | +saprintf (const char *format, ...) | ||
3373 | +{ | ||
3374 | + va_list args; | ||
3375 | + size_t len; | ||
3376 | + char *buf; | ||
3377 | + | ||
3378 | + va_start (args, format); | ||
3379 | + len = vsnprintf (NULL, 0, format, args); | ||
3380 | + va_end (args); | ||
3381 | + | ||
3382 | + buf = xmalloc (len + 1); | ||
3383 | + va_start (args, format); | ||
3384 | + assert (len == vsnprintf (buf, len + 1, format, args)); | ||
3385 | + va_end (args); | ||
3386 | + | ||
3387 | + return buf; | ||
3388 | +} | ||
3389 | + | ||
3390 | + | ||
3391 | + | ||
3392 | +/* Data structures representing the configuration file in memory. */ | ||
3393 | + | ||
3394 | +/* These are copied from nsswitch.h. | ||
3395 | + | ||
3396 | + We could simply #include that file, but this program runs on the | ||
3397 | + build machine and links against the build machine's libraries, | ||
3398 | + whereas that header is meant for use by target code; it uses | ||
3399 | + 'libc_hidden_proto', 'internal_function', and related hair. Since | ||
3400 | + we've copied the parsing code, we might as well copy the data | ||
3401 | + structure definitions as well. */ | ||
3402 | + | ||
3403 | +/* Actions performed after lookup finished. */ | ||
3404 | +typedef enum | ||
3405 | +{ | ||
3406 | + NSS_ACTION_CONTINUE, | ||
3407 | + NSS_ACTION_RETURN | ||
3408 | +} lookup_actions; | ||
3409 | + | ||
3410 | + | ||
3411 | +typedef struct service_library | ||
3412 | +{ | ||
3413 | + /* Name of service (`files', `dns', `nis', ...). */ | ||
3414 | + const char *name; | ||
3415 | + /* Pointer to the loaded shared library. */ | ||
3416 | + void *lib_handle; | ||
3417 | + /* And the link to the next entry. */ | ||
3418 | + struct service_library *next; | ||
3419 | +} service_library; | ||
3420 | + | ||
3421 | + | ||
3422 | +/* For mapping a function name to a function pointer. It is known in | ||
3423 | + nsswitch.c:nss_lookup_function that a string pointer for the lookup key | ||
3424 | + is the first member. */ | ||
3425 | +typedef struct | ||
3426 | +{ | ||
3427 | + const char *fct_name; | ||
3428 | + void *fct_ptr; | ||
3429 | +} known_function; | ||
3430 | + | ||
3431 | + | ||
3432 | +typedef struct service_user | ||
3433 | +{ | ||
3434 | + /* And the link to the next entry. */ | ||
3435 | + struct service_user *next; | ||
3436 | + /* Action according to result. */ | ||
3437 | + lookup_actions actions[5]; | ||
3438 | + /* Link to the underlying library object. */ | ||
3439 | + service_library *library; | ||
3440 | + /* Collection of known functions. | ||
3441 | + | ||
3442 | + With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a | ||
3443 | + 'tsearch'-style tree. | ||
3444 | + | ||
3445 | + With OPTION_EGLIBC_NSSWITCH disabled, this is an array of | ||
3446 | + pointers to known_function structures, NULL-terminated. */ | ||
3447 | + union | ||
3448 | + { | ||
3449 | + void *tree; | ||
3450 | + const known_function **array; | ||
3451 | + } known; | ||
3452 | + /* Name of the service (`files', `dns', `nis', ...). */ | ||
3453 | + const char *name; | ||
3454 | +} service_user; | ||
3455 | + | ||
3456 | +/* To access the action based on the status value use this macro. */ | ||
3457 | +#define nss_next_action(ni, status) ((ni)->actions[2 + status]) | ||
3458 | + | ||
3459 | + | ||
3460 | +typedef struct name_database_entry | ||
3461 | +{ | ||
3462 | + /* And the link to the next entry. */ | ||
3463 | + struct name_database_entry *next; | ||
3464 | + /* List of service to be used. */ | ||
3465 | + service_user *service; | ||
3466 | + /* Name of the database. */ | ||
3467 | + const char *name; | ||
3468 | +} name_database_entry; | ||
3469 | + | ||
3470 | + | ||
3471 | +typedef struct name_database | ||
3472 | +{ | ||
3473 | + /* List of all known databases. */ | ||
3474 | + name_database_entry *entry; | ||
3475 | + /* List of libraries with service implementation. */ | ||
3476 | + service_library *library; | ||
3477 | +} name_database; | ||
3478 | + | ||
3479 | + | ||
3480 | + | ||
3481 | +/* Gathering the contents of the FIXED_FUNCTIONS file. */ | ||
3482 | + | ||
3483 | +/* It should be possible to generate this list automatically by | ||
3484 | + looking at the services and databases used in the nsswitch.conf | ||
3485 | + file, and having a hard-coded set of queries supported on each | ||
3486 | + database. */ | ||
3487 | + | ||
3488 | +/* We #include the FIXED_FUNCTIONS file several times to build an | ||
3489 | + array of function structures holding its data. */ | ||
3490 | +enum function_kind { | ||
3491 | + fk_end = 0, /* Last entry. */ | ||
3492 | + fk_setent, /* Like setpwent. */ | ||
3493 | + fk_getent, /* Like getpwent. */ | ||
3494 | + fk_endent, /* Like endpwent. */ | ||
3495 | + fk_getby, /* Like gethostbyname. */ | ||
3496 | + fk_get /* Like getpwnam. */ | ||
3497 | +}; | ||
3498 | + | ||
3499 | + | ||
3500 | +struct function { | ||
3501 | + /* What kind of function this is. */ | ||
3502 | + enum function_kind kind; | ||
3503 | + | ||
3504 | + /* The database and service of the function being hardwired in. */ | ||
3505 | + char *database, *service; | ||
3506 | + | ||
3507 | + /* The kind of entry being queried, for 'fk_setent', 'fk_getent', | ||
3508 | + 'fk_endent', and 'fk_getby' functions. */ | ||
3509 | + char *entry; | ||
3510 | + | ||
3511 | + /* The key, for 'fk_getby' entries. */ | ||
3512 | + char *key; | ||
3513 | + | ||
3514 | + /* The value and key, for 'fk_get' entries. */ | ||
3515 | + char *value_and_key; | ||
3516 | +}; | ||
3517 | + | ||
3518 | + | ||
3519 | +const struct function functions[] = | ||
3520 | + { | ||
3521 | + | ||
3522 | +#define DEFINE_ENT(database, service, entry) \ | ||
3523 | + { fk_setent, #database, #service, #entry }, \ | ||
3524 | + { fk_getent, #database, #service, #entry }, \ | ||
3525 | + { fk_endent, #database, #service, #entry }, | ||
3526 | +#define DEFINE_GETBY(database, service, entry, key) \ | ||
3527 | + { fk_getby, #database, #service, #entry, #key }, | ||
3528 | +#define DEFINE_GET(database, service, value_and_key) \ | ||
3529 | + { fk_get, #database, #service, NULL, NULL, #value_and_key }, | ||
3530 | + | ||
3531 | +#include FIXED_FUNCTIONS | ||
3532 | + | ||
3533 | +#undef DEFINE_ENT | ||
3534 | +#undef DEFINE_GETBY | ||
3535 | +#undef DEFINE_GET | ||
3536 | + | ||
3537 | + { fk_end } | ||
3538 | + }; | ||
3539 | + | ||
3540 | + | ||
3541 | +/* Parsing the config file. Functions copied from nsswitch.c. */ | ||
3542 | + | ||
3543 | +#define __strchrnul strchrnul | ||
3544 | +#define __getline getline | ||
3545 | +#define __strncasecmp strncasecmp | ||
3546 | + | ||
3547 | +/* Prototypes for the local functions. */ | ||
3548 | +static name_database *nss_parse_file (const char *fname) internal_function; | ||
3549 | +static name_database_entry *nss_getline (char *line) internal_function; | ||
3550 | +static service_user *nss_parse_service_list (const char *line) | ||
3551 | + internal_function; | ||
3552 | + | ||
3553 | +static name_database * | ||
3554 | +internal_function | ||
3555 | +nss_parse_file (const char *fname) | ||
3556 | +{ | ||
3557 | + FILE *fp; | ||
3558 | + name_database *result; | ||
3559 | + name_database_entry *last; | ||
3560 | + char *line; | ||
3561 | + size_t len; | ||
3562 | + | ||
3563 | + /* Open the configuration file. */ | ||
3564 | + fp = fopen (fname, "rc"); | ||
3565 | + if (fp == NULL) | ||
3566 | + return NULL; | ||
3567 | + | ||
3568 | + // /* No threads use this stream. */ | ||
3569 | + // __fsetlocking (fp, FSETLOCKING_BYCALLER); | ||
3570 | + | ||
3571 | + result = (name_database *) xmalloc (sizeof (name_database)); | ||
3572 | + | ||
3573 | + result->entry = NULL; | ||
3574 | + result->library = NULL; | ||
3575 | + last = NULL; | ||
3576 | + line = NULL; | ||
3577 | + len = 0; | ||
3578 | + do | ||
3579 | + { | ||
3580 | + name_database_entry *this; | ||
3581 | + ssize_t n; | ||
3582 | + | ||
3583 | + n = __getline (&line, &len, fp); | ||
3584 | + if (n < 0) | ||
3585 | + break; | ||
3586 | + if (line[n - 1] == '\n') | ||
3587 | + line[n - 1] = '\0'; | ||
3588 | + | ||
3589 | + /* Because the file format does not know any form of quoting we | ||
3590 | + can search forward for the next '#' character and if found | ||
3591 | + make it terminating the line. */ | ||
3592 | + *__strchrnul (line, '#') = '\0'; | ||
3593 | + | ||
3594 | + /* If the line is blank it is ignored. */ | ||
3595 | + if (line[0] == '\0') | ||
3596 | + continue; | ||
3597 | + | ||
3598 | + /* Each line completely specifies the actions for a database. */ | ||
3599 | + this = nss_getline (line); | ||
3600 | + if (this != NULL) | ||
3601 | + { | ||
3602 | + if (last != NULL) | ||
3603 | + last->next = this; | ||
3604 | + else | ||
3605 | + result->entry = this; | ||
3606 | + | ||
3607 | + last = this; | ||
3608 | + } | ||
3609 | + } | ||
3610 | + while (!feof_unlocked (fp)); | ||
3611 | + | ||
3612 | + /* Free the buffer. */ | ||
3613 | + free (line); | ||
3614 | + /* Close configuration file. */ | ||
3615 | + fclose (fp); | ||
3616 | + | ||
3617 | + return result; | ||
3618 | +} | ||
3619 | + | ||
3620 | + | ||
3621 | +/* Read the source names: | ||
3622 | + `( <source> ( "[" "!"? (<status> "=" <action> )+ "]" )? )*' | ||
3623 | + */ | ||
3624 | +static service_user * | ||
3625 | +internal_function | ||
3626 | +nss_parse_service_list (const char *line) | ||
3627 | +{ | ||
3628 | + service_user *result = NULL, **nextp = &result; | ||
3629 | + | ||
3630 | + while (1) | ||
3631 | + { | ||
3632 | + service_user *new_service; | ||
3633 | + const char *name; | ||
3634 | + | ||
3635 | + while (isspace (line[0])) | ||
3636 | + ++line; | ||
3637 | + if (line[0] == '\0') | ||
3638 | + /* No source specified. */ | ||
3639 | + return result; | ||
3640 | + | ||
3641 | + /* Read <source> identifier. */ | ||
3642 | + name = line; | ||
3643 | + while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[') | ||
3644 | + ++line; | ||
3645 | + if (name == line) | ||
3646 | + return result; | ||
3647 | + | ||
3648 | + | ||
3649 | + new_service = (service_user *) xmalloc (sizeof (*new_service)); | ||
3650 | + new_service->name = (char *) xmalloc (line - name + 1); | ||
3651 | + | ||
3652 | + *((char *) __mempcpy ((char *) new_service->name, name, line - name)) | ||
3653 | + = '\0'; | ||
3654 | + | ||
3655 | + /* Set default actions. */ | ||
3656 | + new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE; | ||
3657 | + new_service->actions[2 + NSS_STATUS_UNAVAIL] = NSS_ACTION_CONTINUE; | ||
3658 | + new_service->actions[2 + NSS_STATUS_NOTFOUND] = NSS_ACTION_CONTINUE; | ||
3659 | + new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN; | ||
3660 | + new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN; | ||
3661 | + new_service->library = NULL; | ||
3662 | + new_service->known.tree = NULL; | ||
3663 | + new_service->next = NULL; | ||
3664 | + | ||
3665 | + while (isspace (line[0])) | ||
3666 | + ++line; | ||
3667 | + | ||
3668 | + if (line[0] == '[') | ||
3669 | + { | ||
3670 | + /* Read criterions. */ | ||
3671 | + do | ||
3672 | + ++line; | ||
3673 | + while (line[0] != '\0' && isspace (line[0])); | ||
3674 | + | ||
3675 | + do | ||
3676 | + { | ||
3677 | + int not; | ||
3678 | + enum nss_status status; | ||
3679 | + lookup_actions action; | ||
3680 | + | ||
3681 | + /* Grok ! before name to mean all statii but that one. */ | ||
3682 | + not = line[0] == '!'; | ||
3683 | + if (not) | ||
3684 | + ++line; | ||
3685 | + | ||
3686 | + /* Read status name. */ | ||
3687 | + name = line; | ||
3688 | + while (line[0] != '\0' && !isspace (line[0]) && line[0] != '=' | ||
3689 | + && line[0] != ']') | ||
3690 | + ++line; | ||
3691 | + | ||
3692 | + /* Compare with known statii. */ | ||
3693 | + if (line - name == 7) | ||
3694 | + { | ||
3695 | + if (__strncasecmp (name, "SUCCESS", 7) == 0) | ||
3696 | + status = NSS_STATUS_SUCCESS; | ||
3697 | + else if (__strncasecmp (name, "UNAVAIL", 7) == 0) | ||
3698 | + status = NSS_STATUS_UNAVAIL; | ||
3699 | + else | ||
3700 | + return result; | ||
3701 | + } | ||
3702 | + else if (line - name == 8) | ||
3703 | + { | ||
3704 | + if (__strncasecmp (name, "NOTFOUND", 8) == 0) | ||
3705 | + status = NSS_STATUS_NOTFOUND; | ||
3706 | + else if (__strncasecmp (name, "TRYAGAIN", 8) == 0) | ||
3707 | + status = NSS_STATUS_TRYAGAIN; | ||
3708 | + else | ||
3709 | + return result; | ||
3710 | + } | ||
3711 | + else | ||
3712 | + return result; | ||
3713 | + | ||
3714 | + while (isspace (line[0])) | ||
3715 | + ++line; | ||
3716 | + if (line[0] != '=') | ||
3717 | + return result; | ||
3718 | + do | ||
3719 | + ++line; | ||
3720 | + while (isspace (line[0])); | ||
3721 | + | ||
3722 | + name = line; | ||
3723 | + while (line[0] != '\0' && !isspace (line[0]) && line[0] != '=' | ||
3724 | + && line[0] != ']') | ||
3725 | + ++line; | ||
3726 | + | ||
3727 | + if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0) | ||
3728 | + action = NSS_ACTION_RETURN; | ||
3729 | + else if (line - name == 8 | ||
3730 | + && __strncasecmp (name, "CONTINUE", 8) == 0) | ||
3731 | + action = NSS_ACTION_CONTINUE; | ||
3732 | + else | ||
3733 | + return result; | ||
3734 | + | ||
3735 | + if (not) | ||
3736 | + { | ||
3737 | + /* Save the current action setting for this status, | ||
3738 | + set them all to the given action, and reset this one. */ | ||
3739 | + const lookup_actions save = new_service->actions[2 + status]; | ||
3740 | + new_service->actions[2 + NSS_STATUS_TRYAGAIN] = action; | ||
3741 | + new_service->actions[2 + NSS_STATUS_UNAVAIL] = action; | ||
3742 | + new_service->actions[2 + NSS_STATUS_NOTFOUND] = action; | ||
3743 | + new_service->actions[2 + NSS_STATUS_SUCCESS] = action; | ||
3744 | + new_service->actions[2 + status] = save; | ||
3745 | + } | ||
3746 | + else | ||
3747 | + new_service->actions[2 + status] = action; | ||
3748 | + | ||
3749 | + /* Skip white spaces. */ | ||
3750 | + while (isspace (line[0])) | ||
3751 | + ++line; | ||
3752 | + } | ||
3753 | + while (line[0] != ']'); | ||
3754 | + | ||
3755 | + /* Skip the ']'. */ | ||
3756 | + ++line; | ||
3757 | + } | ||
3758 | + | ||
3759 | + *nextp = new_service; | ||
3760 | + nextp = &new_service->next; | ||
3761 | + } | ||
3762 | +} | ||
3763 | + | ||
3764 | +static name_database_entry * | ||
3765 | +internal_function | ||
3766 | +nss_getline (char *line) | ||
3767 | +{ | ||
3768 | + const char *name; | ||
3769 | + name_database_entry *result; | ||
3770 | + size_t len; | ||
3771 | + | ||
3772 | + /* Ignore leading white spaces. ATTENTION: this is different from | ||
3773 | + what is implemented in Solaris. The Solaris man page says a line | ||
3774 | + beginning with a white space character is ignored. We regard | ||
3775 | + this as just another misfeature in Solaris. */ | ||
3776 | + while (isspace (line[0])) | ||
3777 | + ++line; | ||
3778 | + | ||
3779 | + /* Recognize `<database> ":"'. */ | ||
3780 | + name = line; | ||
3781 | + while (line[0] != '\0' && !isspace (line[0]) && line[0] != ':') | ||
3782 | + ++line; | ||
3783 | + if (line[0] == '\0' || name == line) | ||
3784 | + /* Syntax error. */ | ||
3785 | + return NULL; | ||
3786 | + *line++ = '\0'; | ||
3787 | + | ||
3788 | + len = strlen (name) + 1; | ||
3789 | + | ||
3790 | + result = (name_database_entry *) xmalloc (sizeof (*result)); | ||
3791 | + result->name = (char *) xmalloc (len); | ||
3792 | + | ||
3793 | + /* Save the database name. */ | ||
3794 | + memcpy ((char *) result->name, name, len); | ||
3795 | + | ||
3796 | + /* Parse the list of services. */ | ||
3797 | + result->service = nss_parse_service_list (line); | ||
3798 | + | ||
3799 | + result->next = NULL; | ||
3800 | + return result; | ||
3801 | +} | ||
3802 | + | ||
3803 | + | ||
3804 | + | ||
3805 | +/* Generating code for statically initialized nsswitch structures. */ | ||
3806 | + | ||
3807 | + | ||
3808 | +/* Return the service-neutral suffix of the name of the service | ||
3809 | + library function referred to by the function F. The result is | ||
3810 | + allocated with malloc. */ | ||
3811 | +char * | ||
3812 | +known_function_suffix (const struct function *f) | ||
3813 | +{ | ||
3814 | + switch (f->kind) | ||
3815 | + { | ||
3816 | + case fk_setent: | ||
3817 | + return saprintf ("set%sent", f->entry); | ||
3818 | + | ||
3819 | + case fk_getent: | ||
3820 | + return saprintf ("get%sent_r", f->entry); | ||
3821 | + | ||
3822 | + case fk_endent: | ||
3823 | + return saprintf ("end%sent", f->entry); | ||
3824 | + | ||
3825 | + case fk_getby: | ||
3826 | + return saprintf ("get%sby%s_r", f->entry, f->key); | ||
3827 | + | ||
3828 | + case fk_get: | ||
3829 | + return saprintf ("get%s_r", f->value_and_key); | ||
3830 | + | ||
3831 | + default: | ||
3832 | + abort (); | ||
3833 | + } | ||
3834 | +} | ||
3835 | + | ||
3836 | + | ||
3837 | +/* Return the name of the service library function referred to by the | ||
3838 | + function F. The result is allocated with malloc. */ | ||
3839 | +char * | ||
3840 | +known_function_name (const struct function *f) | ||
3841 | +{ | ||
3842 | + return saprintf ("_nss_%s_%s", f->service, known_function_suffix (f)); | ||
3843 | +} | ||
3844 | + | ||
3845 | + | ||
3846 | +/* Write initialized known_function structures to OUT for | ||
3847 | + all the functions we'll use. */ | ||
3848 | +void | ||
3849 | +generate_known_functions (FILE *out) | ||
3850 | +{ | ||
3851 | + int i; | ||
3852 | + | ||
3853 | + /* First, generate weak references to the functions. The service | ||
3854 | + libraries depend on libc, and if these references weren't weak, | ||
3855 | + we'd be making libc depend circularly on the service | ||
3856 | + libraries. */ | ||
3857 | + for (i = 0; functions[i].kind; i++) | ||
3858 | + { | ||
3859 | + char *name = known_function_name (&functions[i]); | ||
3860 | + fprintf (out, "typeof (%s) %s __attribute__ ((weak));\n", | ||
3861 | + name, name); | ||
3862 | + } | ||
3863 | + fputs ("\n", out); | ||
3864 | + | ||
3865 | + /* Then, a table mapping names to functions. */ | ||
3866 | + fputs ("static const known_function fixed_known_functions[] = {\n", | ||
3867 | + out); | ||
3868 | + for (i = 0; functions[i].kind; i++) | ||
3869 | + { | ||
3870 | + const struct function *f = &functions[i]; | ||
3871 | + char *suffix = known_function_suffix (f); | ||
3872 | + | ||
3873 | + fprintf (out, " /* %2d */ { \"%s\", _nss_%s_%s },\n", | ||
3874 | + i, suffix, f->service, suffix); | ||
3875 | + } | ||
3876 | + fputs ("};\n", out); | ||
3877 | + fputs ("\n", out); | ||
3878 | +} | ||
3879 | + | ||
3880 | + | ||
3881 | +/* Print code to OUT for an initialized array of pointers to the | ||
3882 | + 'known_function' structures needed for USER, which is for | ||
3883 | + DATABASE. Return its name, allocated with malloc. */ | ||
3884 | +char * | ||
3885 | +generate_known_function_list (FILE *out, | ||
3886 | + const name_database_entry *database, | ||
3887 | + const service_user *user) | ||
3888 | +{ | ||
3889 | + char *list_name = saprintf ("fixed_%s_%s_known_funcs", | ||
3890 | + database->name, user->name); | ||
3891 | + fprintf (out, "static const known_function *%s[] = {\n", | ||
3892 | + list_name); | ||
3893 | + int i; | ||
3894 | + for (i = 0; functions[i].kind; i++) | ||
3895 | + if (strcmp (functions[i].database, database->name) == 0 | ||
3896 | + && strcmp (functions[i].service, user->name) == 0) | ||
3897 | + fprintf (out, " &fixed_known_functions[%d], /* %s */\n", | ||
3898 | + i, known_function_name (&functions[i])); | ||
3899 | + fputs (" NULL\n", out); | ||
3900 | + fputs ("};\n", out); | ||
3901 | + fputs ("\n", out); | ||
3902 | + | ||
3903 | + return list_name; | ||
3904 | +} | ||
3905 | + | ||
3906 | + | ||
3907 | +/* Return the name of the status value STATUS, as a statically | ||
3908 | + allocated string. */ | ||
3909 | +const char * | ||
3910 | +lookup_status_name (enum nss_status status) | ||
3911 | +{ | ||
3912 | + switch (status) | ||
3913 | + { | ||
3914 | + case NSS_STATUS_TRYAGAIN: return "NSS_STATUS_TRYAGAIN"; | ||
3915 | + case NSS_STATUS_UNAVAIL: return "NSS_STATUS_UNAVAIL"; | ||
3916 | + case NSS_STATUS_NOTFOUND: return "NSS_STATUS_NOTFOUND"; | ||
3917 | + case NSS_STATUS_SUCCESS: return "NSS_STATUS_SUCCESS"; | ||
3918 | + case NSS_STATUS_RETURN: return "NSS_STATUS_RETURN"; | ||
3919 | + default: abort (); | ||
3920 | + }; | ||
3921 | +} | ||
3922 | + | ||
3923 | + | ||
3924 | +/* Return the name of ACTION as a statically allocated string. */ | ||
3925 | +const char * | ||
3926 | +lookup_action_name (lookup_actions action) | ||
3927 | +{ | ||
3928 | + switch (action) | ||
3929 | + { | ||
3930 | + case NSS_ACTION_CONTINUE: return "NSS_ACTION_CONTINUE"; | ||
3931 | + case NSS_ACTION_RETURN: return "NSS_ACTION_RETURN"; | ||
3932 | + default: abort (); | ||
3933 | + } | ||
3934 | +} | ||
3935 | + | ||
3936 | + | ||
3937 | +/* Print code to OUT for the list of service_user structures starting | ||
3938 | + with USER, which are all for DATABASE. Return the name of the | ||
3939 | + first structure in that list, or zero if USER is NULL. */ | ||
3940 | +char * | ||
3941 | +generate_service_user_list (FILE *out, | ||
3942 | + name_database_entry *database, | ||
3943 | + service_user *user) | ||
3944 | +{ | ||
3945 | + if (user) | ||
3946 | + { | ||
3947 | + /* Generate the tail of the list. */ | ||
3948 | + char *next_name = generate_service_user_list (out, database, user->next); | ||
3949 | + /* Generate our known function list. */ | ||
3950 | + char *known_function_list_name = | ||
3951 | + generate_known_function_list (out, database, user); | ||
3952 | + | ||
3953 | + char *name = saprintf ("fixed_%s_%s_user", database->name, user->name); | ||
3954 | + | ||
3955 | + fprintf (out, "static const service_user %s = {\n", name); | ||
3956 | + if (next_name) | ||
3957 | + fprintf (out, " (service_user *) &%s,\n", next_name); | ||
3958 | + else | ||
3959 | + fprintf (out, " NULL, /* no next entry */\n"); | ||
3960 | + fputs (" {\n", out); | ||
3961 | + int i; | ||
3962 | + for (i = 0; i < sizeof (user->actions) / sizeof (user->actions[0]); i++) | ||
3963 | + fprintf (out, " %s, /* %s */\n", | ||
3964 | + lookup_action_name (user->actions[i]), | ||
3965 | + lookup_status_name (i - 2)); | ||
3966 | + fputs (" },\n", out); | ||
3967 | + fprintf (out, " NULL, /* we never need the service library */\n"); | ||
3968 | + fprintf (out, " { .array = %s },\n", known_function_list_name); | ||
3969 | + fprintf (out, " \"%s\"\n", user->name); | ||
3970 | + fputs ("};\n", out); | ||
3971 | + fputs ("\n", out); | ||
3972 | + | ||
3973 | + return name; | ||
3974 | + } | ||
3975 | + else | ||
3976 | + return NULL; | ||
3977 | +} | ||
3978 | + | ||
3979 | + | ||
3980 | +/* Print code to OUT for the list of name_database_entry structures | ||
3981 | + starting with DATABASE. Return the name of the first structure | ||
3982 | + in that list, or zero if DATABASE is NULL. */ | ||
3983 | +char * | ||
3984 | +generate_name_database_entries (FILE *out, name_database_entry *database) | ||
3985 | +{ | ||
3986 | + if (database) | ||
3987 | + { | ||
3988 | + char *next_name = generate_name_database_entries (out, database->next); | ||
3989 | + char *service_user_name | ||
3990 | + = generate_service_user_list (out, database, database->service); | ||
3991 | + char *name = saprintf ("fixed_%s_name_database", database->name); | ||
3992 | + | ||
3993 | + fprintf (out, "static const name_database_entry %s = {\n", name); | ||
3994 | + | ||
3995 | + if (next_name) | ||
3996 | + fprintf (out, " (name_database_entry *) &%s,\n", next_name); | ||
3997 | + else | ||
3998 | + fprintf (out, " NULL,\n"); | ||
3999 | + | ||
4000 | + if (service_user_name) | ||
4001 | + fprintf (out, " (service_user *) &%s,\n", service_user_name); | ||
4002 | + else | ||
4003 | + fprintf (out, " NULL,\n"); | ||
4004 | + | ||
4005 | + fprintf (out, " \"%s\"\n", database->name); | ||
4006 | + fprintf (out, "};\n"); | ||
4007 | + fputs ("\n", out); | ||
4008 | + | ||
4009 | + return name; | ||
4010 | + } | ||
4011 | + else | ||
4012 | + return NULL; | ||
4013 | +} | ||
4014 | + | ||
4015 | + | ||
4016 | +void | ||
4017 | +generate_name_database (FILE *out, name_database *service_table) | ||
4018 | +{ | ||
4019 | + /* Produce a linked list of the known name_database_entry | ||
4020 | + structures. */ | ||
4021 | + char *entries = generate_name_database_entries (out, service_table->entry); | ||
4022 | + | ||
4023 | + /* Now produce the main structure that points to them all. */ | ||
4024 | + fprintf (out, "static const name_database fixed_name_database = {\n"); | ||
4025 | + if (entries) | ||
4026 | + fprintf (out, " (name_database_entry *) &%s,\n", entries); | ||
4027 | + else | ||
4028 | + fprintf (out, " NULL,\n"); | ||
4029 | + fputs (" NULL /* we don't need the libraries */\n" | ||
4030 | + "};\n", | ||
4031 | + out); | ||
4032 | +} | ||
4033 | + | ||
4034 | + | ||
4035 | + | ||
4036 | +/* Generating the list of service libraries we generate references to. */ | ||
4037 | + | ||
4038 | +/* String with revision number of the shared object files. */ | ||
4039 | +static const char *const nss_shlib_revision = LIBNSS_FILES_SO + 15; | ||
4040 | + | ||
4041 | +void | ||
4042 | +generate_service_lib_list (FILE *out, name_database *service_table) | ||
4043 | +{ | ||
4044 | + int i, j; | ||
4045 | + int printed_any = 0; | ||
4046 | + | ||
4047 | + for (i = 0; functions[i].kind; i++) | ||
4048 | + { | ||
4049 | + /* Mention each service library only once. */ | ||
4050 | + for (j = 0; j < i; j++) | ||
4051 | + if (strcmp (functions[i].service, functions[j].service) == 0) | ||
4052 | + break; | ||
4053 | + | ||
4054 | + if (j >= i) | ||
4055 | + { | ||
4056 | + if (printed_any) | ||
4057 | + putc (' ', out); | ||
4058 | + fprintf (out, "-lnss_%s", | ||
4059 | + functions[i].service, | ||
4060 | + nss_shlib_revision); | ||
4061 | + printed_any = 1; | ||
4062 | + } | ||
4063 | + } | ||
4064 | +} | ||
4065 | + | ||
4066 | + | ||
4067 | +/* Main. */ | ||
4068 | + | ||
4069 | +int | ||
4070 | +main (int argc, char **argv) | ||
4071 | +{ | ||
4072 | + if (argc != 4) | ||
4073 | + { | ||
4074 | + fprintf (stderr, "usage: gen-fixed-nsswitch HEADER SERVLIBS CONFIG\n"); | ||
4075 | + exit (1); | ||
4076 | + } | ||
4077 | + | ||
4078 | + name_database *service_table = nss_parse_file (argv[3]); | ||
4079 | + | ||
4080 | + FILE *header = fopen (argv[1], "w"); | ||
4081 | + if (! header) | ||
4082 | + { | ||
4083 | + fprintf (stderr, | ||
4084 | + "gen-fixed-nsswitch: couldn't open output file %s: %s\n", | ||
4085 | + argv[1], strerror (errno)); | ||
4086 | + exit (1); | ||
4087 | + } | ||
4088 | + fputs ("/* Generated by nss/gen-fixed-nsswitch.c. */\n", header); | ||
4089 | + fputs ("\n", header); | ||
4090 | + generate_known_functions (header); | ||
4091 | + generate_name_database (header, service_table); | ||
4092 | + fclose (header); | ||
4093 | + | ||
4094 | + FILE *service_lib_list = fopen (argv[2], "w"); | ||
4095 | + if (! service_lib_list) | ||
4096 | + { | ||
4097 | + fprintf (stderr, | ||
4098 | + "gen-fixed-nsswitch: couldn't open output file %s: %s\n", | ||
4099 | + argv[2], strerror (errno)); | ||
4100 | + exit (1); | ||
4101 | + } | ||
4102 | + generate_service_lib_list (service_lib_list, service_table); | ||
4103 | + fclose (service_lib_list); | ||
4104 | + | ||
4105 | + return 0; | ||
4106 | +} | ||
4107 | Index: git/nss/getent.c | ||
4108 | =================================================================== | ||
4109 | --- git.orig/nss/getent.c 2014-08-29 20:00:52.976070587 -0700 | ||
4110 | +++ git/nss/getent.c 2014-08-29 20:01:15.216070587 -0700 | ||
4111 | @@ -39,6 +39,7 @@ | ||
4112 | #include <netinet/ether.h> | ||
4113 | #include <netinet/in.h> | ||
4114 | #include <sys/socket.h> | ||
4115 | +#include <gnu/option-groups.h> | ||
4116 | |||
4117 | /* Get libc version number. */ | ||
4118 | #include <version.h> | ||
4119 | @@ -91,6 +92,7 @@ | ||
4120 | fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk"); | ||
4121 | } | ||
4122 | |||
4123 | +#if __OPTION_EGLIBC_DB_ALIASES | ||
4124 | /* This is for aliases */ | ||
4125 | static void | ||
4126 | print_aliases (struct aliasent *alias) | ||
4127 | @@ -135,7 +137,9 @@ | ||
4128 | |||
4129 | return result; | ||
4130 | } | ||
4131 | +#endif /* __OPTION_EGLIBC_DB_ALIASES */ | ||
4132 | |||
4133 | +#if __OPTION_EGLIBC_INET | ||
4134 | /* This is for ethers */ | ||
4135 | static int | ||
4136 | ethers_keys (int number, char *key[]) | ||
4137 | @@ -179,6 +183,7 @@ | ||
4138 | |||
4139 | return result; | ||
4140 | } | ||
4141 | +#endif /* __OPTION_EGLIBC_INET */ | ||
4142 | |||
4143 | /* This is for group */ | ||
4144 | static void | ||
4145 | @@ -301,6 +306,7 @@ | ||
4146 | return result; | ||
4147 | } | ||
4148 | |||
4149 | +#if __OPTION_EGLIBC_INET | ||
4150 | /* This is for hosts */ | ||
4151 | static void | ||
4152 | print_hosts (struct hostent *host) | ||
4153 | @@ -598,6 +604,7 @@ | ||
4154 | |||
4155 | return result; | ||
4156 | } | ||
4157 | +#endif /* __OPTION_EGLIBC_INET */ | ||
4158 | |||
4159 | /* Now is all for passwd */ | ||
4160 | static void | ||
4161 | @@ -650,6 +657,7 @@ | ||
4162 | return result; | ||
4163 | } | ||
4164 | |||
4165 | +#if __OPTION_EGLIBC_INET | ||
4166 | /* This is for protocols */ | ||
4167 | static void | ||
4168 | print_protocols (struct protoent *proto) | ||
4169 | @@ -805,6 +813,7 @@ | ||
4170 | |||
4171 | return result; | ||
4172 | } | ||
4173 | +#endif /* __OPTION_EGLIBC_INET */ | ||
4174 | |||
4175 | /* This is for shadow */ | ||
4176 | static void | ||
4177 | @@ -871,21 +880,34 @@ | ||
4178 | } databases[] = | ||
4179 | { | ||
4180 | #define D(name) { #name, name ## _keys }, | ||
4181 | -D(ahosts) | ||
4182 | -D(ahostsv4) | ||
4183 | -D(ahostsv6) | ||
4184 | -D(aliases) | ||
4185 | -D(ethers) | ||
4186 | + | ||
4187 | +#if __OPTION_EGLIBC_INET | ||
4188 | +#define DN(name) D(name) | ||
4189 | +#else | ||
4190 | +#define DN(name) | ||
4191 | +#endif | ||
4192 | + | ||
4193 | +#if __OPTION_EGLIBC_DB_ALIASES | ||
4194 | +#define DA(name) D(name) | ||
4195 | +#else | ||
4196 | +#define DA(name) | ||
4197 | +#endif | ||
4198 | + | ||
4199 | +DN(ahosts) | ||
4200 | +DN(ahostsv4) | ||
4201 | +DN(ahostsv6) | ||
4202 | +DA(aliases) | ||
4203 | +DN(ethers) | ||
4204 | D(group) | ||
4205 | D(gshadow) | ||
4206 | -D(hosts) | ||
4207 | +DN(hosts) | ||
4208 | D(initgroups) | ||
4209 | -D(netgroup) | ||
4210 | -D(networks) | ||
4211 | +DN(netgroup) | ||
4212 | +DN(networks) | ||
4213 | D(passwd) | ||
4214 | -D(protocols) | ||
4215 | -D(rpc) | ||
4216 | -D(services) | ||
4217 | +DN(protocols) | ||
4218 | +DN(rpc) | ||
4219 | +DN(services) | ||
4220 | D(shadow) | ||
4221 | #undef D | ||
4222 | { NULL, NULL } | ||
4223 | Index: git/nss/getnssent_r.c | ||
4224 | =================================================================== | ||
4225 | --- git.orig/nss/getnssent_r.c 2014-08-29 20:00:52.976070587 -0700 | ||
4226 | +++ git/nss/getnssent_r.c 2014-08-29 20:01:15.220070587 -0700 | ||
4227 | @@ -16,6 +16,7 @@ | ||
4228 | <http://www.gnu.org/licenses/>. */ | ||
4229 | |||
4230 | #include <errno.h> | ||
4231 | +#include <gnu/option-groups.h> | ||
4232 | #include <netdb.h> | ||
4233 | #include "nsswitch.h" | ||
4234 | |||
4235 | @@ -59,11 +60,13 @@ | ||
4236 | } fct; | ||
4237 | int no_more; | ||
4238 | |||
4239 | +#if __OPTION_EGLIBC_INET | ||
4240 | if (res && __res_maybe_init (&_res, 0) == -1) | ||
4241 | { | ||
4242 | __set_h_errno (NETDB_INTERNAL); | ||
4243 | return; | ||
4244 | } | ||
4245 | +#endif /* __OPTION_EGLIBC_INET */ | ||
4246 | |||
4247 | /* Cycle through the services and run their `setXXent' functions until | ||
4248 | we find an available service. */ | ||
4249 | @@ -101,11 +104,13 @@ | ||
4250 | } fct; | ||
4251 | int no_more; | ||
4252 | |||
4253 | +#if __OPTION_EGLIBC_INET | ||
4254 | if (res && __res_maybe_init (&_res, 0) == -1) | ||
4255 | { | ||
4256 | __set_h_errno (NETDB_INTERNAL); | ||
4257 | return; | ||
4258 | } | ||
4259 | +#endif /* __OPTION_EGLIBC_INET */ | ||
4260 | |||
4261 | /* Cycle through all the services and run their endXXent functions. */ | ||
4262 | no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1); | ||
4263 | @@ -141,12 +146,14 @@ | ||
4264 | int no_more; | ||
4265 | enum nss_status status; | ||
4266 | |||
4267 | +#if __OPTION_EGLIBC_INET | ||
4268 | if (res && __res_maybe_init (&_res, 0) == -1) | ||
4269 | { | ||
4270 | *h_errnop = NETDB_INTERNAL; | ||
4271 | *result = NULL; | ||
4272 | return errno; | ||
4273 | } | ||
4274 | +#endif /* __OPTION_EGLIBC_INET */ | ||
4275 | |||
4276 | /* Initialize status to return if no more functions are found. */ | ||
4277 | status = NSS_STATUS_NOTFOUND; | ||
4278 | @@ -161,7 +168,7 @@ | ||
4279 | int is_last_nip = *nip == *last_nip; | ||
4280 | |||
4281 | status = DL_CALL_FCT (fct.f, | ||
4282 | - (resbuf, buffer, buflen, &errno, &h_errno)); | ||
4283 | + (resbuf, buffer, buflen, &errno, h_errnop)); | ||
4284 | |||
4285 | /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the | ||
4286 | provided buffer is too small. In this case we should give | ||
4287 | Index: git/nss/Makefile | ||
4288 | =================================================================== | ||
4289 | --- git.orig/nss/Makefile 2014-08-29 20:00:52.972070587 -0700 | ||
4290 | +++ git/nss/Makefile 2014-08-29 20:01:15.220070587 -0700 | ||
4291 | @@ -18,29 +18,36 @@ | ||
4292 | # | ||
4293 | # Makefile for name service switch. | ||
4294 | # | ||
4295 | +include ../option-groups.mak | ||
4296 | + | ||
4297 | subdir := nss | ||
4298 | |||
4299 | include ../Makeconfig | ||
4300 | |||
4301 | headers := nss.h | ||
4302 | |||
4303 | -# This is the trivial part which goes into libc itself. | ||
4304 | -routines = nsswitch getnssent getnssent_r digits_dots \ | ||
4305 | - $(addsuffix -lookup,$(databases)) | ||
4306 | - | ||
4307 | # These are the databases that go through nss dispatch. | ||
4308 | # Caution: if you add a database here, you must add its real name | ||
4309 | # in databases.def, too. | ||
4310 | -databases = proto service hosts network grp pwd rpc ethers \ | ||
4311 | - spwd netgrp key alias sgrp | ||
4312 | +databases-y = grp pwd spwd sgrp | ||
4313 | +databases-$(OPTION_EGLIBC_INET) \ | ||
4314 | + += proto service hosts network rpc ethers \ | ||
4315 | + netgrp key | ||
4316 | +databases-$(OPTION_EGLIBC_DB_ALIASES) += alias | ||
4317 | + | ||
4318 | +# This is the trivial part which goes into libc itself. | ||
4319 | +routines-y += nsswitch getnssent getnssent_r \ | ||
4320 | + $(addsuffix -lookup,$(databases-y)) | ||
4321 | +routines-$(OPTION_EGLIBC_INET) += digits_dots | ||
4322 | |||
4323 | others := getent makedb | ||
4324 | install-bin := getent makedb | ||
4325 | makedb-modules = xmalloc hash-string | ||
4326 | extra-objs += $(makedb-modules:=.o) | ||
4327 | |||
4328 | -tests = test-netdb tst-nss-test1 test-digits-dots | ||
4329 | -xtests = bug-erange | ||
4330 | +tests = tst-nss-test1 | ||
4331 | +tests-$(OPTION_EGLIBC_INET) += test-netdb test-digits-dots | ||
4332 | +xtests-$(OPTION_EGLIBC_INET) += bug-erange | ||
4333 | |||
4334 | # Specify rules for the nss_* modules. We have some services. | ||
4335 | services := files db | ||
4336 | @@ -55,7 +62,7 @@ | ||
4337 | vpath %.c $(subdir-dirs) ../locale/programs ../intl | ||
4338 | |||
4339 | |||
4340 | -libnss_files-routines := $(addprefix files-,$(databases)) \ | ||
4341 | +libnss_files-routines := $(addprefix files-,$(databases-y)) \ | ||
4342 | files-initgroups files-have_o_cloexec files-init | ||
4343 | |||
4344 | libnss_db-dbs := $(addprefix db-,\ | ||
4345 | @@ -78,6 +85,45 @@ | ||
4346 | tests += $(tests-static) | ||
4347 | endif | ||
4348 | |||
4349 | +ifneq ($(OPTION_EGLIBC_NSSWITCH),y) | ||
4350 | + | ||
4351 | +ifndef OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG | ||
4352 | +$(error OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG variable left unset) | ||
4353 | +endif | ||
4354 | + | ||
4355 | +ifndef OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS | ||
4356 | +$(error OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS variable left unset) | ||
4357 | +endif | ||
4358 | + | ||
4359 | +ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG))) | ||
4360 | +$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed config file) | ||
4361 | +$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)) | ||
4362 | +endif | ||
4363 | + | ||
4364 | +ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS))) | ||
4365 | +$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed functions file) | ||
4366 | +$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)) | ||
4367 | +endif | ||
4368 | + | ||
4369 | +before-compile := $(objpfx)fixed-nsswitch.h | ||
4370 | +generated := fixed-nsswitch.h | ||
4371 | +$(objpfx)fixed-nsswitch.h $(objfpx)fixed-nsswitch-libs: \ | ||
4372 | + $(objpfx)gen-fixed-nsswitch \ | ||
4373 | + $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG) | ||
4374 | + $< $(objpfx)fixed-nsswitch.h \ | ||
4375 | + $(objpfx)fixed-nsswitch-libs \ | ||
4376 | + $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG) | ||
4377 | + | ||
4378 | +$(objpfx)gen-fixed-nsswitch: gen-fixed-nsswitch.c \ | ||
4379 | + $(common-objpfx)option-groups.config \ | ||
4380 | + $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS) | ||
4381 | + $(native-compile) | ||
4382 | +gen-fixed-nsswitch-CFLAGS = \ | ||
4383 | + -g3 -O -Wall \ | ||
4384 | + -I $(objpfx) \ | ||
4385 | + -DFIXED_FUNCTIONS='"$(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)"' | ||
4386 | +endif | ||
4387 | + | ||
4388 | include ../Rules | ||
4389 | |||
4390 | ifeq (yes,$(have-selinux)) | ||
4391 | Index: git/nss/nsswitch.c | ||
4392 | =================================================================== | ||
4393 | --- git.orig/nss/nsswitch.c 2014-08-29 20:00:53.004070587 -0700 | ||
4394 | +++ git/nss/nsswitch.c 2014-08-29 20:01:15.220070587 -0700 | ||
4395 | @@ -26,6 +26,7 @@ | ||
4396 | #include <stdio_ext.h> | ||
4397 | #include <stdlib.h> | ||
4398 | #include <string.h> | ||
4399 | +#include <gnu/option-groups.h> | ||
4400 | |||
4401 | #include <aliases.h> | ||
4402 | #include <grp.h> | ||
4403 | @@ -41,6 +42,15 @@ | ||
4404 | #include "../nscd/nscd_proto.h" | ||
4405 | #include <sysdep.h> | ||
4406 | |||
4407 | +/* When OPTION_EGLIBC_NSSWITCH is disabled, we use fixed tables of | ||
4408 | + databases and services, generated at library build time. Thus: | ||
4409 | + - We can't reconfigure individual databases, so we don't need a | ||
4410 | + name-to-database map. | ||
4411 | + - We never add databases or service libraries, or look up functions | ||
4412 | + at runtime, so there's no need for a lock to protect our tables. | ||
4413 | + See ../option-groups.def for the details. */ | ||
4414 | +#if __OPTION_EGLIBC_NSSWITCH | ||
4415 | + | ||
4416 | /* Prototypes for the local functions. */ | ||
4417 | static name_database *nss_parse_file (const char *fname) internal_function; | ||
4418 | static name_database_entry *nss_getline (char *line) internal_function; | ||
4419 | @@ -79,6 +89,9 @@ | ||
4420 | |||
4421 | __libc_lock_define_initialized (static, lock) | ||
4422 | |||
4423 | +#define lock_nsswitch __libc_lock_lock (lock) | ||
4424 | +#define unlock_nsswitch __libc_lock_unlock (lock) | ||
4425 | + | ||
4426 | #if !defined DO_STATIC_NSS || defined SHARED | ||
4427 | /* String with revision number of the shared object files. */ | ||
4428 | static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15; | ||
4429 | @@ -93,6 +106,20 @@ | ||
4430 | __libc_freeres. */ | ||
4431 | static name_database_entry *defconfig_entries; | ||
4432 | |||
4433 | +#else /* __OPTION_EGLIBC_NSSWITCH */ | ||
4434 | + | ||
4435 | +/* Bring in the statically initialized service table we generated at | ||
4436 | + build time. */ | ||
4437 | +#include "fixed-nsswitch.h" | ||
4438 | + | ||
4439 | +const static name_database *service_table = &fixed_name_database; | ||
4440 | + | ||
4441 | +/* Nothing ever changes, so there's no need to lock anything. */ | ||
4442 | +#define lock_nsswitch (0) | ||
4443 | +#define unlock_nsswitch (0) | ||
4444 | + | ||
4445 | +#endif /* __OPTION_EGLIBC_NSSWITCH */ | ||
4446 | + | ||
4447 | |||
4448 | #ifdef USE_NSCD | ||
4449 | /* Nonzero if this is the nscd process. */ | ||
4450 | @@ -109,20 +136,22 @@ | ||
4451 | const char *defconfig, service_user **ni) | ||
4452 | { | ||
4453 | /* Prevent multiple threads to change the service table. */ | ||
4454 | - __libc_lock_lock (lock); | ||
4455 | + lock_nsswitch; | ||
4456 | |||
4457 | /* Reconsider database variable in case some other thread called | ||
4458 | `__nss_configure_lookup' while we waited for the lock. */ | ||
4459 | if (*ni != NULL) | ||
4460 | { | ||
4461 | - __libc_lock_unlock (lock); | ||
4462 | + unlock_nsswitch; | ||
4463 | return 0; | ||
4464 | } | ||
4465 | |||
4466 | +#if __OPTION_EGLIBC_NSSWITCH | ||
4467 | /* Are we initialized yet? */ | ||
4468 | if (service_table == NULL) | ||
4469 | /* Read config file. */ | ||
4470 | service_table = nss_parse_file (_PATH_NSSWITCH_CONF); | ||
4471 | +#endif | ||
4472 | |||
4473 | /* Test whether configuration data is available. */ | ||
4474 | if (service_table != NULL) | ||
4475 | @@ -144,6 +173,7 @@ | ||
4476 | *ni = entry->service; | ||
4477 | } | ||
4478 | |||
4479 | +#if __OPTION_EGLIBC_NSSWITCH | ||
4480 | /* No configuration data is available, either because nsswitch.conf | ||
4481 | doesn't exist or because it doesn't have a line for this database. | ||
4482 | |||
4483 | @@ -166,13 +196,23 @@ | ||
4484 | { | ||
4485 | entry->next = defconfig_entries; | ||
4486 | entry->service = *ni; | ||
4487 | - entry->name[0] = '\0'; | ||
4488 | + entry->name = ""; | ||
4489 | defconfig_entries = entry; | ||
4490 | } | ||
4491 | } | ||
4492 | } | ||
4493 | +#else | ||
4494 | + /* Without the dynamic behavior, we can't process defconfig. The | ||
4495 | + databases the user specified at library build time are all you | ||
4496 | + get. */ | ||
4497 | + if (*ni == NULL) | ||
4498 | + { | ||
4499 | + unlock_nsswitch; | ||
4500 | + return -1; | ||
4501 | + } | ||
4502 | +#endif | ||
4503 | |||
4504 | - __libc_lock_unlock (lock); | ||
4505 | + unlock_nsswitch; | ||
4506 | |||
4507 | return *ni != NULL ? 0 : -1; | ||
4508 | } | ||
4509 | @@ -252,6 +292,7 @@ | ||
4510 | libc_hidden_def (__nss_next2) | ||
4511 | |||
4512 | |||
4513 | +#if __OPTION_EGLIBC_NSSWITCH | ||
4514 | int | ||
4515 | attribute_compat_text_section | ||
4516 | __nss_next (service_user **ni, const char *fct_name, void **fctp, int status, | ||
4517 | @@ -300,13 +341,13 @@ | ||
4518 | } | ||
4519 | |||
4520 | /* Prevent multiple threads to change the service table. */ | ||
4521 | - __libc_lock_lock (lock); | ||
4522 | + lock_nsswitch; | ||
4523 | |||
4524 | /* Install new rules. */ | ||
4525 | *databases[cnt].dbp = new_db; | ||
4526 | __nss_database_custom[cnt] = true; | ||
4527 | |||
4528 | - __libc_lock_unlock (lock); | ||
4529 | + unlock_nsswitch; | ||
4530 | |||
4531 | return 0; | ||
4532 | } | ||
4533 | @@ -402,7 +443,7 @@ | ||
4534 | void **found, *result; | ||
4535 | |||
4536 | /* We now modify global data. Protect it. */ | ||
4537 | - __libc_lock_lock (lock); | ||
4538 | + lock_nsswitch; | ||
4539 | |||
4540 | /* Search the tree of functions previously requested. Data in the | ||
4541 | tree are `known_function' structures, whose first member is a | ||
4542 | @@ -413,7 +454,7 @@ | ||
4543 | enough to a pointer to our structure to use as a lookup key that | ||
4544 | will be passed to `known_compare' (above). */ | ||
4545 | |||
4546 | - found = __tsearch (&fct_name, &ni->known, &known_compare); | ||
4547 | + found = __tsearch (&fct_name, &ni->known.tree, &known_compare); | ||
4548 | if (found == NULL) | ||
4549 | /* This means out-of-memory. */ | ||
4550 | result = NULL; | ||
4551 | @@ -440,7 +481,7 @@ | ||
4552 | #endif | ||
4553 | /* Oops. We can't instantiate this node properly. | ||
4554 | Remove it from the tree. */ | ||
4555 | - __tdelete (&fct_name, &ni->known, &known_compare); | ||
4556 | + __tdelete (&fct_name, &ni->known.tree, &known_compare); | ||
4557 | free (known); | ||
4558 | result = NULL; | ||
4559 | } | ||
4560 | @@ -520,13 +561,43 @@ | ||
4561 | } | ||
4562 | |||
4563 | /* Remove the lock. */ | ||
4564 | - __libc_lock_unlock (lock); | ||
4565 | + unlock_nsswitch; | ||
4566 | |||
4567 | return result; | ||
4568 | } | ||
4569 | libc_hidden_def (__nss_lookup_function) | ||
4570 | |||
4571 | |||
4572 | +#else /* below if ! __OPTION_EGLIBC_NSSWITCH */ | ||
4573 | + | ||
4574 | + | ||
4575 | +int | ||
4576 | +__nss_configure_lookup (const char *dbname, const char *service_line) | ||
4577 | +{ | ||
4578 | + /* We can't dynamically configure lookup without | ||
4579 | + OPTION_EGLIBC_NSSWITCH. */ | ||
4580 | + __set_errno (EINVAL); | ||
4581 | + return -1; | ||
4582 | +} | ||
4583 | + | ||
4584 | + | ||
4585 | +void * | ||
4586 | +__nss_lookup_function (service_user *ni, const char *fct_name) | ||
4587 | +{ | ||
4588 | + int i; | ||
4589 | + const known_function **known = ni->known.array; | ||
4590 | + | ||
4591 | + for (i = 0; known[i]; i++) | ||
4592 | + if (strcmp (fct_name, known[i]->fct_name) == 0) | ||
4593 | + return known[i]->fct_ptr; | ||
4594 | + | ||
4595 | + return NULL; | ||
4596 | +} | ||
4597 | +libc_hidden_def (__nss_lookup_function) | ||
4598 | +#endif | ||
4599 | + | ||
4600 | + | ||
4601 | +#if __OPTION_EGLIBC_NSSWITCH | ||
4602 | static name_database * | ||
4603 | internal_function | ||
4604 | nss_parse_file (const char *fname) | ||
4605 | @@ -632,8 +703,10 @@ | ||
4606 | + (line - name + 1)); | ||
4607 | if (new_service == NULL) | ||
4608 | return result; | ||
4609 | + new_service->name = (char *) (new_service + 1); | ||
4610 | |||
4611 | - *((char *) __mempcpy (new_service->name, name, line - name)) = '\0'; | ||
4612 | + *((char *) __mempcpy ((char *) new_service->name, name, line - name)) | ||
4613 | + = '\0'; | ||
4614 | |||
4615 | /* Set default actions. */ | ||
4616 | new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE; | ||
4617 | @@ -642,7 +715,7 @@ | ||
4618 | new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN; | ||
4619 | new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN; | ||
4620 | new_service->library = NULL; | ||
4621 | - new_service->known = NULL; | ||
4622 | + new_service->known.tree = NULL; | ||
4623 | new_service->next = NULL; | ||
4624 | |||
4625 | while (isspace (line[0])) | ||
4626 | @@ -778,9 +851,10 @@ | ||
4627 | result = (name_database_entry *) malloc (sizeof (name_database_entry) + len); | ||
4628 | if (result == NULL) | ||
4629 | return NULL; | ||
4630 | + result->name = (char *) (result + 1); | ||
4631 | |||
4632 | /* Save the database name. */ | ||
4633 | - memcpy (result->name, name, len); | ||
4634 | + memcpy ((char *) result->name, name, len); | ||
4635 | |||
4636 | /* Parse the list of services. */ | ||
4637 | result->service = nss_parse_service_list (line); | ||
4638 | @@ -816,6 +890,7 @@ | ||
4639 | return *currentp; | ||
4640 | } | ||
4641 | #endif | ||
4642 | +#endif /* __OPTION_EGLIBC_NSSWITCH */ | ||
4643 | |||
4644 | |||
4645 | #if defined SHARED && defined USE_NSCD | ||
4646 | @@ -834,6 +909,7 @@ | ||
4647 | } | ||
4648 | |||
4649 | |||
4650 | +#if __OPTION_EGLIBC_INET | ||
4651 | /* Called by nscd and nscd alone. */ | ||
4652 | void | ||
4653 | __nss_disable_nscd (void (*cb) (size_t, struct traced_file *)) | ||
4654 | @@ -857,8 +933,10 @@ | ||
4655 | __nss_not_use_nscd_services = -1; | ||
4656 | __nss_not_use_nscd_netgroup = -1; | ||
4657 | } | ||
4658 | +#endif /* __OPTION_EGLIBC_INET */ | ||
4659 | #endif | ||
4660 | |||
4661 | +#if __OPTION_EGLIBC_NSSWITCH | ||
4662 | static void | ||
4663 | free_database_entries (name_database_entry *entry) | ||
4664 | { | ||
4665 | @@ -871,8 +949,8 @@ | ||
4666 | { | ||
4667 | service_user *olds = service; | ||
4668 | |||
4669 | - if (service->known != NULL) | ||
4670 | - __tdestroy (service->known, free); | ||
4671 | + if (service->known.tree != NULL) | ||
4672 | + __tdestroy (service->known.tree, free); | ||
4673 | |||
4674 | service = service->next; | ||
4675 | free (olds); | ||
4676 | @@ -926,3 +1004,4 @@ | ||
4677 | |||
4678 | free (top); | ||
4679 | } | ||
4680 | +#endif /* __OPTION_EGLIBC_NSSWITCH */ | ||
4681 | Index: git/nss/nsswitch.h | ||
4682 | =================================================================== | ||
4683 | --- git.orig/nss/nsswitch.h 2014-08-29 20:00:53.012070587 -0700 | ||
4684 | +++ git/nss/nsswitch.h 2014-08-29 20:01:15.220070587 -0700 | ||
4685 | @@ -65,10 +65,20 @@ | ||
4686 | lookup_actions actions[5]; | ||
4687 | /* Link to the underlying library object. */ | ||
4688 | service_library *library; | ||
4689 | - /* Collection of known functions. */ | ||
4690 | - void *known; | ||
4691 | + /* Collection of known functions. | ||
4692 | + | ||
4693 | + With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a | ||
4694 | + 'tsearch'-style tree. | ||
4695 | + | ||
4696 | + With OPTION_EGLIBC_NSSWITCH disabled, this is an array of | ||
4697 | + pointers to known_function structures, NULL-terminated. */ | ||
4698 | + union | ||
4699 | + { | ||
4700 | + void *tree; | ||
4701 | + const known_function **array; | ||
4702 | + } known; | ||
4703 | /* Name of the service (`files', `dns', `nis', ...). */ | ||
4704 | - char name[0]; | ||
4705 | + const char *name; | ||
4706 | } service_user; | ||
4707 | |||
4708 | /* To access the action based on the status value use this macro. */ | ||
4709 | @@ -82,7 +92,7 @@ | ||
4710 | /* List of service to be used. */ | ||
4711 | service_user *service; | ||
4712 | /* Name of the database. */ | ||
4713 | - char name[0]; | ||
4714 | + const char *name; | ||
4715 | } name_database_entry; | ||
4716 | |||
4717 | |||
4718 | Index: git/posix/bug-regex1.c | ||
4719 | =================================================================== | ||
4720 | --- git.orig/posix/bug-regex1.c 2014-08-29 20:00:53.184070587 -0700 | ||
4721 | +++ git/posix/bug-regex1.c 2014-08-29 20:01:15.220070587 -0700 | ||
4722 | @@ -4,6 +4,7 @@ | ||
4723 | #include <string.h> | ||
4724 | #include <regex.h> | ||
4725 | #include <wchar.h> | ||
4726 | +#include <gnu/option-groups.h> | ||
4727 | |||
4728 | int | ||
4729 | main (void) | ||
4730 | @@ -17,7 +18,9 @@ | ||
4731 | memset (®ex, '\0', sizeof (regex)); | ||
4732 | |||
4733 | setlocale (LC_ALL, "de_DE.ISO-8859-1"); | ||
4734 | +#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
4735 | fwide (stdout, -1); | ||
4736 | +#endif | ||
4737 | |||
4738 | re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_DEBUG); | ||
4739 | |||
4740 | Index: git/posix/bug-regex6.c | ||
4741 | =================================================================== | ||
4742 | --- git.orig/posix/bug-regex6.c 2014-08-29 20:00:53.204070587 -0700 | ||
4743 | +++ git/posix/bug-regex6.c 2014-08-29 20:01:15.220070587 -0700 | ||
4744 | @@ -22,6 +22,7 @@ | ||
4745 | #include <string.h> | ||
4746 | #include <sys/types.h> | ||
4747 | #include <regex.h> | ||
4748 | +#include <gnu/option-groups.h> | ||
4749 | |||
4750 | |||
4751 | int | ||
4752 | @@ -30,7 +31,12 @@ | ||
4753 | regex_t re; | ||
4754 | regmatch_t mat[10]; | ||
4755 | int i, j, ret = 0; | ||
4756 | - const char *locales[] = { "C", "de_DE.UTF-8" }; | ||
4757 | + const char *locales[] = { | ||
4758 | + "C", | ||
4759 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
4760 | + "de_DE.UTF-8" | ||
4761 | +#endif | ||
4762 | + }; | ||
4763 | const char *string = "http://www.regex.com/pattern/matching.html#intro"; | ||
4764 | regmatch_t expect[10] = { | ||
4765 | { 0, 48 }, { 0, 5 }, { 0, 4 }, { 5, 20 }, { 7, 20 }, { 20, 42 }, | ||
4766 | Index: git/posix/fnmatch.c | ||
4767 | =================================================================== | ||
4768 | --- git.orig/posix/fnmatch.c 2014-08-29 20:00:53.208070587 -0700 | ||
4769 | +++ git/posix/fnmatch.c 2014-08-29 20:01:15.220070587 -0700 | ||
4770 | @@ -30,6 +30,10 @@ | ||
4771 | #include <ctype.h> | ||
4772 | #include <string.h> | ||
4773 | |||
4774 | +#if defined _LIBC | ||
4775 | +# include <gnu/option-groups.h> | ||
4776 | +#endif | ||
4777 | + | ||
4778 | #if defined STDC_HEADERS || defined _LIBC | ||
4779 | # include <stdlib.h> | ||
4780 | #endif | ||
4781 | @@ -131,7 +135,7 @@ | ||
4782 | # define ISWCTYPE(WC, WT) iswctype (WC, WT) | ||
4783 | # endif | ||
4784 | |||
4785 | -# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC | ||
4786 | +# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || (_LIBC && __OPTION_EGLIBC_LOCALE_CODE) | ||
4787 | /* In this case we are implementing the multibyte character handling. */ | ||
4788 | # define HANDLE_MULTIBYTE 1 | ||
4789 | # endif | ||
4790 | Index: git/posix/fnmatch_loop.c | ||
4791 | =================================================================== | ||
4792 | --- git.orig/posix/fnmatch_loop.c 2014-08-29 20:00:53.220070587 -0700 | ||
4793 | +++ git/posix/fnmatch_loop.c 2014-08-29 20:01:15.220070587 -0700 | ||
4794 | @@ -15,6 +15,8 @@ | ||
4795 | License along with the GNU C Library; if not, see | ||
4796 | <http://www.gnu.org/licenses/>. */ | ||
4797 | |||
4798 | +#include <gnu/option-groups.h> | ||
4799 | + | ||
4800 | #include <stdint.h> | ||
4801 | |||
4802 | struct STRUCT | ||
4803 | @@ -54,10 +56,15 @@ | ||
4804 | const char *collseq = (const char *) | ||
4805 | _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC); | ||
4806 | # else | ||
4807 | +# if __OPTION_EGLIBC_LOCALE_CODE | ||
4808 | const UCHAR *collseq = (const UCHAR *) | ||
4809 | _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB); | ||
4810 | -# endif | ||
4811 | -#endif | ||
4812 | +# define COLLSEQ_BYTE_LOOKUP(ix) (collseq[(ix)]) | ||
4813 | +# else | ||
4814 | +# define COLLSEQ_BYTE_LOOKUP(ix) (ix) | ||
4815 | +# endif /* __OPTION_EGLIBC_LOCALE_CODE */ | ||
4816 | +# endif /* WIDE_CHAR_VERSION */ | ||
4817 | +#endif /* _LIBC */ | ||
4818 | |||
4819 | while ((c = *p++) != L('\0')) | ||
4820 | { | ||
4821 | @@ -277,7 +284,7 @@ | ||
4822 | /* Leave room for the null. */ | ||
4823 | CHAR str[CHAR_CLASS_MAX_LENGTH + 1]; | ||
4824 | size_t c1 = 0; | ||
4825 | -#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) | ||
4826 | +#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) | ||
4827 | wctype_t wt; | ||
4828 | #endif | ||
4829 | const CHAR *startp = p; | ||
4830 | @@ -307,7 +314,7 @@ | ||
4831 | } | ||
4832 | str[c1] = L('\0'); | ||
4833 | |||
4834 | -#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) | ||
4835 | +#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) | ||
4836 | wt = IS_CHAR_CLASS (str); | ||
4837 | if (wt == 0) | ||
4838 | /* Invalid character class name. */ | ||
4839 | @@ -681,8 +688,10 @@ | ||
4840 | else | ||
4841 | lcollseq = __collseq_table_lookup (collseq, cold); | ||
4842 | # else | ||
4843 | - fcollseq = collseq[fn]; | ||
4844 | - lcollseq = is_seqval ? cold : collseq[(UCHAR) cold]; | ||
4845 | + fcollseq = COLLSEQ_BYTE_LOOKUP (fn); | ||
4846 | + lcollseq = (is_seqval | ||
4847 | + ? cold | ||
4848 | + : COLLSEQ_BYTE_LOOKUP ((UCHAR) cold)); | ||
4849 | # endif | ||
4850 | |||
4851 | is_seqval = 0; | ||
4852 | @@ -858,7 +867,7 @@ | ||
4853 | goto matched; | ||
4854 | } | ||
4855 | # else | ||
4856 | - hcollseq = collseq[cend]; | ||
4857 | + hcollseq = COLLSEQ_BYTE_LOOKUP (cend); | ||
4858 | # endif | ||
4859 | } | ||
4860 | |||
4861 | Index: git/posix/glob.c | ||
4862 | =================================================================== | ||
4863 | --- git.orig/posix/glob.c 2014-08-29 20:00:53.232070587 -0700 | ||
4864 | +++ git/posix/glob.c 2014-08-29 20:01:15.220070587 -0700 | ||
4865 | @@ -25,6 +25,9 @@ | ||
4866 | #include <sys/types.h> | ||
4867 | #include <sys/stat.h> | ||
4868 | #include <stddef.h> | ||
4869 | +#ifdef _LIBC | ||
4870 | +# include <gnu/option-groups.h> | ||
4871 | +#endif | ||
4872 | |||
4873 | /* Outcomment the following line for production quality code. */ | ||
4874 | /* #define NDEBUG 1 */ | ||
4875 | @@ -607,6 +610,7 @@ | ||
4876 | if (home_dir == NULL || home_dir[0] == '\0') | ||
4877 | home_dir = "c:/users/default"; /* poor default */ | ||
4878 | # else | ||
4879 | +# if ! _LIBC || __OPTION_EGLIBC_GETLOGIN | ||
4880 | if (home_dir == NULL || home_dir[0] == '\0') | ||
4881 | { | ||
4882 | int success; | ||
4883 | @@ -623,19 +627,19 @@ | ||
4884 | if (success) | ||
4885 | { | ||
4886 | struct passwd *p; | ||
4887 | -# if defined HAVE_GETPWNAM_R || defined _LIBC | ||
4888 | +# if defined HAVE_GETPWNAM_R || defined _LIBC | ||
4889 | long int pwbuflen = GETPW_R_SIZE_MAX (); | ||
4890 | char *pwtmpbuf; | ||
4891 | struct passwd pwbuf; | ||
4892 | int malloc_pwtmpbuf = 0; | ||
4893 | int save = errno; | ||
4894 | |||
4895 | -# ifndef _LIBC | ||
4896 | +# ifndef _LIBC | ||
4897 | if (pwbuflen == -1) | ||
4898 | /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. | ||
4899 | Try a moderate value. */ | ||
4900 | pwbuflen = 1024; | ||
4901 | -# endif | ||
4902 | +# endif | ||
4903 | if (__libc_use_alloca (alloca_used + pwbuflen)) | ||
4904 | pwtmpbuf = alloca_account (pwbuflen, alloca_used); | ||
4905 | else | ||
4906 | @@ -682,9 +686,9 @@ | ||
4907 | } | ||
4908 | __set_errno (save); | ||
4909 | } | ||
4910 | -# else | ||
4911 | +# else | ||
4912 | p = getpwnam (name); | ||
4913 | -# endif | ||
4914 | +# endif | ||
4915 | if (p != NULL) | ||
4916 | { | ||
4917 | if (!malloc_pwtmpbuf) | ||
4918 | @@ -713,6 +717,7 @@ | ||
4919 | } | ||
4920 | } | ||
4921 | } | ||
4922 | +# endif /* ! _LIBC || __OPTION_EGLIBC_GETLOGIN */ | ||
4923 | if (home_dir == NULL || home_dir[0] == '\0') | ||
4924 | { | ||
4925 | if (flags & GLOB_TILDE_CHECK) | ||
4926 | Index: git/posix/Makefile | ||
4927 | =================================================================== | ||
4928 | --- git.orig/posix/Makefile 2014-08-29 20:00:53.160070587 -0700 | ||
4929 | +++ git/posix/Makefile 2014-08-29 20:01:15.220070587 -0700 | ||
4930 | @@ -18,6 +18,8 @@ | ||
4931 | # | ||
4932 | # Sub-makefile for POSIX portion of the library. | ||
4933 | # | ||
4934 | +include ../option-groups.mak | ||
4935 | + | ||
4936 | subdir := posix | ||
4937 | |||
4938 | include ../Makeconfig | ||
4939 | @@ -43,13 +45,24 @@ | ||
4940 | getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid \ | ||
4941 | getresuid getresgid setresuid setresgid \ | ||
4942 | pathconf sysconf fpathconf \ | ||
4943 | - glob glob64 fnmatch regex \ | ||
4944 | + glob glob64 fnmatch \ | ||
4945 | confstr \ | ||
4946 | getopt getopt1 getopt_init \ | ||
4947 | sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax \ | ||
4948 | sched_primin sched_rr_gi sched_getaffinity sched_setaffinity \ | ||
4949 | - getaddrinfo gai_strerror wordexp \ | ||
4950 | pread pwrite pread64 pwrite64 \ | ||
4951 | + posix_madvise \ | ||
4952 | + get_child_max sched_cpucount sched_cpualloc sched_cpufree | ||
4953 | + | ||
4954 | +routines-$(OPTION_EGLIBC_INET) += getaddrinfo gai_strerror | ||
4955 | + | ||
4956 | +ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC)) | ||
4957 | +routines-$(OPTION_POSIX_REGEXP) += regex | ||
4958 | +else | ||
4959 | +routines-$(OPTION_POSIX_REGEXP) += xregex | ||
4960 | +endif | ||
4961 | + | ||
4962 | +routines-$(OPTION_EGLIBC_SPAWN) += \ | ||
4963 | spawn_faction_init spawn_faction_destroy spawn_faction_addclose \ | ||
4964 | spawn_faction_addopen spawn_faction_adddup2 \ | ||
4965 | spawnattr_init spawnattr_destroy \ | ||
4966 | @@ -57,41 +70,53 @@ | ||
4967 | spawnattr_getflags spawnattr_setflags \ | ||
4968 | spawnattr_getpgroup spawnattr_setpgroup spawn spawnp spawni \ | ||
4969 | spawnattr_getsigmask spawnattr_getschedpolicy spawnattr_getschedparam \ | ||
4970 | - spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \ | ||
4971 | - posix_madvise \ | ||
4972 | - get_child_max sched_cpucount sched_cpualloc sched_cpufree | ||
4973 | + spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam | ||
4974 | +routines-$(OPTION_EGLIBC_WORDEXP) += wordexp | ||
4975 | |||
4976 | aux := init-posix environ | ||
4977 | -tests := tstgetopt testfnm runtests runptests \ | ||
4978 | +tests := tstgetopt testfnm runtests \ | ||
4979 | tst-preadwrite tst-preadwrite64 test-vfork regexbug1 \ | ||
4980 | - tst-getlogin tst-mmap tst-getaddrinfo tst-truncate \ | ||
4981 | - tst-truncate64 tst-fork tst-fnmatch tst-regexloc tst-dir \ | ||
4982 | - tst-chmod bug-regex1 bug-regex2 bug-regex3 bug-regex4 \ | ||
4983 | - tst-gnuglob tst-regex bug-regex5 bug-regex6 bug-regex7 \ | ||
4984 | - bug-regex8 bug-regex9 bug-regex10 bug-regex11 bug-regex12 \ | ||
4985 | - bug-regex13 bug-regex14 bug-regex15 bug-regex16 \ | ||
4986 | - bug-regex17 bug-regex18 bug-regex19 bug-regex20 \ | ||
4987 | - bug-regex21 bug-regex22 bug-regex23 bug-regex24 \ | ||
4988 | - bug-regex25 bug-regex26 bug-regex27 bug-regex28 \ | ||
4989 | - bug-regex29 bug-regex30 bug-regex31 bug-regex32 \ | ||
4990 | - bug-regex33 tst-nice tst-nanosleep tst-regex2 \ | ||
4991 | - transbug tst-rxspencer tst-pcre tst-boost \ | ||
4992 | - bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \ | ||
4993 | - tst-getaddrinfo2 bug-glob1 bug-glob2 bug-glob3 tst-sysconf \ | ||
4994 | + tst-getlogin tst-mmap tst-truncate \ | ||
4995 | + tst-truncate64 tst-fork tst-dir \ | ||
4996 | + tst-chmod bug-regex2 bug-regex3 bug-regex4 \ | ||
4997 | + tst-gnuglob bug-regex6 bug-regex7 \ | ||
4998 | + bug-regex8 bug-regex9 bug-regex10 bug-regex12 \ | ||
4999 | + bug-regex14 bug-regex15 \ | ||
5000 | + bug-regex21 bug-regex24 \ | ||
5001 | + bug-regex27 bug-regex28 bug-regex29 bug-regex30 \ | ||
5002 | + bug-regex31 \ | ||
5003 | + tst-nice tst-nanosleep \ | ||
5004 | + transbug \ | ||
5005 | + tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \ | ||
5006 | + bug-glob1 bug-glob2 bug-glob3 tst-sysconf \ | ||
5007 | tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \ | ||
5008 | tst-execv1 tst-execv2 tst-execl1 tst-execl2 \ | ||
5009 | tst-execve1 tst-execve2 tst-execle1 tst-execle2 \ | ||
5010 | - tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \ | ||
5011 | - tst-rfc3484-3 \ | ||
5012 | - tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \ | ||
5013 | + tst-execvp3 tst-execvp4 \ | ||
5014 | + tst-fnmatch2 tst-cpucount tst-cpuset \ | ||
5015 | bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \ | ||
5016 | bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \ | ||
5017 | tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \ | ||
5018 | tst-fnmatch3 bug-regex36 | ||
5019 | -xtests := bug-ga2 | ||
5020 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
5021 | + += tst-fnmatch tst-regexloc bug-regex1 bug-regex5 \ | ||
5022 | + bug-regex23 bug-regex25 bug-regex32 bug-regex33 | ||
5023 | +tests-$(OPTION_EGLIBC_INET) \ | ||
5024 | + += tst-getaddrinfo bug-ga1 tst-getaddrinfo2 \ | ||
5025 | + tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 tst-getaddrinfo3 | ||
5026 | +tests-$(OPTION_POSIX_REGEXP_GLIBC) \ | ||
5027 | + += runptests bug-regex11 bug-regex13 bug-regex16 \ | ||
5028 | + tst-regex2 tst-rxspencer tst-pcre tst-boost | ||
5029 | +ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP_GLIBC)) | ||
5030 | +tests += tst-regex bug-regex17 bug-regex18 bug-regex19 bug-regex20 \ | ||
5031 | + bug-regex22 bug-regex26 | ||
5032 | +endif | ||
5033 | +xtests-$(OPTION_EGLIBC_INET) += bug-ga2 | ||
5034 | ifeq (yes,$(build-shared)) | ||
5035 | test-srcs := globtest | ||
5036 | -tests += wordexp-test tst-exec tst-spawn | ||
5037 | +tests += tst-exec | ||
5038 | +tests-$(OPTION_EGLIBC_SPAWN) += tst-spawn | ||
5039 | +tests-$(OPTION_EGLIBC_WORDEXP) += wordexp-test | ||
5040 | endif | ||
5041 | tests-static = tst-exec-static tst-spawn-static | ||
5042 | tests += $(tests-static) | ||
5043 | @@ -117,7 +142,10 @@ | ||
5044 | |||
5045 | ifeq ($(run-built-tests),yes) | ||
5046 | ifeq (yes,$(build-shared)) | ||
5047 | -tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out | ||
5048 | +tests-special += $(objpfx)globtest.out | ||
5049 | +ifeq (y,$(OPTION_EGLIBC_WORDEXP)) | ||
5050 | +tests-special += $(objpfx)wordexp-tst.out | ||
5051 | +endif | ||
5052 | endif | ||
5053 | endif | ||
5054 | |||
5055 | @@ -125,12 +153,16 @@ | ||
5056 | # XXX Please note that for now we ignore the result of this test. | ||
5057 | tests-special += $(objpfx)annexc.out | ||
5058 | ifeq ($(run-built-tests),yes) | ||
5059 | -tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \ | ||
5060 | +tests-special += $(objpfx)bug-regex2-mem.out \ | ||
5061 | $(objpfx)bug-regex21-mem.out $(objpfx)bug-regex31-mem.out \ | ||
5062 | - $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \ | ||
5063 | - $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \ | ||
5064 | + $(objpfx)tst-getconf.out \ | ||
5065 | $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \ | ||
5066 | $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out | ||
5067 | +ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC)) | ||
5068 | +tests-special += $(objpfx)bug-regex14-mem $(objpfx)tst-rxspencer-no-utf8-mem \ | ||
5069 | + $(objpfx)tst-pcre-mem $(objpfx)tst-boost-mem | ||
5070 | +endif | ||
5071 | + | ||
5072 | xtests-special += $(objpfx)bug-ga2-mem.out | ||
5073 | endif | ||
5074 | |||
5075 | @@ -143,6 +175,8 @@ | ||
5076 | $(SHELL) $< $(common-objpfx) '$(test-via-rtld-prefix)' \ | ||
5077 | '$(test-program-prefix)' '$(test-wrapper-env)'; \ | ||
5078 | $(evaluate-test) | ||
5079 | +LDLIBS-globtest += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs) | ||
5080 | + | ||
5081 | $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test | ||
5082 | $(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \ | ||
5083 | '$(run-program-env)' '$(test-program-prefix-after-env)'; \ | ||
5084 | @@ -205,7 +239,10 @@ | ||
5085 | tst-chmod-ARGS = $(objdir) | ||
5086 | tst-vfork3-ARGS = --test-dir=$(objpfx) | ||
5087 | |||
5088 | -tst-rxspencer-ARGS = --utf8 rxspencer/tests | ||
5089 | +tst-rxspencer-ARGS = rxspencer/tests | ||
5090 | +ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE)) | ||
5091 | +tst-rxspencer-ARGS += --utf8 | ||
5092 | +endif | ||
5093 | tst-rxspencer-no-utf8-ARGS = rxspencer/tests | ||
5094 | tst-pcre-ARGS = PCRE.tests | ||
5095 | tst-boost-ARGS = BOOST.tests | ||
5096 | Index: git/posix/regcomp.c | ||
5097 | =================================================================== | ||
5098 | --- git.orig/posix/regcomp.c 2014-08-29 20:00:53.264070587 -0700 | ||
5099 | +++ git/posix/regcomp.c 2014-08-29 20:01:15.224070587 -0700 | ||
5100 | @@ -18,6 +18,7 @@ | ||
5101 | <http://www.gnu.org/licenses/>. */ | ||
5102 | |||
5103 | #include <stdint.h> | ||
5104 | +#include <gnu/option-groups.h> | ||
5105 | |||
5106 | static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, | ||
5107 | size_t length, reg_syntax_t syntax); | ||
5108 | @@ -305,7 +306,7 @@ | ||
5109 | { | ||
5110 | re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; | ||
5111 | int node_cnt; | ||
5112 | - int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE)); | ||
5113 | + int icase = (dfa_mb_cur_max (dfa) == 1 && (bufp->syntax & RE_ICASE)); | ||
5114 | for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt) | ||
5115 | { | ||
5116 | int node = init_state->nodes.elems[node_cnt]; | ||
5117 | @@ -315,9 +316,9 @@ | ||
5118 | { | ||
5119 | re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c); | ||
5120 | #ifdef RE_ENABLE_I18N | ||
5121 | - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) | ||
5122 | + if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1) | ||
5123 | { | ||
5124 | - unsigned char *buf = alloca (dfa->mb_cur_max), *p; | ||
5125 | + unsigned char *buf = alloca (dfa_mb_cur_max (dfa)), *p; | ||
5126 | wchar_t wc; | ||
5127 | mbstate_t state; | ||
5128 | |||
5129 | @@ -348,7 +349,11 @@ | ||
5130 | re_set_fastmap (fastmap, icase, ch); | ||
5131 | } | ||
5132 | } | ||
5133 | -#ifdef RE_ENABLE_I18N | ||
5134 | + | ||
5135 | + /* When OPTION_EGLIBC_LOCALE_CODE is disabled, the current | ||
5136 | + locale is always C, which has no rules and no multi-byte | ||
5137 | + characters. */ | ||
5138 | +#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE | ||
5139 | else if (type == COMPLEX_BRACKET) | ||
5140 | { | ||
5141 | re_charset_t *cset = dfa->nodes[node].opr.mbcset; | ||
5142 | @@ -376,7 +381,7 @@ | ||
5143 | i.e. where we would not find an invalid sequence. This only | ||
5144 | applies to multibyte character sets; for single byte character | ||
5145 | sets, the SIMPLE_BRACKET again suffices. */ | ||
5146 | - if (dfa->mb_cur_max > 1 | ||
5147 | + if (dfa_mb_cur_max (dfa) > 1 | ||
5148 | && (cset->nchar_classes || cset->non_match || cset->nranges | ||
5149 | # ifdef _LIBC | ||
5150 | || cset->nequiv_classes | ||
5151 | @@ -404,7 +409,7 @@ | ||
5152 | memset (&state, '\0', sizeof (state)); | ||
5153 | if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1) | ||
5154 | re_set_fastmap (fastmap, icase, *(unsigned char *) buf); | ||
5155 | - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) | ||
5156 | + if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1) | ||
5157 | { | ||
5158 | if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state) | ||
5159 | != (size_t) -1) | ||
5160 | @@ -413,7 +418,7 @@ | ||
5161 | } | ||
5162 | } | ||
5163 | } | ||
5164 | -#endif /* RE_ENABLE_I18N */ | ||
5165 | +#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */ | ||
5166 | else if (type == OP_PERIOD | ||
5167 | #ifdef RE_ENABLE_I18N | ||
5168 | || type == OP_UTF8_PERIOD | ||
5169 | @@ -856,11 +861,15 @@ | ||
5170 | |||
5171 | dfa->mb_cur_max = MB_CUR_MAX; | ||
5172 | #ifdef _LIBC | ||
5173 | - if (dfa->mb_cur_max == 6 | ||
5174 | + if (dfa_mb_cur_max (dfa) == 6 | ||
5175 | && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0) | ||
5176 | dfa->is_utf8 = 1; | ||
5177 | +# if __OPTION_EGLIBC_LOCALE_CODE | ||
5178 | dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII) | ||
5179 | != 0); | ||
5180 | +# else | ||
5181 | + dfa->map_notascii = 0; | ||
5182 | +# endif | ||
5183 | #else | ||
5184 | # ifdef HAVE_LANGINFO_CODESET | ||
5185 | codeset_name = nl_langinfo (CODESET); | ||
5186 | @@ -886,7 +895,7 @@ | ||
5187 | #endif | ||
5188 | |||
5189 | #ifdef RE_ENABLE_I18N | ||
5190 | - if (dfa->mb_cur_max > 1) | ||
5191 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5192 | { | ||
5193 | if (dfa->is_utf8) | ||
5194 | dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map; | ||
5195 | @@ -1784,7 +1793,7 @@ | ||
5196 | token->word_char = 0; | ||
5197 | #ifdef RE_ENABLE_I18N | ||
5198 | token->mb_partial = 0; | ||
5199 | - if (input->mb_cur_max > 1 && | ||
5200 | + if (string_mb_cur_max (input) > 1 && | ||
5201 | !re_string_first_byte (input, re_string_cur_idx (input))) | ||
5202 | { | ||
5203 | token->type = CHARACTER; | ||
5204 | @@ -1805,7 +1814,7 @@ | ||
5205 | token->opr.c = c2; | ||
5206 | token->type = CHARACTER; | ||
5207 | #ifdef RE_ENABLE_I18N | ||
5208 | - if (input->mb_cur_max > 1) | ||
5209 | + if (string_mb_cur_max (input) > 1) | ||
5210 | { | ||
5211 | wint_t wc = re_string_wchar_at (input, | ||
5212 | re_string_cur_idx (input) + 1); | ||
5213 | @@ -1919,7 +1928,7 @@ | ||
5214 | |||
5215 | token->type = CHARACTER; | ||
5216 | #ifdef RE_ENABLE_I18N | ||
5217 | - if (input->mb_cur_max > 1) | ||
5218 | + if (string_mb_cur_max (input) > 1) | ||
5219 | { | ||
5220 | wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input)); | ||
5221 | token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; | ||
5222 | @@ -2019,7 +2028,7 @@ | ||
5223 | token->opr.c = c; | ||
5224 | |||
5225 | #ifdef RE_ENABLE_I18N | ||
5226 | - if (input->mb_cur_max > 1 && | ||
5227 | + if (string_mb_cur_max (input) > 1 && | ||
5228 | !re_string_first_byte (input, re_string_cur_idx (input))) | ||
5229 | { | ||
5230 | token->type = CHARACTER; | ||
5231 | @@ -2242,7 +2251,7 @@ | ||
5232 | return NULL; | ||
5233 | } | ||
5234 | #ifdef RE_ENABLE_I18N | ||
5235 | - if (dfa->mb_cur_max > 1) | ||
5236 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5237 | { | ||
5238 | while (!re_string_eoi (regexp) | ||
5239 | && !re_string_first_byte (regexp, re_string_cur_idx (regexp))) | ||
5240 | @@ -2380,7 +2389,7 @@ | ||
5241 | *err = REG_ESPACE; | ||
5242 | return NULL; | ||
5243 | } | ||
5244 | - if (dfa->mb_cur_max > 1) | ||
5245 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5246 | dfa->has_mb_node = 1; | ||
5247 | break; | ||
5248 | case OP_WORD: | ||
5249 | @@ -2686,7 +2695,7 @@ | ||
5250 | However, for !_LIBC we have no collation elements: if the | ||
5251 | character set is single byte, the single byte character set | ||
5252 | that we build below suffices. parse_bracket_exp passes | ||
5253 | - no MBCSET if dfa->mb_cur_max == 1. */ | ||
5254 | + no MBCSET if dfa_mb_cur_max (dfa) == 1. */ | ||
5255 | if (mbcset) | ||
5256 | { | ||
5257 | /* Check the space of the arrays. */ | ||
5258 | @@ -2782,7 +2791,13 @@ | ||
5259 | reg_syntax_t syntax, reg_errcode_t *err) | ||
5260 | { | ||
5261 | #ifdef _LIBC | ||
5262 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
5263 | const unsigned char *collseqmb; | ||
5264 | +# define COLLSEQMB_LOOKUP(ix) (collseqmb[(ix)]) | ||
5265 | +#else | ||
5266 | +# define COLLSEQMB_LOOKUP(ix) (ix) | ||
5267 | +#endif | ||
5268 | + | ||
5269 | const char *collseqwc; | ||
5270 | uint32_t nrules; | ||
5271 | int32_t table_size; | ||
5272 | @@ -2830,18 +2845,20 @@ | ||
5273 | if (MB_CUR_MAX == 1) | ||
5274 | */ | ||
5275 | if (nrules == 0) | ||
5276 | - return collseqmb[br_elem->opr.ch]; | ||
5277 | + return COLLSEQMB_LOOKUP (br_elem->opr.ch); | ||
5278 | else | ||
5279 | { | ||
5280 | wint_t wc = __btowc (br_elem->opr.ch); | ||
5281 | return __collseq_table_lookup (collseqwc, wc); | ||
5282 | } | ||
5283 | } | ||
5284 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
5285 | else if (br_elem->type == MB_CHAR) | ||
5286 | { | ||
5287 | if (nrules != 0) | ||
5288 | return __collseq_table_lookup (collseqwc, br_elem->opr.wch); | ||
5289 | } | ||
5290 | +#endif | ||
5291 | else if (br_elem->type == COLL_SYM) | ||
5292 | { | ||
5293 | size_t sym_name_len = strlen ((char *) br_elem->opr.name); | ||
5294 | @@ -2872,11 +2889,11 @@ | ||
5295 | { | ||
5296 | /* No valid character. Match it as a single byte | ||
5297 | character. */ | ||
5298 | - return collseqmb[br_elem->opr.name[0]]; | ||
5299 | + return COLLSEQMB_LOOKUP (br_elem->opr.name[0]); | ||
5300 | } | ||
5301 | } | ||
5302 | else if (sym_name_len == 1) | ||
5303 | - return collseqmb[br_elem->opr.name[0]]; | ||
5304 | + return COLLSEQMB_LOOKUP (br_elem->opr.name[0]); | ||
5305 | } | ||
5306 | return UINT_MAX; | ||
5307 | } | ||
5308 | @@ -2916,7 +2933,7 @@ | ||
5309 | However, if we have no collation elements, and the character set | ||
5310 | is single byte, the single byte character set that we | ||
5311 | build below suffices. */ | ||
5312 | - if (nrules > 0 || dfa->mb_cur_max > 1) | ||
5313 | + if (nrules > 0 || dfa_mb_cur_max (dfa) > 1) | ||
5314 | { | ||
5315 | /* Check the space of the arrays. */ | ||
5316 | if (BE (*range_alloc == mbcset->nranges, 0)) | ||
5317 | @@ -2953,7 +2970,7 @@ | ||
5318 | if (MB_CUR_MAX == 1) | ||
5319 | */ | ||
5320 | if (nrules == 0) | ||
5321 | - ch_collseq = collseqmb[ch]; | ||
5322 | + ch_collseq = COLLSEQMB_LOOKUP (ch); | ||
5323 | else | ||
5324 | ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch)); | ||
5325 | if (start_collseq <= ch_collseq && ch_collseq <= end_collseq) | ||
5326 | @@ -3031,7 +3048,10 @@ | ||
5327 | re_bitset_ptr_t sbcset; | ||
5328 | #ifdef RE_ENABLE_I18N | ||
5329 | re_charset_t *mbcset; | ||
5330 | - int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; | ||
5331 | + int coll_sym_alloc = 0, range_alloc = 0; | ||
5332 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
5333 | + int mbchar_alloc = 0; | ||
5334 | +#endif | ||
5335 | int equiv_class_alloc = 0, char_class_alloc = 0; | ||
5336 | #endif /* not RE_ENABLE_I18N */ | ||
5337 | int non_match = 0; | ||
5338 | @@ -3039,9 +3059,15 @@ | ||
5339 | int token_len; | ||
5340 | int first_round = 1; | ||
5341 | #ifdef _LIBC | ||
5342 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
5343 | collseqmb = (const unsigned char *) | ||
5344 | _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); | ||
5345 | nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); | ||
5346 | +#else | ||
5347 | + /* This is true when OPTION_EGLIBC_LOCALE_CODE is disabled, but the | ||
5348 | + compiler can't figure that out. */ | ||
5349 | + nrules = 0; | ||
5350 | +#endif | ||
5351 | if (nrules) | ||
5352 | { | ||
5353 | /* | ||
5354 | @@ -3169,7 +3195,7 @@ | ||
5355 | #else | ||
5356 | # ifdef RE_ENABLE_I18N | ||
5357 | *err = build_range_exp (sbcset, | ||
5358 | - dfa->mb_cur_max > 1 ? mbcset : NULL, | ||
5359 | + dfa_mb_cur_max (dfa) > 1 ? mbcset : NULL, | ||
5360 | &range_alloc, &start_elem, &end_elem); | ||
5361 | # else | ||
5362 | *err = build_range_exp (sbcset, &start_elem, &end_elem); | ||
5363 | @@ -3185,7 +3211,7 @@ | ||
5364 | case SB_CHAR: | ||
5365 | bitset_set (sbcset, start_elem.opr.ch); | ||
5366 | break; | ||
5367 | -#ifdef RE_ENABLE_I18N | ||
5368 | +#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE | ||
5369 | case MB_CHAR: | ||
5370 | /* Check whether the array has enough space. */ | ||
5371 | if (BE (mbchar_alloc == mbcset->nmbchars, 0)) | ||
5372 | @@ -3203,7 +3229,7 @@ | ||
5373 | } | ||
5374 | mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch; | ||
5375 | break; | ||
5376 | -#endif /* RE_ENABLE_I18N */ | ||
5377 | +#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */ | ||
5378 | case EQUIV_CLASS: | ||
5379 | *err = build_equiv_class (sbcset, | ||
5380 | #ifdef RE_ENABLE_I18N | ||
5381 | @@ -3253,11 +3279,11 @@ | ||
5382 | |||
5383 | #ifdef RE_ENABLE_I18N | ||
5384 | /* Ensure only single byte characters are set. */ | ||
5385 | - if (dfa->mb_cur_max > 1) | ||
5386 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5387 | bitset_mask (sbcset, dfa->sb_char); | ||
5388 | |||
5389 | if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes | ||
5390 | - || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes | ||
5391 | + || mbcset->nranges || (dfa_mb_cur_max (dfa) > 1 && (mbcset->nchar_classes | ||
5392 | || mbcset->non_match))) | ||
5393 | { | ||
5394 | bin_tree_t *mbc_tree; | ||
5395 | @@ -3326,7 +3352,7 @@ | ||
5396 | re_token_t *token, int token_len, re_dfa_t *dfa, | ||
5397 | reg_syntax_t syntax, int accept_hyphen) | ||
5398 | { | ||
5399 | -#ifdef RE_ENABLE_I18N | ||
5400 | +#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE | ||
5401 | int cur_char_size; | ||
5402 | cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp)); | ||
5403 | if (cur_char_size > 1) | ||
5404 | @@ -3336,7 +3362,7 @@ | ||
5405 | re_string_skip_bytes (regexp, cur_char_size); | ||
5406 | return REG_NOERROR; | ||
5407 | } | ||
5408 | -#endif /* RE_ENABLE_I18N */ | ||
5409 | +#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */ | ||
5410 | re_string_skip_bytes (regexp, token_len); /* Skip a token. */ | ||
5411 | if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS | ||
5412 | || token->type == OP_OPEN_EQUIV_CLASS) | ||
5413 | @@ -3416,7 +3442,9 @@ | ||
5414 | build_equiv_class (bitset_t sbcset, const unsigned char *name) | ||
5415 | #endif /* not RE_ENABLE_I18N */ | ||
5416 | { | ||
5417 | -#ifdef _LIBC | ||
5418 | + /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C locale | ||
5419 | + is supported; it has no collation rules. */ | ||
5420 | +#if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE | ||
5421 | uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); | ||
5422 | if (nrules != 0) | ||
5423 | { | ||
5424 | @@ -3488,7 +3516,7 @@ | ||
5425 | mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1; | ||
5426 | } | ||
5427 | else | ||
5428 | -#endif /* _LIBC */ | ||
5429 | +#endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */ | ||
5430 | { | ||
5431 | if (BE (strlen ((const char *) name) != 1, 0)) | ||
5432 | return REG_ECOLLATE; | ||
5433 | @@ -3522,7 +3550,7 @@ | ||
5434 | && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0)) | ||
5435 | name = "alpha"; | ||
5436 | |||
5437 | -#ifdef RE_ENABLE_I18N | ||
5438 | +#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE | ||
5439 | /* Check the space of the arrays. */ | ||
5440 | if (BE (*char_class_alloc == mbcset->nchar_classes, 0)) | ||
5441 | { | ||
5442 | @@ -3538,7 +3566,7 @@ | ||
5443 | *char_class_alloc = new_char_class_alloc; | ||
5444 | } | ||
5445 | mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name); | ||
5446 | -#endif /* RE_ENABLE_I18N */ | ||
5447 | +#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */ | ||
5448 | |||
5449 | #define BUILD_CHARCLASS_LOOP(ctype_func) \ | ||
5450 | do { \ | ||
5451 | @@ -3649,7 +3677,7 @@ | ||
5452 | |||
5453 | #ifdef RE_ENABLE_I18N | ||
5454 | /* Ensure only single byte characters are set. */ | ||
5455 | - if (dfa->mb_cur_max > 1) | ||
5456 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5457 | bitset_mask (sbcset, dfa->sb_char); | ||
5458 | #endif | ||
5459 | |||
5460 | @@ -3661,7 +3689,7 @@ | ||
5461 | goto build_word_op_espace; | ||
5462 | |||
5463 | #ifdef RE_ENABLE_I18N | ||
5464 | - if (dfa->mb_cur_max > 1) | ||
5465 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5466 | { | ||
5467 | bin_tree_t *mbc_tree; | ||
5468 | /* Build a tree for complex bracket. */ | ||
5469 | Index: git/posix/regexec.c | ||
5470 | =================================================================== | ||
5471 | --- git.orig/posix/regexec.c 2014-08-29 20:00:53.268070587 -0700 | ||
5472 | +++ git/posix/regexec.c 2014-08-29 20:01:15.224070587 -0700 | ||
5473 | @@ -18,6 +18,7 @@ | ||
5474 | <http://www.gnu.org/licenses/>. */ | ||
5475 | |||
5476 | #include <stdint.h> | ||
5477 | +#include <gnu/option-groups.h> | ||
5478 | |||
5479 | static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, | ||
5480 | int n) internal_function; | ||
5481 | @@ -186,11 +187,11 @@ | ||
5482 | static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx, | ||
5483 | const re_string_t *input, int idx) | ||
5484 | internal_function; | ||
5485 | -# ifdef _LIBC | ||
5486 | +# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE | ||
5487 | static unsigned int find_collation_sequence_value (const unsigned char *mbs, | ||
5488 | size_t name_len) | ||
5489 | internal_function; | ||
5490 | -# endif /* _LIBC */ | ||
5491 | +# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */ | ||
5492 | #endif /* RE_ENABLE_I18N */ | ||
5493 | static int group_nodes_into_DFAstates (const re_dfa_t *dfa, | ||
5494 | const re_dfastate_t *state, | ||
5495 | @@ -255,25 +256,9 @@ | ||
5496 | return err != REG_NOERROR; | ||
5497 | } | ||
5498 | |||
5499 | -#ifdef _LIBC | ||
5500 | -# include <shlib-compat.h> | ||
5501 | -versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4); | ||
5502 | - | ||
5503 | -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) | ||
5504 | -__typeof__ (__regexec) __compat_regexec; | ||
5505 | - | ||
5506 | -int | ||
5507 | -attribute_compat_text_section | ||
5508 | -__compat_regexec (const regex_t *__restrict preg, | ||
5509 | - const char *__restrict string, size_t nmatch, | ||
5510 | - regmatch_t pmatch[], int eflags) | ||
5511 | -{ | ||
5512 | - return regexec (preg, string, nmatch, pmatch, | ||
5513 | - eflags & (REG_NOTBOL | REG_NOTEOL)); | ||
5514 | -} | ||
5515 | -compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); | ||
5516 | -# endif | ||
5517 | -#endif | ||
5518 | +/* EGLIBC: The code that used to be here was move to a separate file | ||
5519 | + so that it can be shared with xregex.c. */ | ||
5520 | +#include "regexec-compat.c" | ||
5521 | |||
5522 | /* Entry points for GNU code. */ | ||
5523 | |||
5524 | @@ -728,7 +713,7 @@ | ||
5525 | incr = (range < 0) ? -1 : 1; | ||
5526 | left_lim = (range < 0) ? start + range : start; | ||
5527 | right_lim = (range < 0) ? start : start + range; | ||
5528 | - sb = dfa->mb_cur_max == 1; | ||
5529 | + sb = dfa_mb_cur_max (dfa) == 1; | ||
5530 | match_kind = | ||
5531 | (fastmap | ||
5532 | ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0) | ||
5533 | @@ -3448,7 +3433,7 @@ | ||
5534 | if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0)) | ||
5535 | goto out_free; | ||
5536 | |||
5537 | - if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1) | ||
5538 | + if (dest_states[i] != dest_states_word[i] && dfa_mb_cur_max (dfa) > 1) | ||
5539 | need_word_trtable = 1; | ||
5540 | |||
5541 | dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows, | ||
5542 | @@ -3590,7 +3575,7 @@ | ||
5543 | else if (type == OP_PERIOD) | ||
5544 | { | ||
5545 | #ifdef RE_ENABLE_I18N | ||
5546 | - if (dfa->mb_cur_max > 1) | ||
5547 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5548 | bitset_merge (accepts, dfa->sb_char); | ||
5549 | else | ||
5550 | #endif | ||
5551 | @@ -3641,7 +3626,7 @@ | ||
5552 | continue; | ||
5553 | } | ||
5554 | #ifdef RE_ENABLE_I18N | ||
5555 | - if (dfa->mb_cur_max > 1) | ||
5556 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5557 | for (j = 0; j < BITSET_WORDS; ++j) | ||
5558 | any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j])); | ||
5559 | else | ||
5560 | @@ -3660,7 +3645,7 @@ | ||
5561 | continue; | ||
5562 | } | ||
5563 | #ifdef RE_ENABLE_I18N | ||
5564 | - if (dfa->mb_cur_max > 1) | ||
5565 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5566 | for (j = 0; j < BITSET_WORDS; ++j) | ||
5567 | any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j])); | ||
5568 | else | ||
5569 | @@ -3832,12 +3817,6 @@ | ||
5570 | if (node->type == COMPLEX_BRACKET) | ||
5571 | { | ||
5572 | const re_charset_t *cset = node->opr.mbcset; | ||
5573 | -# ifdef _LIBC | ||
5574 | - const unsigned char *pin | ||
5575 | - = ((const unsigned char *) re_string_get_buffer (input) + str_idx); | ||
5576 | - int j; | ||
5577 | - uint32_t nrules; | ||
5578 | -# endif /* _LIBC */ | ||
5579 | int match_len = 0; | ||
5580 | wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars) | ||
5581 | ? re_string_wchar_at (input, str_idx) : 0); | ||
5582 | @@ -3849,6 +3828,7 @@ | ||
5583 | match_len = char_len; | ||
5584 | goto check_node_accept_bytes_match; | ||
5585 | } | ||
5586 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
5587 | /* match with character_class? */ | ||
5588 | for (i = 0; i < cset->nchar_classes; ++i) | ||
5589 | { | ||
5590 | @@ -3859,8 +3839,16 @@ | ||
5591 | goto check_node_accept_bytes_match; | ||
5592 | } | ||
5593 | } | ||
5594 | +#endif | ||
5595 | + | ||
5596 | + /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C | ||
5597 | + locale is supported; it has no collation rules. */ | ||
5598 | +# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE | ||
5599 | + const unsigned char *pin | ||
5600 | + = ((const unsigned char *) re_string_get_buffer (input) + str_idx); | ||
5601 | + int j; | ||
5602 | + uint32_t nrules; | ||
5603 | |||
5604 | -# ifdef _LIBC | ||
5605 | nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); | ||
5606 | if (nrules != 0) | ||
5607 | { | ||
5608 | @@ -3953,8 +3941,12 @@ | ||
5609 | } | ||
5610 | } | ||
5611 | else | ||
5612 | -# endif /* _LIBC */ | ||
5613 | +# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */ | ||
5614 | { | ||
5615 | + /* In the _LIBC version, if OPTION_EGLIBC_LOCALE_CODE is | ||
5616 | + disabled, there can be no multibyte range endpoints, and | ||
5617 | + cset->nranges is always zero. */ | ||
5618 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
5619 | /* match with range expression? */ | ||
5620 | #if __GNUC__ >= 2 | ||
5621 | wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'}; | ||
5622 | @@ -3973,6 +3965,7 @@ | ||
5623 | goto check_node_accept_bytes_match; | ||
5624 | } | ||
5625 | } | ||
5626 | +#endif /* __OPTION_EGLIBC_LOCALE_CODE */ | ||
5627 | } | ||
5628 | check_node_accept_bytes_match: | ||
5629 | if (!cset->non_match) | ||
5630 | @@ -3988,7 +3981,7 @@ | ||
5631 | return 0; | ||
5632 | } | ||
5633 | |||
5634 | -# ifdef _LIBC | ||
5635 | +# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE | ||
5636 | static unsigned int | ||
5637 | internal_function | ||
5638 | find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) | ||
5639 | @@ -4046,7 +4039,7 @@ | ||
5640 | return UINT_MAX; | ||
5641 | } | ||
5642 | } | ||
5643 | -# endif /* _LIBC */ | ||
5644 | +# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */ | ||
5645 | #endif /* RE_ENABLE_I18N */ | ||
5646 | |||
5647 | /* Check whether the node accepts the byte which is IDX-th | ||
5648 | @@ -4137,7 +4130,7 @@ | ||
5649 | if (pstr->icase) | ||
5650 | { | ||
5651 | #ifdef RE_ENABLE_I18N | ||
5652 | - if (pstr->mb_cur_max > 1) | ||
5653 | + if (string_mb_cur_max (pstr) > 1) | ||
5654 | { | ||
5655 | ret = build_wcs_upper_buffer (pstr); | ||
5656 | if (BE (ret != REG_NOERROR, 0)) | ||
5657 | @@ -4150,7 +4143,7 @@ | ||
5658 | else | ||
5659 | { | ||
5660 | #ifdef RE_ENABLE_I18N | ||
5661 | - if (pstr->mb_cur_max > 1) | ||
5662 | + if (string_mb_cur_max (pstr) > 1) | ||
5663 | build_wcs_buffer (pstr); | ||
5664 | else | ||
5665 | #endif /* RE_ENABLE_I18N */ | ||
5666 | Index: git/posix/regexec-compat.c | ||
5667 | =================================================================== | ||
5668 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
5669 | +++ git/posix/regexec-compat.c 2014-08-29 20:01:15.224070587 -0700 | ||
5670 | @@ -0,0 +1,39 @@ | ||
5671 | +/* Extended regular expression matching and search library. | ||
5672 | + Copyright (C) 2008 Free Software Foundation, Inc. | ||
5673 | + This file is part of the GNU C Library. | ||
5674 | + Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. | ||
5675 | + | ||
5676 | + The GNU C Library is free software; you can redistribute it and/or | ||
5677 | + modify it under the terms of the GNU Lesser General Public | ||
5678 | + License as published by the Free Software Foundation; either | ||
5679 | + version 2.1 of the License, or (at your option) any later version. | ||
5680 | + | ||
5681 | + The GNU C Library is distributed in the hope that it will be useful, | ||
5682 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
5683 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
5684 | + Lesser General Public License for more details. | ||
5685 | + | ||
5686 | + You should have received a copy of the GNU Lesser General Public | ||
5687 | + License along with the GNU C Library; if not, write to the Free | ||
5688 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
5689 | + 02111-1307 USA. */ | ||
5690 | + | ||
5691 | +#ifdef _LIBC | ||
5692 | +# include <shlib-compat.h> | ||
5693 | +versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4); | ||
5694 | + | ||
5695 | +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) | ||
5696 | +__typeof__ (__regexec) __compat_regexec; | ||
5697 | + | ||
5698 | +int | ||
5699 | +attribute_compat_text_section | ||
5700 | +__compat_regexec (const regex_t *__restrict preg, | ||
5701 | + const char *__restrict string, size_t nmatch, | ||
5702 | + regmatch_t pmatch[], int eflags) | ||
5703 | +{ | ||
5704 | + return regexec (preg, string, nmatch, pmatch, | ||
5705 | + eflags & (REG_NOTBOL | REG_NOTEOL)); | ||
5706 | +} | ||
5707 | +compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); | ||
5708 | +# endif | ||
5709 | +#endif | ||
5710 | Index: git/posix/regex.h | ||
5711 | =================================================================== | ||
5712 | --- git.orig/posix/regex.h 2014-08-29 20:00:53.264070587 -0700 | ||
5713 | +++ git/posix/regex.h 2014-08-29 20:01:15.224070587 -0700 | ||
5714 | @@ -21,6 +21,7 @@ | ||
5715 | #define _REGEX_H 1 | ||
5716 | |||
5717 | #include <sys/types.h> | ||
5718 | +#include <gnu/option-groups.h> | ||
5719 | |||
5720 | /* Allow the use in C++ code. */ | ||
5721 | #ifdef __cplusplus | ||
5722 | @@ -156,6 +157,8 @@ | ||
5723 | treated as 'a\{1'. */ | ||
5724 | # define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1) | ||
5725 | |||
5726 | +/* EGLIBC: Old regex implementation does not support these. */ | ||
5727 | +# ifdef __OPTION_POSIX_REGEXP_GLIBC | ||
5728 | /* If this bit is set, then ignore case when matching. | ||
5729 | If not set, then case is significant. */ | ||
5730 | # define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1) | ||
5731 | @@ -172,6 +175,7 @@ | ||
5732 | /* If this bit is set, then no_sub will be set to 1 during | ||
5733 | re_compile_pattern. */ | ||
5734 | # define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1) | ||
5735 | +# endif /* __OPTION_POSIX_REGEXP_GLIBC */ | ||
5736 | #endif | ||
5737 | |||
5738 | /* This global variable defines the particular regexp syntax to use (for | ||
5739 | @@ -231,8 +235,13 @@ | ||
5740 | (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ | ||
5741 | | RE_INTERVALS | RE_NO_EMPTY_RANGES) | ||
5742 | |||
5743 | +#ifdef __OPTION_POSIX_REGEXP_GLIBC | ||
5744 | #define RE_SYNTAX_POSIX_BASIC \ | ||
5745 | (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP) | ||
5746 | +#else | ||
5747 | +#define RE_SYNTAX_POSIX_BASIC \ | ||
5748 | + (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) | ||
5749 | +#endif | ||
5750 | |||
5751 | /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes | ||
5752 | RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this | ||
5753 | @@ -298,9 +307,11 @@ | ||
5754 | /* Like REG_NOTBOL, except for the end-of-line. */ | ||
5755 | #define REG_NOTEOL (1 << 1) | ||
5756 | |||
5757 | +#ifdef __OPTION_POSIX_REGEXP_GLIBC | ||
5758 | /* Use PMATCH[0] to delimit the start and end of the search in the | ||
5759 | buffer. */ | ||
5760 | #define REG_STARTEND (1 << 2) | ||
5761 | +#endif | ||
5762 | |||
5763 | |||
5764 | /* If any error codes are removed, changed, or added, update the | ||
5765 | Index: git/posix/regex_internal.c | ||
5766 | =================================================================== | ||
5767 | --- git.orig/posix/regex_internal.c 2014-08-29 20:00:53.264070587 -0700 | ||
5768 | +++ git/posix/regex_internal.c 2014-08-29 20:01:15.224070587 -0700 | ||
5769 | @@ -43,8 +43,8 @@ | ||
5770 | int init_buf_len; | ||
5771 | |||
5772 | /* Ensure at least one character fits into the buffers. */ | ||
5773 | - if (init_len < dfa->mb_cur_max) | ||
5774 | - init_len = dfa->mb_cur_max; | ||
5775 | + if (init_len < dfa_mb_cur_max (dfa)) | ||
5776 | + init_len = dfa_mb_cur_max (dfa); | ||
5777 | init_buf_len = (len + 1 < init_len) ? len + 1: init_len; | ||
5778 | re_string_construct_common (str, len, pstr, trans, icase, dfa); | ||
5779 | |||
5780 | @@ -55,7 +55,7 @@ | ||
5781 | pstr->word_char = dfa->word_char; | ||
5782 | pstr->word_ops_used = dfa->word_ops_used; | ||
5783 | pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; | ||
5784 | - pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len; | ||
5785 | + pstr->valid_len = (pstr->mbs_allocated || dfa_mb_cur_max (dfa) > 1) ? 0 : len; | ||
5786 | pstr->valid_raw_len = pstr->valid_len; | ||
5787 | return REG_NOERROR; | ||
5788 | } | ||
5789 | @@ -82,7 +82,7 @@ | ||
5790 | if (icase) | ||
5791 | { | ||
5792 | #ifdef RE_ENABLE_I18N | ||
5793 | - if (dfa->mb_cur_max > 1) | ||
5794 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5795 | { | ||
5796 | while (1) | ||
5797 | { | ||
5798 | @@ -91,7 +91,7 @@ | ||
5799 | return ret; | ||
5800 | if (pstr->valid_raw_len >= len) | ||
5801 | break; | ||
5802 | - if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max) | ||
5803 | + if (pstr->bufs_len > pstr->valid_len + dfa_mb_cur_max (dfa)) | ||
5804 | break; | ||
5805 | ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); | ||
5806 | if (BE (ret != REG_NOERROR, 0)) | ||
5807 | @@ -105,7 +105,7 @@ | ||
5808 | else | ||
5809 | { | ||
5810 | #ifdef RE_ENABLE_I18N | ||
5811 | - if (dfa->mb_cur_max > 1) | ||
5812 | + if (dfa_mb_cur_max (dfa) > 1) | ||
5813 | build_wcs_buffer (pstr); | ||
5814 | else | ||
5815 | #endif /* RE_ENABLE_I18N */ | ||
5816 | @@ -130,7 +130,7 @@ | ||
5817 | re_string_realloc_buffers (re_string_t *pstr, int new_buf_len) | ||
5818 | { | ||
5819 | #ifdef RE_ENABLE_I18N | ||
5820 | - if (pstr->mb_cur_max > 1) | ||
5821 | + if (string_mb_cur_max (pstr) > 1) | ||
5822 | { | ||
5823 | wint_t *new_wcs; | ||
5824 | |||
5825 | @@ -177,7 +177,7 @@ | ||
5826 | pstr->trans = trans; | ||
5827 | pstr->icase = icase ? 1 : 0; | ||
5828 | pstr->mbs_allocated = (trans != NULL || icase); | ||
5829 | - pstr->mb_cur_max = dfa->mb_cur_max; | ||
5830 | + pstr->mb_cur_max = dfa_mb_cur_max (dfa); | ||
5831 | pstr->is_utf8 = dfa->is_utf8; | ||
5832 | pstr->map_notascii = dfa->map_notascii; | ||
5833 | pstr->stop = pstr->len; | ||
5834 | @@ -203,7 +203,7 @@ | ||
5835 | { | ||
5836 | #ifdef _LIBC | ||
5837 | unsigned char buf[MB_LEN_MAX]; | ||
5838 | - assert (MB_LEN_MAX >= pstr->mb_cur_max); | ||
5839 | + assert (MB_LEN_MAX >= string_mb_cur_max (pstr)); | ||
5840 | #else | ||
5841 | unsigned char buf[64]; | ||
5842 | #endif | ||
5843 | @@ -226,7 +226,7 @@ | ||
5844 | { | ||
5845 | int i, ch; | ||
5846 | |||
5847 | - for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) | ||
5848 | + for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i) | ||
5849 | { | ||
5850 | ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i]; | ||
5851 | buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch]; | ||
5852 | @@ -275,7 +275,7 @@ | ||
5853 | size_t mbclen; | ||
5854 | #ifdef _LIBC | ||
5855 | char buf[MB_LEN_MAX]; | ||
5856 | - assert (MB_LEN_MAX >= pstr->mb_cur_max); | ||
5857 | + assert (MB_LEN_MAX >= string_mb_cur_max (pstr)); | ||
5858 | #else | ||
5859 | char buf[64]; | ||
5860 | #endif | ||
5861 | @@ -369,7 +369,7 @@ | ||
5862 | { | ||
5863 | int i, ch; | ||
5864 | |||
5865 | - for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) | ||
5866 | + for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i) | ||
5867 | { | ||
5868 | ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i]; | ||
5869 | buf[i] = pstr->trans[ch]; | ||
5870 | @@ -567,8 +567,9 @@ | ||
5871 | } | ||
5872 | |||
5873 | /* This function re-construct the buffers. | ||
5874 | - Concretely, convert to wide character in case of pstr->mb_cur_max > 1, | ||
5875 | - convert to upper case in case of REG_ICASE, apply translation. */ | ||
5876 | + Concretely, convert to wide character in case of | ||
5877 | + string_mb_cur_max (pstr) > 1, convert to upper case in case of | ||
5878 | + REG_ICASE, apply translation. */ | ||
5879 | |||
5880 | static reg_errcode_t | ||
5881 | internal_function __attribute_warn_unused_result__ | ||
5882 | @@ -579,7 +580,7 @@ | ||
5883 | { | ||
5884 | /* Reset buffer. */ | ||
5885 | #ifdef RE_ENABLE_I18N | ||
5886 | - if (pstr->mb_cur_max > 1) | ||
5887 | + if (string_mb_cur_max (pstr) > 1) | ||
5888 | memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); | ||
5889 | #endif /* RE_ENABLE_I18N */ | ||
5890 | pstr->len = pstr->raw_len; | ||
5891 | @@ -670,7 +671,7 @@ | ||
5892 | pstr->tip_context = re_string_context_at (pstr, offset - 1, | ||
5893 | eflags); | ||
5894 | #ifdef RE_ENABLE_I18N | ||
5895 | - if (pstr->mb_cur_max > 1) | ||
5896 | + if (string_mb_cur_max (pstr) > 1) | ||
5897 | memmove (pstr->wcs, pstr->wcs + offset, | ||
5898 | (pstr->valid_len - offset) * sizeof (wint_t)); | ||
5899 | #endif /* RE_ENABLE_I18N */ | ||
5900 | @@ -699,7 +700,7 @@ | ||
5901 | #endif | ||
5902 | pstr->valid_len = 0; | ||
5903 | #ifdef RE_ENABLE_I18N | ||
5904 | - if (pstr->mb_cur_max > 1) | ||
5905 | + if (string_mb_cur_max (pstr) > 1) | ||
5906 | { | ||
5907 | int wcs_idx; | ||
5908 | wint_t wc = WEOF; | ||
5909 | @@ -711,7 +712,7 @@ | ||
5910 | /* Special case UTF-8. Multi-byte chars start with any | ||
5911 | byte other than 0x80 - 0xbf. */ | ||
5912 | raw = pstr->raw_mbs + pstr->raw_mbs_idx; | ||
5913 | - end = raw + (offset - pstr->mb_cur_max); | ||
5914 | + end = raw + (offset - string_mb_cur_max (pstr)); | ||
5915 | if (end < pstr->raw_mbs) | ||
5916 | end = pstr->raw_mbs; | ||
5917 | p = raw + offset - 1; | ||
5918 | @@ -803,7 +804,7 @@ | ||
5919 | |||
5920 | /* Then build the buffers. */ | ||
5921 | #ifdef RE_ENABLE_I18N | ||
5922 | - if (pstr->mb_cur_max > 1) | ||
5923 | + if (string_mb_cur_max (pstr) > 1) | ||
5924 | { | ||
5925 | if (pstr->icase) | ||
5926 | { | ||
5927 | @@ -841,7 +842,7 @@ | ||
5928 | return re_string_peek_byte (pstr, idx); | ||
5929 | |||
5930 | #ifdef RE_ENABLE_I18N | ||
5931 | - if (pstr->mb_cur_max > 1 | ||
5932 | + if (string_mb_cur_max (pstr) > 1 | ||
5933 | && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx)) | ||
5934 | return re_string_peek_byte (pstr, idx); | ||
5935 | #endif | ||
5936 | @@ -930,7 +931,7 @@ | ||
5937 | return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF | ||
5938 | : CONTEXT_NEWLINE | CONTEXT_ENDBUF); | ||
5939 | #ifdef RE_ENABLE_I18N | ||
5940 | - if (input->mb_cur_max > 1) | ||
5941 | + if (string_mb_cur_max (input) > 1) | ||
5942 | { | ||
5943 | wint_t wc; | ||
5944 | int wc_idx = idx; | ||
5945 | @@ -1444,7 +1445,7 @@ | ||
5946 | dfa->nodes[dfa->nodes_len].constraint = 0; | ||
5947 | #ifdef RE_ENABLE_I18N | ||
5948 | dfa->nodes[dfa->nodes_len].accept_mb = | ||
5949 | - (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET; | ||
5950 | + (type == OP_PERIOD && dfa_mb_cur_max (dfa) > 1) || type == COMPLEX_BRACKET; | ||
5951 | #endif | ||
5952 | dfa->nexts[dfa->nodes_len] = -1; | ||
5953 | re_node_set_init_empty (dfa->edests + dfa->nodes_len); | ||
5954 | Index: git/posix/regex_internal.h | ||
5955 | =================================================================== | ||
5956 | --- git.orig/posix/regex_internal.h 2014-08-29 20:00:53.264070587 -0700 | ||
5957 | +++ git/posix/regex_internal.h 2014-08-29 20:01:15.224070587 -0700 | ||
5958 | @@ -26,6 +26,10 @@ | ||
5959 | #include <stdlib.h> | ||
5960 | #include <string.h> | ||
5961 | |||
5962 | +#if defined _LIBC | ||
5963 | +# include <gnu/option-groups.h> | ||
5964 | +#endif | ||
5965 | + | ||
5966 | #if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC | ||
5967 | # include <langinfo.h> | ||
5968 | #endif | ||
5969 | @@ -370,6 +374,13 @@ | ||
5970 | }; | ||
5971 | typedef struct re_string_t re_string_t; | ||
5972 | |||
5973 | +/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1; | ||
5974 | + help the compiler make use of that fact. */ | ||
5975 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
5976 | +# define string_mb_cur_max(str) ((str)->mb_cur_max + 0) | ||
5977 | +#else | ||
5978 | +# define string_mb_cur_max(str) (1) | ||
5979 | +#endif | ||
5980 | |||
5981 | struct re_dfa_t; | ||
5982 | typedef struct re_dfa_t re_dfa_t; | ||
5983 | @@ -655,6 +666,14 @@ | ||
5984 | __libc_lock_define (, lock) | ||
5985 | }; | ||
5986 | |||
5987 | +/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1; | ||
5988 | + help the compiler make use of that fact. */ | ||
5989 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
5990 | +# define dfa_mb_cur_max(dfa) ((dfa)->mb_cur_max + 0) | ||
5991 | +#else | ||
5992 | +# define dfa_mb_cur_max(dfa) (1) | ||
5993 | +#endif | ||
5994 | + | ||
5995 | #define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set)) | ||
5996 | #define re_node_set_remove(set,id) \ | ||
5997 | (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1)) | ||
5998 | @@ -715,7 +734,7 @@ | ||
5999 | re_string_char_size_at (const re_string_t *pstr, int idx) | ||
6000 | { | ||
6001 | int byte_idx; | ||
6002 | - if (pstr->mb_cur_max == 1) | ||
6003 | + if (string_mb_cur_max (pstr) == 1) | ||
6004 | return 1; | ||
6005 | for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx) | ||
6006 | if (pstr->wcs[idx + byte_idx] != WEOF) | ||
6007 | @@ -727,7 +746,7 @@ | ||
6008 | internal_function __attribute__ ((pure, unused)) | ||
6009 | re_string_wchar_at (const re_string_t *pstr, int idx) | ||
6010 | { | ||
6011 | - if (pstr->mb_cur_max == 1) | ||
6012 | + if (string_mb_cur_max (pstr) == 1) | ||
6013 | return (wint_t) pstr->mbs[idx]; | ||
6014 | return (wint_t) pstr->wcs[idx]; | ||
6015 | } | ||
6016 | Index: git/posix/xregex.c | ||
6017 | =================================================================== | ||
6018 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
6019 | +++ git/posix/xregex.c 2014-08-29 20:01:15.228070587 -0700 | ||
6020 | @@ -0,0 +1,8212 @@ | ||
6021 | +/* Extended regular expression matching and search library, | ||
6022 | + version 0.12. | ||
6023 | + (Implements POSIX draft P1003.2/D11.2, except for some of the | ||
6024 | + internationalization features.) | ||
6025 | + | ||
6026 | + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, | ||
6027 | + 2002, 2005 Free Software Foundation, Inc. | ||
6028 | + This file is part of the GNU C Library. | ||
6029 | + | ||
6030 | + The GNU C Library is free software; you can redistribute it and/or | ||
6031 | + modify it under the terms of the GNU Lesser General Public | ||
6032 | + License as published by the Free Software Foundation; either | ||
6033 | + version 2.1 of the License, or (at your option) any later version. | ||
6034 | + | ||
6035 | + The GNU C Library is distributed in the hope that it will be useful, | ||
6036 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
6037 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
6038 | + Lesser General Public License for more details. | ||
6039 | + | ||
6040 | + You should have received a copy of the GNU Lesser General Public | ||
6041 | + License along with the GNU C Library; if not, write to the Free | ||
6042 | + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
6043 | + 02110-1301 USA. */ | ||
6044 | + | ||
6045 | +/* AIX requires this to be the first thing in the file. */ | ||
6046 | +#if defined _AIX && !defined __GNUC__ && !defined REGEX_MALLOC | ||
6047 | + #pragma alloca | ||
6048 | +#endif | ||
6049 | + | ||
6050 | +#undef _GNU_SOURCE | ||
6051 | +#define _GNU_SOURCE | ||
6052 | + | ||
6053 | +#ifndef INSIDE_RECURSION | ||
6054 | +# ifdef HAVE_CONFIG_H | ||
6055 | +# include <config.h> | ||
6056 | +# endif | ||
6057 | +#endif | ||
6058 | + | ||
6059 | +/*#include <ansidecl.h>*/ | ||
6060 | + | ||
6061 | +#ifndef INSIDE_RECURSION | ||
6062 | + | ||
6063 | +# if defined STDC_HEADERS && !defined emacs | ||
6064 | +# include <stddef.h> | ||
6065 | +# else | ||
6066 | +/* We need this for `regex.h', and perhaps for the Emacs include files. */ | ||
6067 | +# include <sys/types.h> | ||
6068 | +# endif | ||
6069 | + | ||
6070 | +# define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC) | ||
6071 | + | ||
6072 | +/* For platform which support the ISO C amendement 1 functionality we | ||
6073 | + support user defined character classes. */ | ||
6074 | +# if WIDE_CHAR_SUPPORT | ||
6075 | +/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ | ||
6076 | +# include <wchar.h> | ||
6077 | +# include <wctype.h> | ||
6078 | +# endif | ||
6079 | + | ||
6080 | +# ifdef _LIBC | ||
6081 | +/* We have to keep the namespace clean. */ | ||
6082 | +# define regfree(preg) __regfree (preg) | ||
6083 | +# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) | ||
6084 | +# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) | ||
6085 | +# define regerror(errcode, preg, errbuf, errbuf_size) \ | ||
6086 | + __regerror(errcode, preg, errbuf, errbuf_size) | ||
6087 | +# define re_set_registers(bu, re, nu, st, en) \ | ||
6088 | + __re_set_registers (bu, re, nu, st, en) | ||
6089 | +# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ | ||
6090 | + __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) | ||
6091 | +# define re_match(bufp, string, size, pos, regs) \ | ||
6092 | + __re_match (bufp, string, size, pos, regs) | ||
6093 | +# define re_search(bufp, string, size, startpos, range, regs) \ | ||
6094 | + __re_search (bufp, string, size, startpos, range, regs) | ||
6095 | +# define re_compile_pattern(pattern, length, bufp) \ | ||
6096 | + __re_compile_pattern (pattern, length, bufp) | ||
6097 | +# define re_set_syntax(syntax) __re_set_syntax (syntax) | ||
6098 | +# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ | ||
6099 | + __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) | ||
6100 | +# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) | ||
6101 | + | ||
6102 | +# define btowc __btowc | ||
6103 | + | ||
6104 | +/* We are also using some library internals. */ | ||
6105 | +# include <locale/localeinfo.h> | ||
6106 | +# include <locale/elem-hash.h> | ||
6107 | +# include <langinfo.h> | ||
6108 | +# include <locale/coll-lookup.h> | ||
6109 | +# endif | ||
6110 | + | ||
6111 | +/* This is for other GNU distributions with internationalized messages. */ | ||
6112 | +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC | ||
6113 | +# include <libintl.h> | ||
6114 | +# ifdef _LIBC | ||
6115 | +# undef gettext | ||
6116 | +# define gettext(msgid) __dcgettext ("libc", msgid, LC_MESSAGES) | ||
6117 | +# endif | ||
6118 | +# else | ||
6119 | +# define gettext(msgid) (msgid) | ||
6120 | +# endif | ||
6121 | + | ||
6122 | +# ifndef gettext_noop | ||
6123 | +/* This define is so xgettext can find the internationalizable | ||
6124 | + strings. */ | ||
6125 | +# define gettext_noop(String) String | ||
6126 | +# endif | ||
6127 | + | ||
6128 | +/* The `emacs' switch turns on certain matching commands | ||
6129 | + that make sense only in Emacs. */ | ||
6130 | +# ifdef emacs | ||
6131 | + | ||
6132 | +# include "lisp.h" | ||
6133 | +# include "buffer.h" | ||
6134 | +# include "syntax.h" | ||
6135 | + | ||
6136 | +# else /* not emacs */ | ||
6137 | + | ||
6138 | +/* If we are not linking with Emacs proper, | ||
6139 | + we can't use the relocating allocator | ||
6140 | + even if config.h says that we can. */ | ||
6141 | +# undef REL_ALLOC | ||
6142 | + | ||
6143 | +# if defined STDC_HEADERS || defined _LIBC | ||
6144 | +# include <stdlib.h> | ||
6145 | +# else | ||
6146 | +char *malloc (); | ||
6147 | +char *realloc (); | ||
6148 | +# endif | ||
6149 | + | ||
6150 | +/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow. | ||
6151 | + If nothing else has been done, use the method below. */ | ||
6152 | +# ifdef INHIBIT_STRING_HEADER | ||
6153 | +# if !(defined HAVE_BZERO && defined HAVE_BCOPY) | ||
6154 | +# if !defined bzero && !defined bcopy | ||
6155 | +# undef INHIBIT_STRING_HEADER | ||
6156 | +# endif | ||
6157 | +# endif | ||
6158 | +# endif | ||
6159 | + | ||
6160 | +/* This is the normal way of making sure we have a bcopy and a bzero. | ||
6161 | + This is used in most programs--a few other programs avoid this | ||
6162 | + by defining INHIBIT_STRING_HEADER. */ | ||
6163 | +# ifndef INHIBIT_STRING_HEADER | ||
6164 | +# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC | ||
6165 | +# include <string.h> | ||
6166 | +# ifndef bzero | ||
6167 | +# ifndef _LIBC | ||
6168 | +# define bzero(s, n) (memset (s, '\0', n), (s)) | ||
6169 | +# else | ||
6170 | +# define bzero(s, n) __bzero (s, n) | ||
6171 | +# endif | ||
6172 | +# endif | ||
6173 | +# else | ||
6174 | +# include <strings.h> | ||
6175 | +# ifndef memcmp | ||
6176 | +# define memcmp(s1, s2, n) bcmp (s1, s2, n) | ||
6177 | +# endif | ||
6178 | +# ifndef memcpy | ||
6179 | +# define memcpy(d, s, n) (bcopy (s, d, n), (d)) | ||
6180 | +# endif | ||
6181 | +# endif | ||
6182 | +# endif | ||
6183 | + | ||
6184 | +/* Define the syntax stuff for \<, \>, etc. */ | ||
6185 | + | ||
6186 | +/* This must be nonzero for the wordchar and notwordchar pattern | ||
6187 | + commands in re_match_2. */ | ||
6188 | +# ifndef Sword | ||
6189 | +# define Sword 1 | ||
6190 | +# endif | ||
6191 | + | ||
6192 | +# ifdef SWITCH_ENUM_BUG | ||
6193 | +# define SWITCH_ENUM_CAST(x) ((int)(x)) | ||
6194 | +# else | ||
6195 | +# define SWITCH_ENUM_CAST(x) (x) | ||
6196 | +# endif | ||
6197 | + | ||
6198 | +# endif /* not emacs */ | ||
6199 | + | ||
6200 | +# if defined _LIBC || HAVE_LIMITS_H | ||
6201 | +# include <limits.h> | ||
6202 | +# endif | ||
6203 | + | ||
6204 | +# ifndef MB_LEN_MAX | ||
6205 | +# define MB_LEN_MAX 1 | ||
6206 | +# endif | ||
6207 | + | ||
6208 | +/* Get the interface, including the syntax bits. */ | ||
6209 | +# include "regex.h" | ||
6210 | + | ||
6211 | +/* isalpha etc. are used for the character classes. */ | ||
6212 | +# include <ctype.h> | ||
6213 | + | ||
6214 | +/* Jim Meyering writes: | ||
6215 | + | ||
6216 | + "... Some ctype macros are valid only for character codes that | ||
6217 | + isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when | ||
6218 | + using /bin/cc or gcc but without giving an ansi option). So, all | ||
6219 | + ctype uses should be through macros like ISPRINT... If | ||
6220 | + STDC_HEADERS is defined, then autoconf has verified that the ctype | ||
6221 | + macros don't need to be guarded with references to isascii. ... | ||
6222 | + Defining isascii to 1 should let any compiler worth its salt | ||
6223 | + eliminate the && through constant folding." | ||
6224 | + Solaris defines some of these symbols so we must undefine them first. */ | ||
6225 | + | ||
6226 | +# undef ISASCII | ||
6227 | +# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII) | ||
6228 | +# define ISASCII(c) 1 | ||
6229 | +# else | ||
6230 | +# define ISASCII(c) isascii(c) | ||
6231 | +# endif | ||
6232 | + | ||
6233 | +# ifdef isblank | ||
6234 | +# define ISBLANK(c) (ISASCII (c) && isblank (c)) | ||
6235 | +# else | ||
6236 | +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') | ||
6237 | +# endif | ||
6238 | +# ifdef isgraph | ||
6239 | +# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) | ||
6240 | +# else | ||
6241 | +# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) | ||
6242 | +# endif | ||
6243 | + | ||
6244 | +# undef ISPRINT | ||
6245 | +# define ISPRINT(c) (ISASCII (c) && isprint (c)) | ||
6246 | +# define ISDIGIT(c) (ISASCII (c) && isdigit (c)) | ||
6247 | +# define ISALNUM(c) (ISASCII (c) && isalnum (c)) | ||
6248 | +# define ISALPHA(c) (ISASCII (c) && isalpha (c)) | ||
6249 | +# define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) | ||
6250 | +# define ISLOWER(c) (ISASCII (c) && islower (c)) | ||
6251 | +# define ISPUNCT(c) (ISASCII (c) && ispunct (c)) | ||
6252 | +# define ISSPACE(c) (ISASCII (c) && isspace (c)) | ||
6253 | +# define ISUPPER(c) (ISASCII (c) && isupper (c)) | ||
6254 | +# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) | ||
6255 | + | ||
6256 | +# ifdef _tolower | ||
6257 | +# define TOLOWER(c) _tolower(c) | ||
6258 | +# else | ||
6259 | +# define TOLOWER(c) tolower(c) | ||
6260 | +# endif | ||
6261 | + | ||
6262 | +# ifndef NULL | ||
6263 | +# define NULL (void *)0 | ||
6264 | +# endif | ||
6265 | + | ||
6266 | +/* We remove any previous definition of `SIGN_EXTEND_CHAR', | ||
6267 | + since ours (we hope) works properly with all combinations of | ||
6268 | + machines, compilers, `char' and `unsigned char' argument types. | ||
6269 | + (Per Bothner suggested the basic approach.) */ | ||
6270 | +# undef SIGN_EXTEND_CHAR | ||
6271 | +# if __STDC__ | ||
6272 | +# define SIGN_EXTEND_CHAR(c) ((signed char) (c)) | ||
6273 | +# else /* not __STDC__ */ | ||
6274 | +/* As in Harbison and Steele. */ | ||
6275 | +# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) | ||
6276 | +# endif | ||
6277 | + | ||
6278 | +# ifndef emacs | ||
6279 | +/* How many characters in the character set. */ | ||
6280 | +# define CHAR_SET_SIZE 256 | ||
6281 | + | ||
6282 | +# ifdef SYNTAX_TABLE | ||
6283 | + | ||
6284 | +extern char *re_syntax_table; | ||
6285 | + | ||
6286 | +# else /* not SYNTAX_TABLE */ | ||
6287 | + | ||
6288 | +static char re_syntax_table[CHAR_SET_SIZE]; | ||
6289 | + | ||
6290 | +static void init_syntax_once (void); | ||
6291 | + | ||
6292 | +static void | ||
6293 | +init_syntax_once (void) | ||
6294 | +{ | ||
6295 | + register int c; | ||
6296 | + static int done = 0; | ||
6297 | + | ||
6298 | + if (done) | ||
6299 | + return; | ||
6300 | + bzero (re_syntax_table, sizeof re_syntax_table); | ||
6301 | + | ||
6302 | + for (c = 0; c < CHAR_SET_SIZE; ++c) | ||
6303 | + if (ISALNUM (c)) | ||
6304 | + re_syntax_table[c] = Sword; | ||
6305 | + | ||
6306 | + re_syntax_table['_'] = Sword; | ||
6307 | + | ||
6308 | + done = 1; | ||
6309 | +} | ||
6310 | + | ||
6311 | +# endif /* not SYNTAX_TABLE */ | ||
6312 | + | ||
6313 | +# define SYNTAX(c) re_syntax_table[(unsigned char) (c)] | ||
6314 | + | ||
6315 | +# endif /* emacs */ | ||
6316 | + | ||
6317 | +/* Integer type for pointers. */ | ||
6318 | +# if !defined _LIBC && !defined HAVE_UINTPTR_T | ||
6319 | +typedef unsigned long int uintptr_t; | ||
6320 | +# endif | ||
6321 | + | ||
6322 | +/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we | ||
6323 | + use `alloca' instead of `malloc'. This is because using malloc in | ||
6324 | + re_search* or re_match* could cause memory leaks when C-g is used in | ||
6325 | + Emacs; also, malloc is slower and causes storage fragmentation. On | ||
6326 | + the other hand, malloc is more portable, and easier to debug. | ||
6327 | + | ||
6328 | + Because we sometimes use alloca, some routines have to be macros, | ||
6329 | + not functions -- `alloca'-allocated space disappears at the end of the | ||
6330 | + function it is called in. */ | ||
6331 | + | ||
6332 | +# ifdef REGEX_MALLOC | ||
6333 | + | ||
6334 | +# define REGEX_ALLOCATE malloc | ||
6335 | +# define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) | ||
6336 | +# define REGEX_FREE free | ||
6337 | + | ||
6338 | +# else /* not REGEX_MALLOC */ | ||
6339 | + | ||
6340 | +/* Emacs already defines alloca, sometimes. */ | ||
6341 | +# ifndef alloca | ||
6342 | + | ||
6343 | +/* Make alloca work the best possible way. */ | ||
6344 | +# ifdef __GNUC__ | ||
6345 | +# define alloca __builtin_alloca | ||
6346 | +# else /* not __GNUC__ */ | ||
6347 | +# if HAVE_ALLOCA_H | ||
6348 | +# include <alloca.h> | ||
6349 | +# endif /* HAVE_ALLOCA_H */ | ||
6350 | +# endif /* not __GNUC__ */ | ||
6351 | + | ||
6352 | +# endif /* not alloca */ | ||
6353 | + | ||
6354 | +# define REGEX_ALLOCATE alloca | ||
6355 | + | ||
6356 | +/* Assumes a `char *destination' variable. */ | ||
6357 | +# define REGEX_REALLOCATE(source, osize, nsize) \ | ||
6358 | + (destination = (char *) alloca (nsize), \ | ||
6359 | + memcpy (destination, source, osize)) | ||
6360 | + | ||
6361 | +/* No need to do anything to free, after alloca. */ | ||
6362 | +# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */ | ||
6363 | + | ||
6364 | +# endif /* not REGEX_MALLOC */ | ||
6365 | + | ||
6366 | +/* Define how to allocate the failure stack. */ | ||
6367 | + | ||
6368 | +# if defined REL_ALLOC && defined REGEX_MALLOC | ||
6369 | + | ||
6370 | +# define REGEX_ALLOCATE_STACK(size) \ | ||
6371 | + r_alloc (&failure_stack_ptr, (size)) | ||
6372 | +# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ | ||
6373 | + r_re_alloc (&failure_stack_ptr, (nsize)) | ||
6374 | +# define REGEX_FREE_STACK(ptr) \ | ||
6375 | + r_alloc_free (&failure_stack_ptr) | ||
6376 | + | ||
6377 | +# else /* not using relocating allocator */ | ||
6378 | + | ||
6379 | +# ifdef REGEX_MALLOC | ||
6380 | + | ||
6381 | +# define REGEX_ALLOCATE_STACK malloc | ||
6382 | +# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize) | ||
6383 | +# define REGEX_FREE_STACK free | ||
6384 | + | ||
6385 | +# else /* not REGEX_MALLOC */ | ||
6386 | + | ||
6387 | +# define REGEX_ALLOCATE_STACK alloca | ||
6388 | + | ||
6389 | +# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ | ||
6390 | + REGEX_REALLOCATE (source, osize, nsize) | ||
6391 | +/* No need to explicitly free anything. */ | ||
6392 | +# define REGEX_FREE_STACK(arg) | ||
6393 | + | ||
6394 | +# endif /* not REGEX_MALLOC */ | ||
6395 | +# endif /* not using relocating allocator */ | ||
6396 | + | ||
6397 | + | ||
6398 | +/* True if `size1' is non-NULL and PTR is pointing anywhere inside | ||
6399 | + `string1' or just past its end. This works if PTR is NULL, which is | ||
6400 | + a good thing. */ | ||
6401 | +# define FIRST_STRING_P(ptr) \ | ||
6402 | + (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) | ||
6403 | + | ||
6404 | +/* (Re)Allocate N items of type T using malloc, or fail. */ | ||
6405 | +# define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) | ||
6406 | +# define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) | ||
6407 | +# define RETALLOC_IF(addr, n, t) \ | ||
6408 | + if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t) | ||
6409 | +# define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) | ||
6410 | + | ||
6411 | +# define BYTEWIDTH 8 /* In bits. */ | ||
6412 | + | ||
6413 | +# define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) | ||
6414 | + | ||
6415 | +# undef MAX | ||
6416 | +# undef MIN | ||
6417 | +# define MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
6418 | +# define MIN(a, b) ((a) < (b) ? (a) : (b)) | ||
6419 | + | ||
6420 | +typedef char boolean; | ||
6421 | +# define false 0 | ||
6422 | +# define true 1 | ||
6423 | + | ||
6424 | +static reg_errcode_t byte_regex_compile (const char *pattern, size_t size, | ||
6425 | + reg_syntax_t syntax, | ||
6426 | + struct re_pattern_buffer *bufp); | ||
6427 | + | ||
6428 | +static int byte_re_match_2_internal (struct re_pattern_buffer *bufp, | ||
6429 | + const char *string1, int size1, | ||
6430 | + const char *string2, int size2, | ||
6431 | + int pos, | ||
6432 | + struct re_registers *regs, | ||
6433 | + int stop); | ||
6434 | +static int byte_re_search_2 (struct re_pattern_buffer *bufp, | ||
6435 | + const char *string1, int size1, | ||
6436 | + const char *string2, int size2, | ||
6437 | + int startpos, int range, | ||
6438 | + struct re_registers *regs, int stop); | ||
6439 | +static int byte_re_compile_fastmap (struct re_pattern_buffer *bufp); | ||
6440 | + | ||
6441 | +#ifdef MBS_SUPPORT | ||
6442 | +static reg_errcode_t wcs_regex_compile (const char *pattern, size_t size, | ||
6443 | + reg_syntax_t syntax, | ||
6444 | + struct re_pattern_buffer *bufp); | ||
6445 | + | ||
6446 | + | ||
6447 | +static int wcs_re_match_2_internal (struct re_pattern_buffer *bufp, | ||
6448 | + const char *cstring1, int csize1, | ||
6449 | + const char *cstring2, int csize2, | ||
6450 | + int pos, | ||
6451 | + struct re_registers *regs, | ||
6452 | + int stop, | ||
6453 | + wchar_t *string1, int size1, | ||
6454 | + wchar_t *string2, int size2, | ||
6455 | + int *mbs_offset1, int *mbs_offset2); | ||
6456 | +static int wcs_re_search_2 (struct re_pattern_buffer *bufp, | ||
6457 | + const char *string1, int size1, | ||
6458 | + const char *string2, int size2, | ||
6459 | + int startpos, int range, | ||
6460 | + struct re_registers *regs, int stop); | ||
6461 | +static int wcs_re_compile_fastmap (struct re_pattern_buffer *bufp); | ||
6462 | +#endif | ||
6463 | + | ||
6464 | +/* These are the command codes that appear in compiled regular | ||
6465 | + expressions. Some opcodes are followed by argument bytes. A | ||
6466 | + command code can specify any interpretation whatsoever for its | ||
6467 | + arguments. Zero bytes may appear in the compiled regular expression. */ | ||
6468 | + | ||
6469 | +typedef enum | ||
6470 | +{ | ||
6471 | + no_op = 0, | ||
6472 | + | ||
6473 | + /* Succeed right away--no more backtracking. */ | ||
6474 | + succeed, | ||
6475 | + | ||
6476 | + /* Followed by one byte giving n, then by n literal bytes. */ | ||
6477 | + exactn, | ||
6478 | + | ||
6479 | +# ifdef MBS_SUPPORT | ||
6480 | + /* Same as exactn, but contains binary data. */ | ||
6481 | + exactn_bin, | ||
6482 | +# endif | ||
6483 | + | ||
6484 | + /* Matches any (more or less) character. */ | ||
6485 | + anychar, | ||
6486 | + | ||
6487 | + /* Matches any one char belonging to specified set. First | ||
6488 | + following byte is number of bitmap bytes. Then come bytes | ||
6489 | + for a bitmap saying which chars are in. Bits in each byte | ||
6490 | + are ordered low-bit-first. A character is in the set if its | ||
6491 | + bit is 1. A character too large to have a bit in the map is | ||
6492 | + automatically not in the set. */ | ||
6493 | + /* ifdef MBS_SUPPORT, following element is length of character | ||
6494 | + classes, length of collating symbols, length of equivalence | ||
6495 | + classes, length of character ranges, and length of characters. | ||
6496 | + Next, character class element, collating symbols elements, | ||
6497 | + equivalence class elements, range elements, and character | ||
6498 | + elements follow. | ||
6499 | + See regex_compile function. */ | ||
6500 | + charset, | ||
6501 | + | ||
6502 | + /* Same parameters as charset, but match any character that is | ||
6503 | + not one of those specified. */ | ||
6504 | + charset_not, | ||
6505 | + | ||
6506 | + /* Start remembering the text that is matched, for storing in a | ||
6507 | + register. Followed by one byte with the register number, in | ||
6508 | + the range 0 to one less than the pattern buffer's re_nsub | ||
6509 | + field. Then followed by one byte with the number of groups | ||
6510 | + inner to this one. (This last has to be part of the | ||
6511 | + start_memory only because we need it in the on_failure_jump | ||
6512 | + of re_match_2.) */ | ||
6513 | + start_memory, | ||
6514 | + | ||
6515 | + /* Stop remembering the text that is matched and store it in a | ||
6516 | + memory register. Followed by one byte with the register | ||
6517 | + number, in the range 0 to one less than `re_nsub' in the | ||
6518 | + pattern buffer, and one byte with the number of inner groups, | ||
6519 | + just like `start_memory'. (We need the number of inner | ||
6520 | + groups here because we don't have any easy way of finding the | ||
6521 | + corresponding start_memory when we're at a stop_memory.) */ | ||
6522 | + stop_memory, | ||
6523 | + | ||
6524 | + /* Match a duplicate of something remembered. Followed by one | ||
6525 | + byte containing the register number. */ | ||
6526 | + duplicate, | ||
6527 | + | ||
6528 | + /* Fail unless at beginning of line. */ | ||
6529 | + begline, | ||
6530 | + | ||
6531 | + /* Fail unless at end of line. */ | ||
6532 | + endline, | ||
6533 | + | ||
6534 | + /* Succeeds if at beginning of buffer (if emacs) or at beginning | ||
6535 | + of string to be matched (if not). */ | ||
6536 | + begbuf, | ||
6537 | + | ||
6538 | + /* Analogously, for end of buffer/string. */ | ||
6539 | + endbuf, | ||
6540 | + | ||
6541 | + /* Followed by two byte relative address to which to jump. */ | ||
6542 | + jump, | ||
6543 | + | ||
6544 | + /* Same as jump, but marks the end of an alternative. */ | ||
6545 | + jump_past_alt, | ||
6546 | + | ||
6547 | + /* Followed by two-byte relative address of place to resume at | ||
6548 | + in case of failure. */ | ||
6549 | + /* ifdef MBS_SUPPORT, the size of address is 1. */ | ||
6550 | + on_failure_jump, | ||
6551 | + | ||
6552 | + /* Like on_failure_jump, but pushes a placeholder instead of the | ||
6553 | + current string position when executed. */ | ||
6554 | + on_failure_keep_string_jump, | ||
6555 | + | ||
6556 | + /* Throw away latest failure point and then jump to following | ||
6557 | + two-byte relative address. */ | ||
6558 | + /* ifdef MBS_SUPPORT, the size of address is 1. */ | ||
6559 | + pop_failure_jump, | ||
6560 | + | ||
6561 | + /* Change to pop_failure_jump if know won't have to backtrack to | ||
6562 | + match; otherwise change to jump. This is used to jump | ||
6563 | + back to the beginning of a repeat. If what follows this jump | ||
6564 | + clearly won't match what the repeat does, such that we can be | ||
6565 | + sure that there is no use backtracking out of repetitions | ||
6566 | + already matched, then we change it to a pop_failure_jump. | ||
6567 | + Followed by two-byte address. */ | ||
6568 | + /* ifdef MBS_SUPPORT, the size of address is 1. */ | ||
6569 | + maybe_pop_jump, | ||
6570 | + | ||
6571 | + /* Jump to following two-byte address, and push a dummy failure | ||
6572 | + point. This failure point will be thrown away if an attempt | ||
6573 | + is made to use it for a failure. A `+' construct makes this | ||
6574 | + before the first repeat. Also used as an intermediary kind | ||
6575 | + of jump when compiling an alternative. */ | ||
6576 | + /* ifdef MBS_SUPPORT, the size of address is 1. */ | ||
6577 | + dummy_failure_jump, | ||
6578 | + | ||
6579 | + /* Push a dummy failure point and continue. Used at the end of | ||
6580 | + alternatives. */ | ||
6581 | + push_dummy_failure, | ||
6582 | + | ||
6583 | + /* Followed by two-byte relative address and two-byte number n. | ||
6584 | + After matching N times, jump to the address upon failure. */ | ||
6585 | + /* ifdef MBS_SUPPORT, the size of address is 1. */ | ||
6586 | + succeed_n, | ||
6587 | + | ||
6588 | + /* Followed by two-byte relative address, and two-byte number n. | ||
6589 | + Jump to the address N times, then fail. */ | ||
6590 | + /* ifdef MBS_SUPPORT, the size of address is 1. */ | ||
6591 | + jump_n, | ||
6592 | + | ||
6593 | + /* Set the following two-byte relative address to the | ||
6594 | + subsequent two-byte number. The address *includes* the two | ||
6595 | + bytes of number. */ | ||
6596 | + /* ifdef MBS_SUPPORT, the size of address is 1. */ | ||
6597 | + set_number_at, | ||
6598 | + | ||
6599 | + wordchar, /* Matches any word-constituent character. */ | ||
6600 | + notwordchar, /* Matches any char that is not a word-constituent. */ | ||
6601 | + | ||
6602 | + wordbeg, /* Succeeds if at word beginning. */ | ||
6603 | + wordend, /* Succeeds if at word end. */ | ||
6604 | + | ||
6605 | + wordbound, /* Succeeds if at a word boundary. */ | ||
6606 | + notwordbound /* Succeeds if not at a word boundary. */ | ||
6607 | + | ||
6608 | +# ifdef emacs | ||
6609 | + ,before_dot, /* Succeeds if before point. */ | ||
6610 | + at_dot, /* Succeeds if at point. */ | ||
6611 | + after_dot, /* Succeeds if after point. */ | ||
6612 | + | ||
6613 | + /* Matches any character whose syntax is specified. Followed by | ||
6614 | + a byte which contains a syntax code, e.g., Sword. */ | ||
6615 | + syntaxspec, | ||
6616 | + | ||
6617 | + /* Matches any character whose syntax is not that specified. */ | ||
6618 | + notsyntaxspec | ||
6619 | +# endif /* emacs */ | ||
6620 | +} re_opcode_t; | ||
6621 | +#endif /* not INSIDE_RECURSION */ | ||
6622 | + | ||
6623 | + | ||
6624 | +#ifdef BYTE | ||
6625 | +# define CHAR_T char | ||
6626 | +# define UCHAR_T unsigned char | ||
6627 | +# define COMPILED_BUFFER_VAR bufp->buffer | ||
6628 | +# define OFFSET_ADDRESS_SIZE 2 | ||
6629 | +# define PREFIX(name) byte_##name | ||
6630 | +# define ARG_PREFIX(name) name | ||
6631 | +# define PUT_CHAR(c) putchar (c) | ||
6632 | +#else | ||
6633 | +# ifdef WCHAR | ||
6634 | +# define CHAR_T wchar_t | ||
6635 | +# define UCHAR_T wchar_t | ||
6636 | +# define COMPILED_BUFFER_VAR wc_buffer | ||
6637 | +# define OFFSET_ADDRESS_SIZE 1 /* the size which STORE_NUMBER macro use */ | ||
6638 | +# define CHAR_CLASS_SIZE ((__alignof__(wctype_t)+sizeof(wctype_t))/sizeof(CHAR_T)+1) | ||
6639 | +# define PREFIX(name) wcs_##name | ||
6640 | +# define ARG_PREFIX(name) c##name | ||
6641 | +/* Should we use wide stream?? */ | ||
6642 | +# define PUT_CHAR(c) printf ("%C", c); | ||
6643 | +# define TRUE 1 | ||
6644 | +# define FALSE 0 | ||
6645 | +# else | ||
6646 | +# ifdef MBS_SUPPORT | ||
6647 | +# define WCHAR | ||
6648 | +# define INSIDE_RECURSION | ||
6649 | +# include "xregex.c" | ||
6650 | +# undef INSIDE_RECURSION | ||
6651 | +# endif | ||
6652 | +# define BYTE | ||
6653 | +# define INSIDE_RECURSION | ||
6654 | +# include "xregex.c" | ||
6655 | +# undef INSIDE_RECURSION | ||
6656 | +# endif | ||
6657 | +#endif | ||
6658 | + | ||
6659 | +#ifdef INSIDE_RECURSION | ||
6660 | +/* Common operations on the compiled pattern. */ | ||
6661 | + | ||
6662 | +/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ | ||
6663 | +/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */ | ||
6664 | + | ||
6665 | +# ifdef WCHAR | ||
6666 | +# define STORE_NUMBER(destination, number) \ | ||
6667 | + do { \ | ||
6668 | + *(destination) = (UCHAR_T)(number); \ | ||
6669 | + } while (0) | ||
6670 | +# else /* BYTE */ | ||
6671 | +# define STORE_NUMBER(destination, number) \ | ||
6672 | + do { \ | ||
6673 | + (destination)[0] = (number) & 0377; \ | ||
6674 | + (destination)[1] = (number) >> 8; \ | ||
6675 | + } while (0) | ||
6676 | +# endif /* WCHAR */ | ||
6677 | + | ||
6678 | +/* Same as STORE_NUMBER, except increment DESTINATION to | ||
6679 | + the byte after where the number is stored. Therefore, DESTINATION | ||
6680 | + must be an lvalue. */ | ||
6681 | +/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */ | ||
6682 | + | ||
6683 | +# define STORE_NUMBER_AND_INCR(destination, number) \ | ||
6684 | + do { \ | ||
6685 | + STORE_NUMBER (destination, number); \ | ||
6686 | + (destination) += OFFSET_ADDRESS_SIZE; \ | ||
6687 | + } while (0) | ||
6688 | + | ||
6689 | +/* Put into DESTINATION a number stored in two contiguous bytes starting | ||
6690 | + at SOURCE. */ | ||
6691 | +/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */ | ||
6692 | + | ||
6693 | +# ifdef WCHAR | ||
6694 | +# define EXTRACT_NUMBER(destination, source) \ | ||
6695 | + do { \ | ||
6696 | + (destination) = *(source); \ | ||
6697 | + } while (0) | ||
6698 | +# else /* BYTE */ | ||
6699 | +# define EXTRACT_NUMBER(destination, source) \ | ||
6700 | + do { \ | ||
6701 | + (destination) = *(source) & 0377; \ | ||
6702 | + (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ | ||
6703 | + } while (0) | ||
6704 | +# endif | ||
6705 | + | ||
6706 | +# ifdef DEBUG | ||
6707 | +static void PREFIX(extract_number) (int *dest, UCHAR_T *source); | ||
6708 | +static void | ||
6709 | +PREFIX(extract_number) (int *dest, UCHAR_T *source) | ||
6710 | +{ | ||
6711 | +# ifdef WCHAR | ||
6712 | + *dest = *source; | ||
6713 | +# else /* BYTE */ | ||
6714 | + int temp = SIGN_EXTEND_CHAR (*(source + 1)); | ||
6715 | + *dest = *source & 0377; | ||
6716 | + *dest += temp << 8; | ||
6717 | +# endif | ||
6718 | +} | ||
6719 | + | ||
6720 | +# ifndef EXTRACT_MACROS /* To debug the macros. */ | ||
6721 | +# undef EXTRACT_NUMBER | ||
6722 | +# define EXTRACT_NUMBER(dest, src) PREFIX(extract_number) (&dest, src) | ||
6723 | +# endif /* not EXTRACT_MACROS */ | ||
6724 | + | ||
6725 | +# endif /* DEBUG */ | ||
6726 | + | ||
6727 | +/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. | ||
6728 | + SOURCE must be an lvalue. */ | ||
6729 | + | ||
6730 | +# define EXTRACT_NUMBER_AND_INCR(destination, source) \ | ||
6731 | + do { \ | ||
6732 | + EXTRACT_NUMBER (destination, source); \ | ||
6733 | + (source) += OFFSET_ADDRESS_SIZE; \ | ||
6734 | + } while (0) | ||
6735 | + | ||
6736 | +# ifdef DEBUG | ||
6737 | +static void PREFIX(extract_number_and_incr) (int *destination, | ||
6738 | + UCHAR_T **source); | ||
6739 | +static void | ||
6740 | +PREFIX(extract_number_and_incr) (int *destination, UCHAR_T **source) | ||
6741 | +{ | ||
6742 | + PREFIX(extract_number) (destination, *source); | ||
6743 | + *source += OFFSET_ADDRESS_SIZE; | ||
6744 | +} | ||
6745 | + | ||
6746 | +# ifndef EXTRACT_MACROS | ||
6747 | +# undef EXTRACT_NUMBER_AND_INCR | ||
6748 | +# define EXTRACT_NUMBER_AND_INCR(dest, src) \ | ||
6749 | + PREFIX(extract_number_and_incr) (&dest, &src) | ||
6750 | +# endif /* not EXTRACT_MACROS */ | ||
6751 | + | ||
6752 | +# endif /* DEBUG */ | ||
6753 | + | ||
6754 | + | ||
6755 | + | ||
6756 | +/* If DEBUG is defined, Regex prints many voluminous messages about what | ||
6757 | + it is doing (if the variable `debug' is nonzero). If linked with the | ||
6758 | + main program in `iregex.c', you can enter patterns and strings | ||
6759 | + interactively. And if linked with the main program in `main.c' and | ||
6760 | + the other test files, you can run the already-written tests. */ | ||
6761 | + | ||
6762 | +# ifdef DEBUG | ||
6763 | + | ||
6764 | +# ifndef DEFINED_ONCE | ||
6765 | + | ||
6766 | +/* We use standard I/O for debugging. */ | ||
6767 | +# include <stdio.h> | ||
6768 | + | ||
6769 | +/* It is useful to test things that ``must'' be true when debugging. */ | ||
6770 | +# include <assert.h> | ||
6771 | + | ||
6772 | +static int debug; | ||
6773 | + | ||
6774 | +# define DEBUG_STATEMENT(e) e | ||
6775 | +# define DEBUG_PRINT1(x) if (debug) printf (x) | ||
6776 | +# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) | ||
6777 | +# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) | ||
6778 | +# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) | ||
6779 | +# endif /* not DEFINED_ONCE */ | ||
6780 | + | ||
6781 | +# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ | ||
6782 | + if (debug) PREFIX(print_partial_compiled_pattern) (s, e) | ||
6783 | +# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ | ||
6784 | + if (debug) PREFIX(print_double_string) (w, s1, sz1, s2, sz2) | ||
6785 | + | ||
6786 | + | ||
6787 | +/* Print the fastmap in human-readable form. */ | ||
6788 | + | ||
6789 | +# ifndef DEFINED_ONCE | ||
6790 | +void | ||
6791 | +print_fastmap (char *fastmap) | ||
6792 | +{ | ||
6793 | + unsigned was_a_range = 0; | ||
6794 | + unsigned i = 0; | ||
6795 | + | ||
6796 | + while (i < (1 << BYTEWIDTH)) | ||
6797 | + { | ||
6798 | + if (fastmap[i++]) | ||
6799 | + { | ||
6800 | + was_a_range = 0; | ||
6801 | + putchar (i - 1); | ||
6802 | + while (i < (1 << BYTEWIDTH) && fastmap[i]) | ||
6803 | + { | ||
6804 | + was_a_range = 1; | ||
6805 | + i++; | ||
6806 | + } | ||
6807 | + if (was_a_range) | ||
6808 | + { | ||
6809 | + printf ("-"); | ||
6810 | + putchar (i - 1); | ||
6811 | + } | ||
6812 | + } | ||
6813 | + } | ||
6814 | + putchar ('\n'); | ||
6815 | +} | ||
6816 | +# endif /* not DEFINED_ONCE */ | ||
6817 | + | ||
6818 | + | ||
6819 | +/* Print a compiled pattern string in human-readable form, starting at | ||
6820 | + the START pointer into it and ending just before the pointer END. */ | ||
6821 | + | ||
6822 | +void | ||
6823 | +PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end) | ||
6824 | +{ | ||
6825 | + int mcnt, mcnt2; | ||
6826 | + UCHAR_T *p1; | ||
6827 | + UCHAR_T *p = start; | ||
6828 | + UCHAR_T *pend = end; | ||
6829 | + | ||
6830 | + if (start == NULL) | ||
6831 | + { | ||
6832 | + printf ("(null)\n"); | ||
6833 | + return; | ||
6834 | + } | ||
6835 | + | ||
6836 | + /* Loop over pattern commands. */ | ||
6837 | + while (p < pend) | ||
6838 | + { | ||
6839 | +# ifdef _LIBC | ||
6840 | + printf ("%td:\t", p - start); | ||
6841 | +# else | ||
6842 | + printf ("%ld:\t", (long int) (p - start)); | ||
6843 | +# endif | ||
6844 | + | ||
6845 | + switch ((re_opcode_t) *p++) | ||
6846 | + { | ||
6847 | + case no_op: | ||
6848 | + printf ("/no_op"); | ||
6849 | + break; | ||
6850 | + | ||
6851 | + case exactn: | ||
6852 | + mcnt = *p++; | ||
6853 | + printf ("/exactn/%d", mcnt); | ||
6854 | + do | ||
6855 | + { | ||
6856 | + putchar ('/'); | ||
6857 | + PUT_CHAR (*p++); | ||
6858 | + } | ||
6859 | + while (--mcnt); | ||
6860 | + break; | ||
6861 | + | ||
6862 | +# ifdef MBS_SUPPORT | ||
6863 | + case exactn_bin: | ||
6864 | + mcnt = *p++; | ||
6865 | + printf ("/exactn_bin/%d", mcnt); | ||
6866 | + do | ||
6867 | + { | ||
6868 | + printf("/%lx", (long int) *p++); | ||
6869 | + } | ||
6870 | + while (--mcnt); | ||
6871 | + break; | ||
6872 | +# endif /* MBS_SUPPORT */ | ||
6873 | + | ||
6874 | + case start_memory: | ||
6875 | + mcnt = *p++; | ||
6876 | + printf ("/start_memory/%d/%ld", mcnt, (long int) *p++); | ||
6877 | + break; | ||
6878 | + | ||
6879 | + case stop_memory: | ||
6880 | + mcnt = *p++; | ||
6881 | + printf ("/stop_memory/%d/%ld", mcnt, (long int) *p++); | ||
6882 | + break; | ||
6883 | + | ||
6884 | + case duplicate: | ||
6885 | + printf ("/duplicate/%ld", (long int) *p++); | ||
6886 | + break; | ||
6887 | + | ||
6888 | + case anychar: | ||
6889 | + printf ("/anychar"); | ||
6890 | + break; | ||
6891 | + | ||
6892 | + case charset: | ||
6893 | + case charset_not: | ||
6894 | + { | ||
6895 | +# ifdef WCHAR | ||
6896 | + int i, length; | ||
6897 | + wchar_t *workp = p; | ||
6898 | + printf ("/charset [%s", | ||
6899 | + (re_opcode_t) *(workp - 1) == charset_not ? "^" : ""); | ||
6900 | + p += 5; | ||
6901 | + length = *workp++; /* the length of char_classes */ | ||
6902 | + for (i=0 ; i<length ; i++) | ||
6903 | + printf("[:%lx:]", (long int) *p++); | ||
6904 | + length = *workp++; /* the length of collating_symbol */ | ||
6905 | + for (i=0 ; i<length ;) | ||
6906 | + { | ||
6907 | + printf("[."); | ||
6908 | + while(*p != 0) | ||
6909 | + PUT_CHAR((i++,*p++)); | ||
6910 | + i++,p++; | ||
6911 | + printf(".]"); | ||
6912 | + } | ||
6913 | + length = *workp++; /* the length of equivalence_class */ | ||
6914 | + for (i=0 ; i<length ;) | ||
6915 | + { | ||
6916 | + printf("[="); | ||
6917 | + while(*p != 0) | ||
6918 | + PUT_CHAR((i++,*p++)); | ||
6919 | + i++,p++; | ||
6920 | + printf("=]"); | ||
6921 | + } | ||
6922 | + length = *workp++; /* the length of char_range */ | ||
6923 | + for (i=0 ; i<length ; i++) | ||
6924 | + { | ||
6925 | + wchar_t range_start = *p++; | ||
6926 | + wchar_t range_end = *p++; | ||
6927 | + printf("%C-%C", range_start, range_end); | ||
6928 | + } | ||
6929 | + length = *workp++; /* the length of char */ | ||
6930 | + for (i=0 ; i<length ; i++) | ||
6931 | + printf("%C", *p++); | ||
6932 | + putchar (']'); | ||
6933 | +# else | ||
6934 | + register int c, last = -100; | ||
6935 | + register int in_range = 0; | ||
6936 | + | ||
6937 | + printf ("/charset [%s", | ||
6938 | + (re_opcode_t) *(p - 1) == charset_not ? "^" : ""); | ||
6939 | + | ||
6940 | + assert (p + *p < pend); | ||
6941 | + | ||
6942 | + for (c = 0; c < 256; c++) | ||
6943 | + if (c / 8 < *p | ||
6944 | + && (p[1 + (c/8)] & (1 << (c % 8)))) | ||
6945 | + { | ||
6946 | + /* Are we starting a range? */ | ||
6947 | + if (last + 1 == c && ! in_range) | ||
6948 | + { | ||
6949 | + putchar ('-'); | ||
6950 | + in_range = 1; | ||
6951 | + } | ||
6952 | + /* Have we broken a range? */ | ||
6953 | + else if (last + 1 != c && in_range) | ||
6954 | + { | ||
6955 | + putchar (last); | ||
6956 | + in_range = 0; | ||
6957 | + } | ||
6958 | + | ||
6959 | + if (! in_range) | ||
6960 | + putchar (c); | ||
6961 | + | ||
6962 | + last = c; | ||
6963 | + } | ||
6964 | + | ||
6965 | + if (in_range) | ||
6966 | + putchar (last); | ||
6967 | + | ||
6968 | + putchar (']'); | ||
6969 | + | ||
6970 | + p += 1 + *p; | ||
6971 | +# endif /* WCHAR */ | ||
6972 | + } | ||
6973 | + break; | ||
6974 | + | ||
6975 | + case begline: | ||
6976 | + printf ("/begline"); | ||
6977 | + break; | ||
6978 | + | ||
6979 | + case endline: | ||
6980 | + printf ("/endline"); | ||
6981 | + break; | ||
6982 | + | ||
6983 | + case on_failure_jump: | ||
6984 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
6985 | +# ifdef _LIBC | ||
6986 | + printf ("/on_failure_jump to %td", p + mcnt - start); | ||
6987 | +# else | ||
6988 | + printf ("/on_failure_jump to %ld", (long int) (p + mcnt - start)); | ||
6989 | +# endif | ||
6990 | + break; | ||
6991 | + | ||
6992 | + case on_failure_keep_string_jump: | ||
6993 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
6994 | +# ifdef _LIBC | ||
6995 | + printf ("/on_failure_keep_string_jump to %td", p + mcnt - start); | ||
6996 | +# else | ||
6997 | + printf ("/on_failure_keep_string_jump to %ld", | ||
6998 | + (long int) (p + mcnt - start)); | ||
6999 | +# endif | ||
7000 | + break; | ||
7001 | + | ||
7002 | + case dummy_failure_jump: | ||
7003 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
7004 | +# ifdef _LIBC | ||
7005 | + printf ("/dummy_failure_jump to %td", p + mcnt - start); | ||
7006 | +# else | ||
7007 | + printf ("/dummy_failure_jump to %ld", (long int) (p + mcnt - start)); | ||
7008 | +# endif | ||
7009 | + break; | ||
7010 | + | ||
7011 | + case push_dummy_failure: | ||
7012 | + printf ("/push_dummy_failure"); | ||
7013 | + break; | ||
7014 | + | ||
7015 | + case maybe_pop_jump: | ||
7016 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
7017 | +# ifdef _LIBC | ||
7018 | + printf ("/maybe_pop_jump to %td", p + mcnt - start); | ||
7019 | +# else | ||
7020 | + printf ("/maybe_pop_jump to %ld", (long int) (p + mcnt - start)); | ||
7021 | +# endif | ||
7022 | + break; | ||
7023 | + | ||
7024 | + case pop_failure_jump: | ||
7025 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
7026 | +# ifdef _LIBC | ||
7027 | + printf ("/pop_failure_jump to %td", p + mcnt - start); | ||
7028 | +# else | ||
7029 | + printf ("/pop_failure_jump to %ld", (long int) (p + mcnt - start)); | ||
7030 | +# endif | ||
7031 | + break; | ||
7032 | + | ||
7033 | + case jump_past_alt: | ||
7034 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
7035 | +# ifdef _LIBC | ||
7036 | + printf ("/jump_past_alt to %td", p + mcnt - start); | ||
7037 | +# else | ||
7038 | + printf ("/jump_past_alt to %ld", (long int) (p + mcnt - start)); | ||
7039 | +# endif | ||
7040 | + break; | ||
7041 | + | ||
7042 | + case jump: | ||
7043 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
7044 | +# ifdef _LIBC | ||
7045 | + printf ("/jump to %td", p + mcnt - start); | ||
7046 | +# else | ||
7047 | + printf ("/jump to %ld", (long int) (p + mcnt - start)); | ||
7048 | +# endif | ||
7049 | + break; | ||
7050 | + | ||
7051 | + case succeed_n: | ||
7052 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
7053 | + p1 = p + mcnt; | ||
7054 | + PREFIX(extract_number_and_incr) (&mcnt2, &p); | ||
7055 | +# ifdef _LIBC | ||
7056 | + printf ("/succeed_n to %td, %d times", p1 - start, mcnt2); | ||
7057 | +# else | ||
7058 | + printf ("/succeed_n to %ld, %d times", | ||
7059 | + (long int) (p1 - start), mcnt2); | ||
7060 | +# endif | ||
7061 | + break; | ||
7062 | + | ||
7063 | + case jump_n: | ||
7064 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
7065 | + p1 = p + mcnt; | ||
7066 | + PREFIX(extract_number_and_incr) (&mcnt2, &p); | ||
7067 | + printf ("/jump_n to %d, %d times", p1 - start, mcnt2); | ||
7068 | + break; | ||
7069 | + | ||
7070 | + case set_number_at: | ||
7071 | + PREFIX(extract_number_and_incr) (&mcnt, &p); | ||
7072 | + p1 = p + mcnt; | ||
7073 | + PREFIX(extract_number_and_incr) (&mcnt2, &p); | ||
7074 | +# ifdef _LIBC | ||
7075 | + printf ("/set_number_at location %td to %d", p1 - start, mcnt2); | ||
7076 | +# else | ||
7077 | + printf ("/set_number_at location %ld to %d", | ||
7078 | + (long int) (p1 - start), mcnt2); | ||
7079 | +# endif | ||
7080 | + break; | ||
7081 | + | ||
7082 | + case wordbound: | ||
7083 | + printf ("/wordbound"); | ||
7084 | + break; | ||
7085 | + | ||
7086 | + case notwordbound: | ||
7087 | + printf ("/notwordbound"); | ||
7088 | + break; | ||
7089 | + | ||
7090 | + case wordbeg: | ||
7091 | + printf ("/wordbeg"); | ||
7092 | + break; | ||
7093 | + | ||
7094 | + case wordend: | ||
7095 | + printf ("/wordend"); | ||
7096 | + break; | ||
7097 | + | ||
7098 | +# ifdef emacs | ||
7099 | + case before_dot: | ||
7100 | + printf ("/before_dot"); | ||
7101 | + break; | ||
7102 | + | ||
7103 | + case at_dot: | ||
7104 | + printf ("/at_dot"); | ||
7105 | + break; | ||
7106 | + | ||
7107 | + case after_dot: | ||
7108 | + printf ("/after_dot"); | ||
7109 | + break; | ||
7110 | + | ||
7111 | + case syntaxspec: | ||
7112 | + printf ("/syntaxspec"); | ||
7113 | + mcnt = *p++; | ||
7114 | + printf ("/%d", mcnt); | ||
7115 | + break; | ||
7116 | + | ||
7117 | + case notsyntaxspec: | ||
7118 | + printf ("/notsyntaxspec"); | ||
7119 | + mcnt = *p++; | ||
7120 | + printf ("/%d", mcnt); | ||
7121 | + break; | ||
7122 | +# endif /* emacs */ | ||
7123 | + | ||
7124 | + case wordchar: | ||
7125 | + printf ("/wordchar"); | ||
7126 | + break; | ||
7127 | + | ||
7128 | + case notwordchar: | ||
7129 | + printf ("/notwordchar"); | ||
7130 | + break; | ||
7131 | + | ||
7132 | + case begbuf: | ||
7133 | + printf ("/begbuf"); | ||
7134 | + break; | ||
7135 | + | ||
7136 | + case endbuf: | ||
7137 | + printf ("/endbuf"); | ||
7138 | + break; | ||
7139 | + | ||
7140 | + default: | ||
7141 | + printf ("?%ld", (long int) *(p-1)); | ||
7142 | + } | ||
7143 | + | ||
7144 | + putchar ('\n'); | ||
7145 | + } | ||
7146 | + | ||
7147 | +# ifdef _LIBC | ||
7148 | + printf ("%td:\tend of pattern.\n", p - start); | ||
7149 | +# else | ||
7150 | + printf ("%ld:\tend of pattern.\n", (long int) (p - start)); | ||
7151 | +# endif | ||
7152 | +} | ||
7153 | + | ||
7154 | + | ||
7155 | +void | ||
7156 | +PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp) | ||
7157 | +{ | ||
7158 | + UCHAR_T *buffer = (UCHAR_T*) bufp->buffer; | ||
7159 | + | ||
7160 | + PREFIX(print_partial_compiled_pattern) (buffer, buffer | ||
7161 | + + bufp->used / sizeof(UCHAR_T)); | ||
7162 | + printf ("%ld bytes used/%ld bytes allocated.\n", | ||
7163 | + bufp->used, bufp->allocated); | ||
7164 | + | ||
7165 | + if (bufp->fastmap_accurate && bufp->fastmap) | ||
7166 | + { | ||
7167 | + printf ("fastmap: "); | ||
7168 | + print_fastmap (bufp->fastmap); | ||
7169 | + } | ||
7170 | + | ||
7171 | +# ifdef _LIBC | ||
7172 | + printf ("re_nsub: %Zd\t", bufp->re_nsub); | ||
7173 | +# else | ||
7174 | + printf ("re_nsub: %ld\t", (long int) bufp->re_nsub); | ||
7175 | +# endif | ||
7176 | + printf ("regs_alloc: %d\t", bufp->regs_allocated); | ||
7177 | + printf ("can_be_null: %d\t", bufp->can_be_null); | ||
7178 | + printf ("newline_anchor: %d\n", bufp->newline_anchor); | ||
7179 | + printf ("no_sub: %d\t", bufp->no_sub); | ||
7180 | + printf ("not_bol: %d\t", bufp->not_bol); | ||
7181 | + printf ("not_eol: %d\t", bufp->not_eol); | ||
7182 | + printf ("syntax: %lx\n", bufp->syntax); | ||
7183 | + /* Perhaps we should print the translate table? */ | ||
7184 | +} | ||
7185 | + | ||
7186 | + | ||
7187 | +void | ||
7188 | +PREFIX(print_double_string) (const CHAR_T *where, const CHAR_T *string1, | ||
7189 | + int size1, const CHAR_T *string2, int size2) | ||
7190 | +{ | ||
7191 | + int this_char; | ||
7192 | + | ||
7193 | + if (where == NULL) | ||
7194 | + printf ("(null)"); | ||
7195 | + else | ||
7196 | + { | ||
7197 | + int cnt; | ||
7198 | + | ||
7199 | + if (FIRST_STRING_P (where)) | ||
7200 | + { | ||
7201 | + for (this_char = where - string1; this_char < size1; this_char++) | ||
7202 | + PUT_CHAR (string1[this_char]); | ||
7203 | + | ||
7204 | + where = string2; | ||
7205 | + } | ||
7206 | + | ||
7207 | + cnt = 0; | ||
7208 | + for (this_char = where - string2; this_char < size2; this_char++) | ||
7209 | + { | ||
7210 | + PUT_CHAR (string2[this_char]); | ||
7211 | + if (++cnt > 100) | ||
7212 | + { | ||
7213 | + fputs ("...", stdout); | ||
7214 | + break; | ||
7215 | + } | ||
7216 | + } | ||
7217 | + } | ||
7218 | +} | ||
7219 | + | ||
7220 | +# ifndef DEFINED_ONCE | ||
7221 | +void | ||
7222 | +printchar (int c) | ||
7223 | +{ | ||
7224 | + putc (c, stderr); | ||
7225 | +} | ||
7226 | +# endif | ||
7227 | + | ||
7228 | +# else /* not DEBUG */ | ||
7229 | + | ||
7230 | +# ifndef DEFINED_ONCE | ||
7231 | +# undef assert | ||
7232 | +# define assert(e) | ||
7233 | + | ||
7234 | +# define DEBUG_STATEMENT(e) | ||
7235 | +# define DEBUG_PRINT1(x) | ||
7236 | +# define DEBUG_PRINT2(x1, x2) | ||
7237 | +# define DEBUG_PRINT3(x1, x2, x3) | ||
7238 | +# define DEBUG_PRINT4(x1, x2, x3, x4) | ||
7239 | +# endif /* not DEFINED_ONCE */ | ||
7240 | +# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) | ||
7241 | +# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) | ||
7242 | + | ||
7243 | +# endif /* not DEBUG */ | ||
7244 | + | ||
7245 | + | ||
7246 | + | ||
7247 | +# ifdef WCHAR | ||
7248 | +/* This convert a multibyte string to a wide character string. | ||
7249 | + And write their correspondances to offset_buffer(see below) | ||
7250 | + and write whether each wchar_t is binary data to is_binary. | ||
7251 | + This assume invalid multibyte sequences as binary data. | ||
7252 | + We assume offset_buffer and is_binary is already allocated | ||
7253 | + enough space. */ | ||
7254 | + | ||
7255 | +static size_t convert_mbs_to_wcs (CHAR_T *dest, const unsigned char* src, | ||
7256 | + size_t len, int *offset_buffer, | ||
7257 | + char *is_binary); | ||
7258 | +static size_t | ||
7259 | +convert_mbs_to_wcs (CHAR_T *dest, const unsigned char*src, size_t len, | ||
7260 | + int *offset_buffer, char *is_binary) | ||
7261 | + /* It hold correspondances between src(char string) and | ||
7262 | + dest(wchar_t string) for optimization. | ||
7263 | + e.g. src = "xxxyzz" | ||
7264 | + dest = {'X', 'Y', 'Z'} | ||
7265 | + (each "xxx", "y" and "zz" represent one multibyte character | ||
7266 | + corresponding to 'X', 'Y' and 'Z'.) | ||
7267 | + offset_buffer = {0, 0+3("xxx"), 0+3+1("y"), 0+3+1+2("zz")} | ||
7268 | + = {0, 3, 4, 6} | ||
7269 | + */ | ||
7270 | +{ | ||
7271 | + wchar_t *pdest = dest; | ||
7272 | + const unsigned char *psrc = src; | ||
7273 | + size_t wc_count = 0; | ||
7274 | + | ||
7275 | + mbstate_t mbs; | ||
7276 | + int i, consumed; | ||
7277 | + size_t mb_remain = len; | ||
7278 | + size_t mb_count = 0; | ||
7279 | + | ||
7280 | + /* Initialize the conversion state. */ | ||
7281 | + memset (&mbs, 0, sizeof (mbstate_t)); | ||
7282 | + | ||
7283 | + offset_buffer[0] = 0; | ||
7284 | + for( ; mb_remain > 0 ; ++wc_count, ++pdest, mb_remain -= consumed, | ||
7285 | + psrc += consumed) | ||
7286 | + { | ||
7287 | +#ifdef _LIBC | ||
7288 | + consumed = __mbrtowc (pdest, psrc, mb_remain, &mbs); | ||
7289 | +#else | ||
7290 | + consumed = mbrtowc (pdest, psrc, mb_remain, &mbs); | ||
7291 | +#endif | ||
7292 | + | ||
7293 | + if (consumed <= 0) | ||
7294 | + /* failed to convert. maybe src contains binary data. | ||
7295 | + So we consume 1 byte manualy. */ | ||
7296 | + { | ||
7297 | + *pdest = *psrc; | ||
7298 | + consumed = 1; | ||
7299 | + is_binary[wc_count] = TRUE; | ||
7300 | + } | ||
7301 | + else | ||
7302 | + is_binary[wc_count] = FALSE; | ||
7303 | + /* In sjis encoding, we use yen sign as escape character in | ||
7304 | + place of reverse solidus. So we convert 0x5c(yen sign in | ||
7305 | + sjis) to not 0xa5(yen sign in UCS2) but 0x5c(reverse | ||
7306 | + solidus in UCS2). */ | ||
7307 | + if (consumed == 1 && (int) *psrc == 0x5c && (int) *pdest == 0xa5) | ||
7308 | + *pdest = (wchar_t) *psrc; | ||
7309 | + | ||
7310 | + offset_buffer[wc_count + 1] = mb_count += consumed; | ||
7311 | + } | ||
7312 | + | ||
7313 | + /* Fill remain of the buffer with sentinel. */ | ||
7314 | + for (i = wc_count + 1 ; i <= len ; i++) | ||
7315 | + offset_buffer[i] = mb_count + 1; | ||
7316 | + | ||
7317 | + return wc_count; | ||
7318 | +} | ||
7319 | + | ||
7320 | +# endif /* WCHAR */ | ||
7321 | + | ||
7322 | +#else /* not INSIDE_RECURSION */ | ||
7323 | + | ||
7324 | +/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can | ||
7325 | + also be assigned to arbitrarily: each pattern buffer stores its own | ||
7326 | + syntax, so it can be changed between regex compilations. */ | ||
7327 | +/* This has no initializer because initialized variables in Emacs | ||
7328 | + become read-only after dumping. */ | ||
7329 | +reg_syntax_t re_syntax_options; | ||
7330 | + | ||
7331 | + | ||
7332 | +/* Specify the precise syntax of regexps for compilation. This provides | ||
7333 | + for compatibility for various utilities which historically have | ||
7334 | + different, incompatible syntaxes. | ||
7335 | + | ||
7336 | + The argument SYNTAX is a bit mask comprised of the various bits | ||
7337 | + defined in regex.h. We return the old syntax. */ | ||
7338 | + | ||
7339 | +reg_syntax_t | ||
7340 | +re_set_syntax (reg_syntax_t syntax) | ||
7341 | +{ | ||
7342 | + reg_syntax_t ret = re_syntax_options; | ||
7343 | + | ||
7344 | + re_syntax_options = syntax; | ||
7345 | +# ifdef DEBUG | ||
7346 | + if (syntax & RE_DEBUG) | ||
7347 | + debug = 1; | ||
7348 | + else if (debug) /* was on but now is not */ | ||
7349 | + debug = 0; | ||
7350 | +# endif /* DEBUG */ | ||
7351 | + return ret; | ||
7352 | +} | ||
7353 | +# ifdef _LIBC | ||
7354 | +weak_alias (__re_set_syntax, re_set_syntax) | ||
7355 | +# endif | ||
7356 | + | ||
7357 | +/* This table gives an error message for each of the error codes listed | ||
7358 | + in regex.h. Obviously the order here has to be same as there. | ||
7359 | + POSIX doesn't require that we do anything for REG_NOERROR, | ||
7360 | + but why not be nice? */ | ||
7361 | + | ||
7362 | +static const char *re_error_msgid[] = | ||
7363 | + { | ||
7364 | + gettext_noop ("Success"), /* REG_NOERROR */ | ||
7365 | + gettext_noop ("No match"), /* REG_NOMATCH */ | ||
7366 | + gettext_noop ("Invalid regular expression"), /* REG_BADPAT */ | ||
7367 | + gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */ | ||
7368 | + gettext_noop ("Invalid character class name"), /* REG_ECTYPE */ | ||
7369 | + gettext_noop ("Trailing backslash"), /* REG_EESCAPE */ | ||
7370 | + gettext_noop ("Invalid back reference"), /* REG_ESUBREG */ | ||
7371 | + gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */ | ||
7372 | + gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */ | ||
7373 | + gettext_noop ("Unmatched \\{"), /* REG_EBRACE */ | ||
7374 | + gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */ | ||
7375 | + gettext_noop ("Invalid range end"), /* REG_ERANGE */ | ||
7376 | + gettext_noop ("Memory exhausted"), /* REG_ESPACE */ | ||
7377 | + gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */ | ||
7378 | + gettext_noop ("Premature end of regular expression"), /* REG_EEND */ | ||
7379 | + gettext_noop ("Regular expression too big"), /* REG_ESIZE */ | ||
7380 | + gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */ | ||
7381 | + }; | ||
7382 | + | ||
7383 | +#endif /* INSIDE_RECURSION */ | ||
7384 | + | ||
7385 | +#ifndef DEFINED_ONCE | ||
7386 | +/* Avoiding alloca during matching, to placate r_alloc. */ | ||
7387 | + | ||
7388 | +/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the | ||
7389 | + searching and matching functions should not call alloca. On some | ||
7390 | + systems, alloca is implemented in terms of malloc, and if we're | ||
7391 | + using the relocating allocator routines, then malloc could cause a | ||
7392 | + relocation, which might (if the strings being searched are in the | ||
7393 | + ralloc heap) shift the data out from underneath the regexp | ||
7394 | + routines. | ||
7395 | + | ||
7396 | + Here's another reason to avoid allocation: Emacs | ||
7397 | + processes input from X in a signal handler; processing X input may | ||
7398 | + call malloc; if input arrives while a matching routine is calling | ||
7399 | + malloc, then we're scrod. But Emacs can't just block input while | ||
7400 | + calling matching routines; then we don't notice interrupts when | ||
7401 | + they come in. So, Emacs blocks input around all regexp calls | ||
7402 | + except the matching calls, which it leaves unprotected, in the | ||
7403 | + faith that they will not malloc. */ | ||
7404 | + | ||
7405 | +/* Normally, this is fine. */ | ||
7406 | +# define MATCH_MAY_ALLOCATE | ||
7407 | + | ||
7408 | +/* When using GNU C, we are not REALLY using the C alloca, no matter | ||
7409 | + what config.h may say. So don't take precautions for it. */ | ||
7410 | +# ifdef __GNUC__ | ||
7411 | +# undef C_ALLOCA | ||
7412 | +# endif | ||
7413 | + | ||
7414 | +/* The match routines may not allocate if (1) they would do it with malloc | ||
7415 | + and (2) it's not safe for them to use malloc. | ||
7416 | + Note that if REL_ALLOC is defined, matching would not use malloc for the | ||
7417 | + failure stack, but we would still use it for the register vectors; | ||
7418 | + so REL_ALLOC should not affect this. */ | ||
7419 | +# if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs | ||
7420 | +# undef MATCH_MAY_ALLOCATE | ||
7421 | +# endif | ||
7422 | +#endif /* not DEFINED_ONCE */ | ||
7423 | + | ||
7424 | +#ifdef INSIDE_RECURSION | ||
7425 | +/* Failure stack declarations and macros; both re_compile_fastmap and | ||
7426 | + re_match_2 use a failure stack. These have to be macros because of | ||
7427 | + REGEX_ALLOCATE_STACK. */ | ||
7428 | + | ||
7429 | + | ||
7430 | +/* Number of failure points for which to initially allocate space | ||
7431 | + when matching. If this number is exceeded, we allocate more | ||
7432 | + space, so it is not a hard limit. */ | ||
7433 | +# ifndef INIT_FAILURE_ALLOC | ||
7434 | +# define INIT_FAILURE_ALLOC 5 | ||
7435 | +# endif | ||
7436 | + | ||
7437 | +/* Roughly the maximum number of failure points on the stack. Would be | ||
7438 | + exactly that if always used MAX_FAILURE_ITEMS items each time we failed. | ||
7439 | + This is a variable only so users of regex can assign to it; we never | ||
7440 | + change it ourselves. */ | ||
7441 | + | ||
7442 | + | ||
7443 | +# ifndef DEFINED_ONCE | ||
7444 | + | ||
7445 | +# ifdef INT_IS_16BIT | ||
7446 | +# define RE_M_F_TYPE long int | ||
7447 | +# else | ||
7448 | +# define RE_M_F_TYPE int | ||
7449 | +# endif /* INT_IS_16BIT */ | ||
7450 | + | ||
7451 | +# ifdef MATCH_MAY_ALLOCATE | ||
7452 | +/* 4400 was enough to cause a crash on Alpha OSF/1, | ||
7453 | + whose default stack limit is 2mb. */ | ||
7454 | +# define RE_M_F_DEFAULT 4000 | ||
7455 | +# else | ||
7456 | +# define RE_M_F_DEFAULT 2000 | ||
7457 | +# endif /* MATCH_MAY_ALLOCATE */ | ||
7458 | + | ||
7459 | +# include <shlib-compat.h> | ||
7460 | + | ||
7461 | +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) | ||
7462 | +link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.") | ||
7463 | +RE_M_F_TYPE re_max_failures = RE_M_F_DEFAULT; | ||
7464 | +# else | ||
7465 | +RE_M_F_TYPE re_max_failures attribute_hidden = RE_M_F_DEFAULT; | ||
7466 | +# endif /* SHLIB_COMPAT */ | ||
7467 | + | ||
7468 | +# undef RE_M_F_TYPE | ||
7469 | +# undef RE_M_F_DEFAULT | ||
7470 | + | ||
7471 | +# endif /* DEFINED_ONCE */ | ||
7472 | + | ||
7473 | +# ifdef INT_IS_16BIT | ||
7474 | + | ||
7475 | +union PREFIX(fail_stack_elt) | ||
7476 | +{ | ||
7477 | + UCHAR_T *pointer; | ||
7478 | + long int integer; | ||
7479 | +}; | ||
7480 | + | ||
7481 | +typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t); | ||
7482 | + | ||
7483 | +typedef struct | ||
7484 | +{ | ||
7485 | + PREFIX(fail_stack_elt_t) *stack; | ||
7486 | + unsigned long int size; | ||
7487 | + unsigned long int avail; /* Offset of next open position. */ | ||
7488 | +} PREFIX(fail_stack_type); | ||
7489 | + | ||
7490 | +# else /* not INT_IS_16BIT */ | ||
7491 | + | ||
7492 | +union PREFIX(fail_stack_elt) | ||
7493 | +{ | ||
7494 | + UCHAR_T *pointer; | ||
7495 | + int integer; | ||
7496 | +}; | ||
7497 | + | ||
7498 | +typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t); | ||
7499 | + | ||
7500 | +typedef struct | ||
7501 | +{ | ||
7502 | + PREFIX(fail_stack_elt_t) *stack; | ||
7503 | + unsigned size; | ||
7504 | + unsigned avail; /* Offset of next open position. */ | ||
7505 | +} PREFIX(fail_stack_type); | ||
7506 | + | ||
7507 | +# endif /* INT_IS_16BIT */ | ||
7508 | + | ||
7509 | +# ifndef DEFINED_ONCE | ||
7510 | +# define FAIL_STACK_EMPTY() (fail_stack.avail == 0) | ||
7511 | +# define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) | ||
7512 | +# define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) | ||
7513 | +# endif | ||
7514 | + | ||
7515 | + | ||
7516 | +/* Define macros to initialize and free the failure stack. | ||
7517 | + Do `return -2' if the alloc fails. */ | ||
7518 | + | ||
7519 | +# ifdef MATCH_MAY_ALLOCATE | ||
7520 | +# define INIT_FAIL_STACK() \ | ||
7521 | + do { \ | ||
7522 | + fail_stack.stack = (PREFIX(fail_stack_elt_t) *) \ | ||
7523 | + REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (PREFIX(fail_stack_elt_t))); \ | ||
7524 | + \ | ||
7525 | + if (fail_stack.stack == NULL) \ | ||
7526 | + return -2; \ | ||
7527 | + \ | ||
7528 | + fail_stack.size = INIT_FAILURE_ALLOC; \ | ||
7529 | + fail_stack.avail = 0; \ | ||
7530 | + } while (0) | ||
7531 | + | ||
7532 | +# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack) | ||
7533 | +# else | ||
7534 | +# define INIT_FAIL_STACK() \ | ||
7535 | + do { \ | ||
7536 | + fail_stack.avail = 0; \ | ||
7537 | + } while (0) | ||
7538 | + | ||
7539 | +# define RESET_FAIL_STACK() | ||
7540 | +# endif | ||
7541 | + | ||
7542 | + | ||
7543 | +/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items. | ||
7544 | + | ||
7545 | + Return 1 if succeeds, and 0 if either ran out of memory | ||
7546 | + allocating space for it or it was already too large. | ||
7547 | + | ||
7548 | + REGEX_REALLOCATE_STACK requires `destination' be declared. */ | ||
7549 | + | ||
7550 | +# define DOUBLE_FAIL_STACK(fail_stack) \ | ||
7551 | + ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \ | ||
7552 | + ? 0 \ | ||
7553 | + : ((fail_stack).stack = (PREFIX(fail_stack_elt_t) *) \ | ||
7554 | + REGEX_REALLOCATE_STACK ((fail_stack).stack, \ | ||
7555 | + (fail_stack).size * sizeof (PREFIX(fail_stack_elt_t)), \ | ||
7556 | + ((fail_stack).size << 1) * sizeof (PREFIX(fail_stack_elt_t))),\ | ||
7557 | + \ | ||
7558 | + (fail_stack).stack == NULL \ | ||
7559 | + ? 0 \ | ||
7560 | + : ((fail_stack).size <<= 1, \ | ||
7561 | + 1))) | ||
7562 | + | ||
7563 | + | ||
7564 | +/* Push pointer POINTER on FAIL_STACK. | ||
7565 | + Return 1 if was able to do so and 0 if ran out of memory allocating | ||
7566 | + space to do so. */ | ||
7567 | +# define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \ | ||
7568 | + ((FAIL_STACK_FULL () \ | ||
7569 | + && !DOUBLE_FAIL_STACK (FAIL_STACK)) \ | ||
7570 | + ? 0 \ | ||
7571 | + : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \ | ||
7572 | + 1)) | ||
7573 | + | ||
7574 | +/* Push a pointer value onto the failure stack. | ||
7575 | + Assumes the variable `fail_stack'. Probably should only | ||
7576 | + be called from within `PUSH_FAILURE_POINT'. */ | ||
7577 | +# define PUSH_FAILURE_POINTER(item) \ | ||
7578 | + fail_stack.stack[fail_stack.avail++].pointer = (UCHAR_T *) (item) | ||
7579 | + | ||
7580 | +/* This pushes an integer-valued item onto the failure stack. | ||
7581 | + Assumes the variable `fail_stack'. Probably should only | ||
7582 | + be called from within `PUSH_FAILURE_POINT'. */ | ||
7583 | +# define PUSH_FAILURE_INT(item) \ | ||
7584 | + fail_stack.stack[fail_stack.avail++].integer = (item) | ||
7585 | + | ||
7586 | +/* Push a fail_stack_elt_t value onto the failure stack. | ||
7587 | + Assumes the variable `fail_stack'. Probably should only | ||
7588 | + be called from within `PUSH_FAILURE_POINT'. */ | ||
7589 | +# define PUSH_FAILURE_ELT(item) \ | ||
7590 | + fail_stack.stack[fail_stack.avail++] = (item) | ||
7591 | + | ||
7592 | +/* These three POP... operations complement the three PUSH... operations. | ||
7593 | + All assume that `fail_stack' is nonempty. */ | ||
7594 | +# define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer | ||
7595 | +# define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer | ||
7596 | +# define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail] | ||
7597 | + | ||
7598 | +/* Used to omit pushing failure point id's when we're not debugging. */ | ||
7599 | +# ifdef DEBUG | ||
7600 | +# define DEBUG_PUSH PUSH_FAILURE_INT | ||
7601 | +# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT () | ||
7602 | +# else | ||
7603 | +# define DEBUG_PUSH(item) | ||
7604 | +# define DEBUG_POP(item_addr) | ||
7605 | +# endif | ||
7606 | + | ||
7607 | + | ||
7608 | +/* Push the information about the state we will need | ||
7609 | + if we ever fail back to it. | ||
7610 | + | ||
7611 | + Requires variables fail_stack, regstart, regend, reg_info, and | ||
7612 | + num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination' | ||
7613 | + be declared. | ||
7614 | + | ||
7615 | + Does `return FAILURE_CODE' if runs out of memory. */ | ||
7616 | + | ||
7617 | +# define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ | ||
7618 | + do { \ | ||
7619 | + char *destination; \ | ||
7620 | + /* Must be int, so when we don't save any registers, the arithmetic \ | ||
7621 | + of 0 + -1 isn't done as unsigned. */ \ | ||
7622 | + /* Can't be int, since there is not a shred of a guarantee that int \ | ||
7623 | + is wide enough to hold a value of something to which pointer can \ | ||
7624 | + be assigned */ \ | ||
7625 | + active_reg_t this_reg; \ | ||
7626 | + \ | ||
7627 | + DEBUG_STATEMENT (failure_id++); \ | ||
7628 | + DEBUG_STATEMENT (nfailure_points_pushed++); \ | ||
7629 | + DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ | ||
7630 | + DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ | ||
7631 | + DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ | ||
7632 | + \ | ||
7633 | + DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \ | ||
7634 | + DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ | ||
7635 | + \ | ||
7636 | + /* Ensure we have enough space allocated for what we will push. */ \ | ||
7637 | + while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ | ||
7638 | + { \ | ||
7639 | + if (!DOUBLE_FAIL_STACK (fail_stack)) \ | ||
7640 | + return failure_code; \ | ||
7641 | + \ | ||
7642 | + DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ | ||
7643 | + (fail_stack).size); \ | ||
7644 | + DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ | ||
7645 | + } \ | ||
7646 | + \ | ||
7647 | + /* Push the info, starting with the registers. */ \ | ||
7648 | + DEBUG_PRINT1 ("\n"); \ | ||
7649 | + \ | ||
7650 | + if (1) \ | ||
7651 | + for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ | ||
7652 | + this_reg++) \ | ||
7653 | + { \ | ||
7654 | + DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \ | ||
7655 | + DEBUG_STATEMENT (num_regs_pushed++); \ | ||
7656 | + \ | ||
7657 | + DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ | ||
7658 | + PUSH_FAILURE_POINTER (regstart[this_reg]); \ | ||
7659 | + \ | ||
7660 | + DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ | ||
7661 | + PUSH_FAILURE_POINTER (regend[this_reg]); \ | ||
7662 | + \ | ||
7663 | + DEBUG_PRINT2 (" info: %p\n ", \ | ||
7664 | + reg_info[this_reg].word.pointer); \ | ||
7665 | + DEBUG_PRINT2 (" match_null=%d", \ | ||
7666 | + REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ | ||
7667 | + DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ | ||
7668 | + DEBUG_PRINT2 (" matched_something=%d", \ | ||
7669 | + MATCHED_SOMETHING (reg_info[this_reg])); \ | ||
7670 | + DEBUG_PRINT2 (" ever_matched=%d", \ | ||
7671 | + EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ | ||
7672 | + DEBUG_PRINT1 ("\n"); \ | ||
7673 | + PUSH_FAILURE_ELT (reg_info[this_reg].word); \ | ||
7674 | + } \ | ||
7675 | + \ | ||
7676 | + DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\ | ||
7677 | + PUSH_FAILURE_INT (lowest_active_reg); \ | ||
7678 | + \ | ||
7679 | + DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\ | ||
7680 | + PUSH_FAILURE_INT (highest_active_reg); \ | ||
7681 | + \ | ||
7682 | + DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \ | ||
7683 | + DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ | ||
7684 | + PUSH_FAILURE_POINTER (pattern_place); \ | ||
7685 | + \ | ||
7686 | + DEBUG_PRINT2 (" Pushing string %p: `", string_place); \ | ||
7687 | + DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ | ||
7688 | + size2); \ | ||
7689 | + DEBUG_PRINT1 ("'\n"); \ | ||
7690 | + PUSH_FAILURE_POINTER (string_place); \ | ||
7691 | + \ | ||
7692 | + DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ | ||
7693 | + DEBUG_PUSH (failure_id); \ | ||
7694 | + } while (0) | ||
7695 | + | ||
7696 | +# ifndef DEFINED_ONCE | ||
7697 | +/* This is the number of items that are pushed and popped on the stack | ||
7698 | + for each register. */ | ||
7699 | +# define NUM_REG_ITEMS 3 | ||
7700 | + | ||
7701 | +/* Individual items aside from the registers. */ | ||
7702 | +# ifdef DEBUG | ||
7703 | +# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ | ||
7704 | +# else | ||
7705 | +# define NUM_NONREG_ITEMS 4 | ||
7706 | +# endif | ||
7707 | + | ||
7708 | +/* We push at most this many items on the stack. */ | ||
7709 | +/* We used to use (num_regs - 1), which is the number of registers | ||
7710 | + this regexp will save; but that was changed to 5 | ||
7711 | + to avoid stack overflow for a regexp with lots of parens. */ | ||
7712 | +# define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS) | ||
7713 | + | ||
7714 | +/* We actually push this many items. */ | ||
7715 | +# define NUM_FAILURE_ITEMS \ | ||
7716 | + (((0 \ | ||
7717 | + ? 0 : highest_active_reg - lowest_active_reg + 1) \ | ||
7718 | + * NUM_REG_ITEMS) \ | ||
7719 | + + NUM_NONREG_ITEMS) | ||
7720 | + | ||
7721 | +/* How many items can still be added to the stack without overflowing it. */ | ||
7722 | +# define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) | ||
7723 | +# endif /* not DEFINED_ONCE */ | ||
7724 | + | ||
7725 | + | ||
7726 | +/* Pops what PUSH_FAIL_STACK pushes. | ||
7727 | + | ||
7728 | + We restore into the parameters, all of which should be lvalues: | ||
7729 | + STR -- the saved data position. | ||
7730 | + PAT -- the saved pattern position. | ||
7731 | + LOW_REG, HIGH_REG -- the highest and lowest active registers. | ||
7732 | + REGSTART, REGEND -- arrays of string positions. | ||
7733 | + REG_INFO -- array of information about each subexpression. | ||
7734 | + | ||
7735 | + Also assumes the variables `fail_stack' and (if debugging), `bufp', | ||
7736 | + `pend', `string1', `size1', `string2', and `size2'. */ | ||
7737 | +# define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ | ||
7738 | +{ \ | ||
7739 | + DEBUG_STATEMENT (unsigned failure_id;) \ | ||
7740 | + active_reg_t this_reg; \ | ||
7741 | + const UCHAR_T *string_temp; \ | ||
7742 | + \ | ||
7743 | + assert (!FAIL_STACK_EMPTY ()); \ | ||
7744 | + \ | ||
7745 | + /* Remove failure points and point to how many regs pushed. */ \ | ||
7746 | + DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ | ||
7747 | + DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ | ||
7748 | + DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ | ||
7749 | + \ | ||
7750 | + assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ | ||
7751 | + \ | ||
7752 | + DEBUG_POP (&failure_id); \ | ||
7753 | + DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ | ||
7754 | + \ | ||
7755 | + /* If the saved string location is NULL, it came from an \ | ||
7756 | + on_failure_keep_string_jump opcode, and we want to throw away the \ | ||
7757 | + saved NULL, thus retaining our current position in the string. */ \ | ||
7758 | + string_temp = POP_FAILURE_POINTER (); \ | ||
7759 | + if (string_temp != NULL) \ | ||
7760 | + str = (const CHAR_T *) string_temp; \ | ||
7761 | + \ | ||
7762 | + DEBUG_PRINT2 (" Popping string %p: `", str); \ | ||
7763 | + DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ | ||
7764 | + DEBUG_PRINT1 ("'\n"); \ | ||
7765 | + \ | ||
7766 | + pat = (UCHAR_T *) POP_FAILURE_POINTER (); \ | ||
7767 | + DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \ | ||
7768 | + DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ | ||
7769 | + \ | ||
7770 | + /* Restore register info. */ \ | ||
7771 | + high_reg = (active_reg_t) POP_FAILURE_INT (); \ | ||
7772 | + DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \ | ||
7773 | + \ | ||
7774 | + low_reg = (active_reg_t) POP_FAILURE_INT (); \ | ||
7775 | + DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \ | ||
7776 | + \ | ||
7777 | + if (1) \ | ||
7778 | + for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ | ||
7779 | + { \ | ||
7780 | + DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \ | ||
7781 | + \ | ||
7782 | + reg_info[this_reg].word = POP_FAILURE_ELT (); \ | ||
7783 | + DEBUG_PRINT2 (" info: %p\n", \ | ||
7784 | + reg_info[this_reg].word.pointer); \ | ||
7785 | + \ | ||
7786 | + regend[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER (); \ | ||
7787 | + DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ | ||
7788 | + \ | ||
7789 | + regstart[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER (); \ | ||
7790 | + DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ | ||
7791 | + } \ | ||
7792 | + else \ | ||
7793 | + { \ | ||
7794 | + for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \ | ||
7795 | + { \ | ||
7796 | + reg_info[this_reg].word.integer = 0; \ | ||
7797 | + regend[this_reg] = 0; \ | ||
7798 | + regstart[this_reg] = 0; \ | ||
7799 | + } \ | ||
7800 | + highest_active_reg = high_reg; \ | ||
7801 | + } \ | ||
7802 | + \ | ||
7803 | + set_regs_matched_done = 0; \ | ||
7804 | + DEBUG_STATEMENT (nfailure_points_popped++); \ | ||
7805 | +} /* POP_FAILURE_POINT */ | ||
7806 | + | ||
7807 | +/* Structure for per-register (a.k.a. per-group) information. | ||
7808 | + Other register information, such as the | ||
7809 | + starting and ending positions (which are addresses), and the list of | ||
7810 | + inner groups (which is a bits list) are maintained in separate | ||
7811 | + variables. | ||
7812 | + | ||
7813 | + We are making a (strictly speaking) nonportable assumption here: that | ||
7814 | + the compiler will pack our bit fields into something that fits into | ||
7815 | + the type of `word', i.e., is something that fits into one item on the | ||
7816 | + failure stack. */ | ||
7817 | + | ||
7818 | + | ||
7819 | +/* Declarations and macros for re_match_2. */ | ||
7820 | + | ||
7821 | +typedef union | ||
7822 | +{ | ||
7823 | + PREFIX(fail_stack_elt_t) word; | ||
7824 | + struct | ||
7825 | + { | ||
7826 | + /* This field is one if this group can match the empty string, | ||
7827 | + zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ | ||
7828 | +# define MATCH_NULL_UNSET_VALUE 3 | ||
7829 | + unsigned match_null_string_p : 2; | ||
7830 | + unsigned is_active : 1; | ||
7831 | + unsigned matched_something : 1; | ||
7832 | + unsigned ever_matched_something : 1; | ||
7833 | + } bits; | ||
7834 | +} PREFIX(register_info_type); | ||
7835 | + | ||
7836 | +# ifndef DEFINED_ONCE | ||
7837 | +# define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) | ||
7838 | +# define IS_ACTIVE(R) ((R).bits.is_active) | ||
7839 | +# define MATCHED_SOMETHING(R) ((R).bits.matched_something) | ||
7840 | +# define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) | ||
7841 | + | ||
7842 | + | ||
7843 | +/* Call this when have matched a real character; it sets `matched' flags | ||
7844 | + for the subexpressions which we are currently inside. Also records | ||
7845 | + that those subexprs have matched. */ | ||
7846 | +# define SET_REGS_MATCHED() \ | ||
7847 | + do \ | ||
7848 | + { \ | ||
7849 | + if (!set_regs_matched_done) \ | ||
7850 | + { \ | ||
7851 | + active_reg_t r; \ | ||
7852 | + set_regs_matched_done = 1; \ | ||
7853 | + for (r = lowest_active_reg; r <= highest_active_reg; r++) \ | ||
7854 | + { \ | ||
7855 | + MATCHED_SOMETHING (reg_info[r]) \ | ||
7856 | + = EVER_MATCHED_SOMETHING (reg_info[r]) \ | ||
7857 | + = 1; \ | ||
7858 | + } \ | ||
7859 | + } \ | ||
7860 | + } \ | ||
7861 | + while (0) | ||
7862 | +# endif /* not DEFINED_ONCE */ | ||
7863 | + | ||
7864 | +/* Registers are set to a sentinel when they haven't yet matched. */ | ||
7865 | +static CHAR_T PREFIX(reg_unset_dummy); | ||
7866 | +# define REG_UNSET_VALUE (&PREFIX(reg_unset_dummy)) | ||
7867 | +# define REG_UNSET(e) ((e) == REG_UNSET_VALUE) | ||
7868 | + | ||
7869 | +/* Subroutine declarations and macros for regex_compile. */ | ||
7870 | +static void PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg); | ||
7871 | +static void PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, | ||
7872 | + int arg1, int arg2); | ||
7873 | +static void PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, | ||
7874 | + int arg, UCHAR_T *end); | ||
7875 | +static void PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, | ||
7876 | + int arg1, int arg2, UCHAR_T *end); | ||
7877 | +static boolean PREFIX(at_begline_loc_p) (const CHAR_T *pattern, | ||
7878 | + const CHAR_T *p, | ||
7879 | + reg_syntax_t syntax); | ||
7880 | +static boolean PREFIX(at_endline_loc_p) (const CHAR_T *p, | ||
7881 | + const CHAR_T *pend, | ||
7882 | + reg_syntax_t syntax); | ||
7883 | +# ifdef WCHAR | ||
7884 | +static reg_errcode_t wcs_compile_range (CHAR_T range_start, | ||
7885 | + const CHAR_T **p_ptr, | ||
7886 | + const CHAR_T *pend, | ||
7887 | + char *translate, | ||
7888 | + reg_syntax_t syntax, | ||
7889 | + UCHAR_T *b, | ||
7890 | + CHAR_T *char_set); | ||
7891 | +static void insert_space (int num, CHAR_T *loc, CHAR_T *end); | ||
7892 | +# else /* BYTE */ | ||
7893 | +static reg_errcode_t byte_compile_range (unsigned int range_start, | ||
7894 | + const char **p_ptr, | ||
7895 | + const char *pend, | ||
7896 | + RE_TRANSLATE_TYPE translate, | ||
7897 | + reg_syntax_t syntax, | ||
7898 | + unsigned char *b); | ||
7899 | +# endif /* WCHAR */ | ||
7900 | + | ||
7901 | +/* Fetch the next character in the uncompiled pattern---translating it | ||
7902 | + if necessary. Also cast from a signed character in the constant | ||
7903 | + string passed to us by the user to an unsigned char that we can use | ||
7904 | + as an array index (in, e.g., `translate'). */ | ||
7905 | +/* ifdef MBS_SUPPORT, we translate only if character <= 0xff, | ||
7906 | + because it is impossible to allocate 4GB array for some encodings | ||
7907 | + which have 4 byte character_set like UCS4. */ | ||
7908 | +# ifndef PATFETCH | ||
7909 | +# ifdef WCHAR | ||
7910 | +# define PATFETCH(c) \ | ||
7911 | + do {if (p == pend) return REG_EEND; \ | ||
7912 | + c = (UCHAR_T) *p++; \ | ||
7913 | + if (translate && (c <= 0xff)) c = (UCHAR_T) translate[c]; \ | ||
7914 | + } while (0) | ||
7915 | +# else /* BYTE */ | ||
7916 | +# define PATFETCH(c) \ | ||
7917 | + do {if (p == pend) return REG_EEND; \ | ||
7918 | + c = (unsigned char) *p++; \ | ||
7919 | + if (translate) c = (unsigned char) translate[c]; \ | ||
7920 | + } while (0) | ||
7921 | +# endif /* WCHAR */ | ||
7922 | +# endif | ||
7923 | + | ||
7924 | +/* Fetch the next character in the uncompiled pattern, with no | ||
7925 | + translation. */ | ||
7926 | +# define PATFETCH_RAW(c) \ | ||
7927 | + do {if (p == pend) return REG_EEND; \ | ||
7928 | + c = (UCHAR_T) *p++; \ | ||
7929 | + } while (0) | ||
7930 | + | ||
7931 | +/* Go backwards one character in the pattern. */ | ||
7932 | +# define PATUNFETCH p-- | ||
7933 | + | ||
7934 | + | ||
7935 | +/* If `translate' is non-null, return translate[D], else just D. We | ||
7936 | + cast the subscript to translate because some data is declared as | ||
7937 | + `char *', to avoid warnings when a string constant is passed. But | ||
7938 | + when we use a character as a subscript we must make it unsigned. */ | ||
7939 | +/* ifdef MBS_SUPPORT, we translate only if character <= 0xff, | ||
7940 | + because it is impossible to allocate 4GB array for some encodings | ||
7941 | + which have 4 byte character_set like UCS4. */ | ||
7942 | + | ||
7943 | +# ifndef TRANSLATE | ||
7944 | +# ifdef WCHAR | ||
7945 | +# define TRANSLATE(d) \ | ||
7946 | + ((translate && ((UCHAR_T) (d)) <= 0xff) \ | ||
7947 | + ? (char) translate[(unsigned char) (d)] : (d)) | ||
7948 | +# else /* BYTE */ | ||
7949 | +# define TRANSLATE(d) \ | ||
7950 | + (translate ? (char) translate[(unsigned char) (d)] : (char) (d)) | ||
7951 | +# endif /* WCHAR */ | ||
7952 | +# endif | ||
7953 | + | ||
7954 | + | ||
7955 | +/* Macros for outputting the compiled pattern into `buffer'. */ | ||
7956 | + | ||
7957 | +/* If the buffer isn't allocated when it comes in, use this. */ | ||
7958 | +# define INIT_BUF_SIZE (32 * sizeof(UCHAR_T)) | ||
7959 | + | ||
7960 | +/* Make sure we have at least N more bytes of space in buffer. */ | ||
7961 | +# ifdef WCHAR | ||
7962 | +# define GET_BUFFER_SPACE(n) \ | ||
7963 | + while (((unsigned long)b - (unsigned long)COMPILED_BUFFER_VAR \ | ||
7964 | + + (n)*sizeof(CHAR_T)) > bufp->allocated) \ | ||
7965 | + EXTEND_BUFFER () | ||
7966 | +# else /* BYTE */ | ||
7967 | +# define GET_BUFFER_SPACE(n) \ | ||
7968 | + while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \ | ||
7969 | + EXTEND_BUFFER () | ||
7970 | +# endif /* WCHAR */ | ||
7971 | + | ||
7972 | +/* Make sure we have one more byte of buffer space and then add C to it. */ | ||
7973 | +# define BUF_PUSH(c) \ | ||
7974 | + do { \ | ||
7975 | + GET_BUFFER_SPACE (1); \ | ||
7976 | + *b++ = (UCHAR_T) (c); \ | ||
7977 | + } while (0) | ||
7978 | + | ||
7979 | + | ||
7980 | +/* Ensure we have two more bytes of buffer space and then append C1 and C2. */ | ||
7981 | +# define BUF_PUSH_2(c1, c2) \ | ||
7982 | + do { \ | ||
7983 | + GET_BUFFER_SPACE (2); \ | ||
7984 | + *b++ = (UCHAR_T) (c1); \ | ||
7985 | + *b++ = (UCHAR_T) (c2); \ | ||
7986 | + } while (0) | ||
7987 | + | ||
7988 | + | ||
7989 | +/* As with BUF_PUSH_2, except for three bytes. */ | ||
7990 | +# define BUF_PUSH_3(c1, c2, c3) \ | ||
7991 | + do { \ | ||
7992 | + GET_BUFFER_SPACE (3); \ | ||
7993 | + *b++ = (UCHAR_T) (c1); \ | ||
7994 | + *b++ = (UCHAR_T) (c2); \ | ||
7995 | + *b++ = (UCHAR_T) (c3); \ | ||
7996 | + } while (0) | ||
7997 | + | ||
7998 | +/* Store a jump with opcode OP at LOC to location TO. We store a | ||
7999 | + relative address offset by the three bytes the jump itself occupies. */ | ||
8000 | +# define STORE_JUMP(op, loc, to) \ | ||
8001 | + PREFIX(store_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE))) | ||
8002 | + | ||
8003 | +/* Likewise, for a two-argument jump. */ | ||
8004 | +# define STORE_JUMP2(op, loc, to, arg) \ | ||
8005 | + PREFIX(store_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), arg) | ||
8006 | + | ||
8007 | +/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ | ||
8008 | +# define INSERT_JUMP(op, loc, to) \ | ||
8009 | + PREFIX(insert_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), b) | ||
8010 | + | ||
8011 | +/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ | ||
8012 | +# define INSERT_JUMP2(op, loc, to, arg) \ | ||
8013 | + PREFIX(insert_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)),\ | ||
8014 | + arg, b) | ||
8015 | + | ||
8016 | +/* This is not an arbitrary limit: the arguments which represent offsets | ||
8017 | + into the pattern are two bytes long. So if 2^16 bytes turns out to | ||
8018 | + be too small, many things would have to change. */ | ||
8019 | +/* Any other compiler which, like MSC, has allocation limit below 2^16 | ||
8020 | + bytes will have to use approach similar to what was done below for | ||
8021 | + MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up | ||
8022 | + reallocating to 0 bytes. Such thing is not going to work too well. | ||
8023 | + You have been warned!! */ | ||
8024 | +# ifndef DEFINED_ONCE | ||
8025 | +# if defined _MSC_VER && !defined WIN32 | ||
8026 | +/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes. | ||
8027 | + The REALLOC define eliminates a flurry of conversion warnings, | ||
8028 | + but is not required. */ | ||
8029 | +# define MAX_BUF_SIZE 65500L | ||
8030 | +# define REALLOC(p,s) realloc ((p), (size_t) (s)) | ||
8031 | +# else | ||
8032 | +# define MAX_BUF_SIZE (1L << 16) | ||
8033 | +# define REALLOC(p,s) realloc ((p), (s)) | ||
8034 | +# endif | ||
8035 | + | ||
8036 | +/* Extend the buffer by twice its current size via realloc and | ||
8037 | + reset the pointers that pointed into the old block to point to the | ||
8038 | + correct places in the new one. If extending the buffer results in it | ||
8039 | + being larger than MAX_BUF_SIZE, then flag memory exhausted. */ | ||
8040 | +# if __BOUNDED_POINTERS__ | ||
8041 | +# define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated) | ||
8042 | +# define MOVE_BUFFER_POINTER(P) \ | ||
8043 | + (__ptrlow (P) += incr, SET_HIGH_BOUND (P), __ptrvalue (P) += incr) | ||
8044 | +# define ELSE_EXTEND_BUFFER_HIGH_BOUND \ | ||
8045 | + else \ | ||
8046 | + { \ | ||
8047 | + SET_HIGH_BOUND (b); \ | ||
8048 | + SET_HIGH_BOUND (begalt); \ | ||
8049 | + if (fixup_alt_jump) \ | ||
8050 | + SET_HIGH_BOUND (fixup_alt_jump); \ | ||
8051 | + if (laststart) \ | ||
8052 | + SET_HIGH_BOUND (laststart); \ | ||
8053 | + if (pending_exact) \ | ||
8054 | + SET_HIGH_BOUND (pending_exact); \ | ||
8055 | + } | ||
8056 | +# else | ||
8057 | +# define MOVE_BUFFER_POINTER(P) (P) += incr | ||
8058 | +# define ELSE_EXTEND_BUFFER_HIGH_BOUND | ||
8059 | +# endif | ||
8060 | +# endif /* not DEFINED_ONCE */ | ||
8061 | + | ||
8062 | +# ifdef WCHAR | ||
8063 | +# define EXTEND_BUFFER() \ | ||
8064 | + do { \ | ||
8065 | + UCHAR_T *old_buffer = COMPILED_BUFFER_VAR; \ | ||
8066 | + int wchar_count; \ | ||
8067 | + if (bufp->allocated + sizeof(UCHAR_T) > MAX_BUF_SIZE) \ | ||
8068 | + return REG_ESIZE; \ | ||
8069 | + bufp->allocated <<= 1; \ | ||
8070 | + if (bufp->allocated > MAX_BUF_SIZE) \ | ||
8071 | + bufp->allocated = MAX_BUF_SIZE; \ | ||
8072 | + /* How many characters the new buffer can have? */ \ | ||
8073 | + wchar_count = bufp->allocated / sizeof(UCHAR_T); \ | ||
8074 | + if (wchar_count == 0) wchar_count = 1; \ | ||
8075 | + /* Truncate the buffer to CHAR_T align. */ \ | ||
8076 | + bufp->allocated = wchar_count * sizeof(UCHAR_T); \ | ||
8077 | + RETALLOC (COMPILED_BUFFER_VAR, wchar_count, UCHAR_T); \ | ||
8078 | + bufp->buffer = (char*)COMPILED_BUFFER_VAR; \ | ||
8079 | + if (COMPILED_BUFFER_VAR == NULL) \ | ||
8080 | + return REG_ESPACE; \ | ||
8081 | + /* If the buffer moved, move all the pointers into it. */ \ | ||
8082 | + if (old_buffer != COMPILED_BUFFER_VAR) \ | ||
8083 | + { \ | ||
8084 | + int incr = COMPILED_BUFFER_VAR - old_buffer; \ | ||
8085 | + MOVE_BUFFER_POINTER (b); \ | ||
8086 | + MOVE_BUFFER_POINTER (begalt); \ | ||
8087 | + if (fixup_alt_jump) \ | ||
8088 | + MOVE_BUFFER_POINTER (fixup_alt_jump); \ | ||
8089 | + if (laststart) \ | ||
8090 | + MOVE_BUFFER_POINTER (laststart); \ | ||
8091 | + if (pending_exact) \ | ||
8092 | + MOVE_BUFFER_POINTER (pending_exact); \ | ||
8093 | + } \ | ||
8094 | + ELSE_EXTEND_BUFFER_HIGH_BOUND \ | ||
8095 | + } while (0) | ||
8096 | +# else /* BYTE */ | ||
8097 | +# define EXTEND_BUFFER() \ | ||
8098 | + do { \ | ||
8099 | + UCHAR_T *old_buffer = COMPILED_BUFFER_VAR; \ | ||
8100 | + if (bufp->allocated == MAX_BUF_SIZE) \ | ||
8101 | + return REG_ESIZE; \ | ||
8102 | + bufp->allocated <<= 1; \ | ||
8103 | + if (bufp->allocated > MAX_BUF_SIZE) \ | ||
8104 | + bufp->allocated = MAX_BUF_SIZE; \ | ||
8105 | + bufp->buffer = (UCHAR_T *) REALLOC (COMPILED_BUFFER_VAR, \ | ||
8106 | + bufp->allocated); \ | ||
8107 | + if (COMPILED_BUFFER_VAR == NULL) \ | ||
8108 | + return REG_ESPACE; \ | ||
8109 | + /* If the buffer moved, move all the pointers into it. */ \ | ||
8110 | + if (old_buffer != COMPILED_BUFFER_VAR) \ | ||
8111 | + { \ | ||
8112 | + int incr = COMPILED_BUFFER_VAR - old_buffer; \ | ||
8113 | + MOVE_BUFFER_POINTER (b); \ | ||
8114 | + MOVE_BUFFER_POINTER (begalt); \ | ||
8115 | + if (fixup_alt_jump) \ | ||
8116 | + MOVE_BUFFER_POINTER (fixup_alt_jump); \ | ||
8117 | + if (laststart) \ | ||
8118 | + MOVE_BUFFER_POINTER (laststart); \ | ||
8119 | + if (pending_exact) \ | ||
8120 | + MOVE_BUFFER_POINTER (pending_exact); \ | ||
8121 | + } \ | ||
8122 | + ELSE_EXTEND_BUFFER_HIGH_BOUND \ | ||
8123 | + } while (0) | ||
8124 | +# endif /* WCHAR */ | ||
8125 | + | ||
8126 | +# ifndef DEFINED_ONCE | ||
8127 | +/* Since we have one byte reserved for the register number argument to | ||
8128 | + {start,stop}_memory, the maximum number of groups we can report | ||
8129 | + things about is what fits in that byte. */ | ||
8130 | +# define MAX_REGNUM 255 | ||
8131 | + | ||
8132 | +/* But patterns can have more than `MAX_REGNUM' registers. We just | ||
8133 | + ignore the excess. */ | ||
8134 | +typedef unsigned regnum_t; | ||
8135 | + | ||
8136 | + | ||
8137 | +/* Macros for the compile stack. */ | ||
8138 | + | ||
8139 | +/* Since offsets can go either forwards or backwards, this type needs to | ||
8140 | + be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ | ||
8141 | +/* int may be not enough when sizeof(int) == 2. */ | ||
8142 | +typedef long pattern_offset_t; | ||
8143 | + | ||
8144 | +typedef struct | ||
8145 | +{ | ||
8146 | + pattern_offset_t begalt_offset; | ||
8147 | + pattern_offset_t fixup_alt_jump; | ||
8148 | + pattern_offset_t inner_group_offset; | ||
8149 | + pattern_offset_t laststart_offset; | ||
8150 | + regnum_t regnum; | ||
8151 | +} compile_stack_elt_t; | ||
8152 | + | ||
8153 | + | ||
8154 | +typedef struct | ||
8155 | +{ | ||
8156 | + compile_stack_elt_t *stack; | ||
8157 | + unsigned size; | ||
8158 | + unsigned avail; /* Offset of next open position. */ | ||
8159 | +} compile_stack_type; | ||
8160 | + | ||
8161 | + | ||
8162 | +# define INIT_COMPILE_STACK_SIZE 32 | ||
8163 | + | ||
8164 | +# define COMPILE_STACK_EMPTY (compile_stack.avail == 0) | ||
8165 | +# define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) | ||
8166 | + | ||
8167 | +/* The next available element. */ | ||
8168 | +# define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) | ||
8169 | + | ||
8170 | +# endif /* not DEFINED_ONCE */ | ||
8171 | + | ||
8172 | +/* Set the bit for character C in a list. */ | ||
8173 | +# ifndef DEFINED_ONCE | ||
8174 | +# define SET_LIST_BIT(c) \ | ||
8175 | + (b[((unsigned char) (c)) / BYTEWIDTH] \ | ||
8176 | + |= 1 << (((unsigned char) c) % BYTEWIDTH)) | ||
8177 | +# endif /* DEFINED_ONCE */ | ||
8178 | + | ||
8179 | +/* Get the next unsigned number in the uncompiled pattern. */ | ||
8180 | +# define GET_UNSIGNED_NUMBER(num) \ | ||
8181 | + { \ | ||
8182 | + while (p != pend) \ | ||
8183 | + { \ | ||
8184 | + PATFETCH (c); \ | ||
8185 | + if (c < '0' || c > '9') \ | ||
8186 | + break; \ | ||
8187 | + if (num <= RE_DUP_MAX) \ | ||
8188 | + { \ | ||
8189 | + if (num < 0) \ | ||
8190 | + num = 0; \ | ||
8191 | + num = num * 10 + c - '0'; \ | ||
8192 | + } \ | ||
8193 | + } \ | ||
8194 | + } | ||
8195 | + | ||
8196 | +# ifndef DEFINED_ONCE | ||
8197 | +# if WIDE_CHAR_SUPPORT | ||
8198 | +/* The GNU C library provides support for user-defined character classes | ||
8199 | + and the functions from ISO C amendement 1. */ | ||
8200 | +# ifdef CHARCLASS_NAME_MAX | ||
8201 | +# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX | ||
8202 | +# else | ||
8203 | +/* This shouldn't happen but some implementation might still have this | ||
8204 | + problem. Use a reasonable default value. */ | ||
8205 | +# define CHAR_CLASS_MAX_LENGTH 256 | ||
8206 | +# endif | ||
8207 | + | ||
8208 | +# ifdef _LIBC | ||
8209 | +# define IS_CHAR_CLASS(string) __wctype (string) | ||
8210 | +# else | ||
8211 | +# define IS_CHAR_CLASS(string) wctype (string) | ||
8212 | +# endif | ||
8213 | +# else | ||
8214 | +# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ | ||
8215 | + | ||
8216 | +# define IS_CHAR_CLASS(string) \ | ||
8217 | + (STREQ (string, "alpha") || STREQ (string, "upper") \ | ||
8218 | + || STREQ (string, "lower") || STREQ (string, "digit") \ | ||
8219 | + || STREQ (string, "alnum") || STREQ (string, "xdigit") \ | ||
8220 | + || STREQ (string, "space") || STREQ (string, "print") \ | ||
8221 | + || STREQ (string, "punct") || STREQ (string, "graph") \ | ||
8222 | + || STREQ (string, "cntrl") || STREQ (string, "blank")) | ||
8223 | +# endif | ||
8224 | +# endif /* DEFINED_ONCE */ | ||
8225 | + | ||
8226 | +# ifndef MATCH_MAY_ALLOCATE | ||
8227 | + | ||
8228 | +/* If we cannot allocate large objects within re_match_2_internal, | ||
8229 | + we make the fail stack and register vectors global. | ||
8230 | + The fail stack, we grow to the maximum size when a regexp | ||
8231 | + is compiled. | ||
8232 | + The register vectors, we adjust in size each time we | ||
8233 | + compile a regexp, according to the number of registers it needs. */ | ||
8234 | + | ||
8235 | +static PREFIX(fail_stack_type) fail_stack; | ||
8236 | + | ||
8237 | +/* Size with which the following vectors are currently allocated. | ||
8238 | + That is so we can make them bigger as needed, | ||
8239 | + but never make them smaller. */ | ||
8240 | +# ifdef DEFINED_ONCE | ||
8241 | +static int regs_allocated_size; | ||
8242 | + | ||
8243 | +static const char ** regstart, ** regend; | ||
8244 | +static const char ** old_regstart, ** old_regend; | ||
8245 | +static const char **best_regstart, **best_regend; | ||
8246 | +static const char **reg_dummy; | ||
8247 | +# endif /* DEFINED_ONCE */ | ||
8248 | + | ||
8249 | +static PREFIX(register_info_type) *PREFIX(reg_info); | ||
8250 | +static PREFIX(register_info_type) *PREFIX(reg_info_dummy); | ||
8251 | + | ||
8252 | +/* Make the register vectors big enough for NUM_REGS registers, | ||
8253 | + but don't make them smaller. */ | ||
8254 | + | ||
8255 | +static void | ||
8256 | +PREFIX(regex_grow_registers) (int num_regs) | ||
8257 | +{ | ||
8258 | + if (num_regs > regs_allocated_size) | ||
8259 | + { | ||
8260 | + RETALLOC_IF (regstart, num_regs, const char *); | ||
8261 | + RETALLOC_IF (regend, num_regs, const char *); | ||
8262 | + RETALLOC_IF (old_regstart, num_regs, const char *); | ||
8263 | + RETALLOC_IF (old_regend, num_regs, const char *); | ||
8264 | + RETALLOC_IF (best_regstart, num_regs, const char *); | ||
8265 | + RETALLOC_IF (best_regend, num_regs, const char *); | ||
8266 | + RETALLOC_IF (PREFIX(reg_info), num_regs, PREFIX(register_info_type)); | ||
8267 | + RETALLOC_IF (reg_dummy, num_regs, const char *); | ||
8268 | + RETALLOC_IF (PREFIX(reg_info_dummy), num_regs, PREFIX(register_info_type)); | ||
8269 | + | ||
8270 | + regs_allocated_size = num_regs; | ||
8271 | + } | ||
8272 | +} | ||
8273 | + | ||
8274 | +# endif /* not MATCH_MAY_ALLOCATE */ | ||
8275 | + | ||
8276 | +# ifndef DEFINED_ONCE | ||
8277 | +static boolean group_in_compile_stack (compile_stack_type compile_stack, | ||
8278 | + regnum_t regnum); | ||
8279 | +# endif /* not DEFINED_ONCE */ | ||
8280 | + | ||
8281 | +/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. | ||
8282 | + Returns one of error codes defined in `regex.h', or zero for success. | ||
8283 | + | ||
8284 | + Assumes the `allocated' (and perhaps `buffer') and `translate' | ||
8285 | + fields are set in BUFP on entry. | ||
8286 | + | ||
8287 | + If it succeeds, results are put in BUFP (if it returns an error, the | ||
8288 | + contents of BUFP are undefined): | ||
8289 | + `buffer' is the compiled pattern; | ||
8290 | + `syntax' is set to SYNTAX; | ||
8291 | + `used' is set to the length of the compiled pattern; | ||
8292 | + `fastmap_accurate' is zero; | ||
8293 | + `re_nsub' is the number of subexpressions in PATTERN; | ||
8294 | + `not_bol' and `not_eol' are zero; | ||
8295 | + | ||
8296 | + The `fastmap' and `newline_anchor' fields are neither | ||
8297 | + examined nor set. */ | ||
8298 | + | ||
8299 | +/* Return, freeing storage we allocated. */ | ||
8300 | +# ifdef WCHAR | ||
8301 | +# define FREE_STACK_RETURN(value) \ | ||
8302 | + return (free(pattern), free(mbs_offset), free(is_binary), free (compile_stack.stack), value) | ||
8303 | +# else | ||
8304 | +# define FREE_STACK_RETURN(value) \ | ||
8305 | + return (free (compile_stack.stack), value) | ||
8306 | +# endif /* WCHAR */ | ||
8307 | + | ||
8308 | +static reg_errcode_t | ||
8309 | +PREFIX(regex_compile) (const char *ARG_PREFIX(pattern), | ||
8310 | + size_t ARG_PREFIX(size), reg_syntax_t syntax, | ||
8311 | + struct re_pattern_buffer *bufp) | ||
8312 | +{ | ||
8313 | + /* We fetch characters from PATTERN here. Even though PATTERN is | ||
8314 | + `char *' (i.e., signed), we declare these variables as unsigned, so | ||
8315 | + they can be reliably used as array indices. */ | ||
8316 | + register UCHAR_T c, c1; | ||
8317 | + | ||
8318 | +#ifdef WCHAR | ||
8319 | + /* A temporary space to keep wchar_t pattern and compiled pattern. */ | ||
8320 | + CHAR_T *pattern, *COMPILED_BUFFER_VAR; | ||
8321 | + size_t size; | ||
8322 | + /* offset buffer for optimization. See convert_mbs_to_wc. */ | ||
8323 | + int *mbs_offset = NULL; | ||
8324 | + /* It hold whether each wchar_t is binary data or not. */ | ||
8325 | + char *is_binary = NULL; | ||
8326 | + /* A flag whether exactn is handling binary data or not. */ | ||
8327 | + char is_exactn_bin = FALSE; | ||
8328 | +#endif /* WCHAR */ | ||
8329 | + | ||
8330 | + /* A random temporary spot in PATTERN. */ | ||
8331 | + const CHAR_T *p1; | ||
8332 | + | ||
8333 | + /* Points to the end of the buffer, where we should append. */ | ||
8334 | + register UCHAR_T *b; | ||
8335 | + | ||
8336 | + /* Keeps track of unclosed groups. */ | ||
8337 | + compile_stack_type compile_stack; | ||
8338 | + | ||
8339 | + /* Points to the current (ending) position in the pattern. */ | ||
8340 | +#ifdef WCHAR | ||
8341 | + const CHAR_T *p; | ||
8342 | + const CHAR_T *pend; | ||
8343 | +#else /* BYTE */ | ||
8344 | + const CHAR_T *p = pattern; | ||
8345 | + const CHAR_T *pend = pattern + size; | ||
8346 | +#endif /* WCHAR */ | ||
8347 | + | ||
8348 | + /* How to translate the characters in the pattern. */ | ||
8349 | + RE_TRANSLATE_TYPE translate = bufp->translate; | ||
8350 | + | ||
8351 | + /* Address of the count-byte of the most recently inserted `exactn' | ||
8352 | + command. This makes it possible to tell if a new exact-match | ||
8353 | + character can be added to that command or if the character requires | ||
8354 | + a new `exactn' command. */ | ||
8355 | + UCHAR_T *pending_exact = 0; | ||
8356 | + | ||
8357 | + /* Address of start of the most recently finished expression. | ||
8358 | + This tells, e.g., postfix * where to find the start of its | ||
8359 | + operand. Reset at the beginning of groups and alternatives. */ | ||
8360 | + UCHAR_T *laststart = 0; | ||
8361 | + | ||
8362 | + /* Address of beginning of regexp, or inside of last group. */ | ||
8363 | + UCHAR_T *begalt; | ||
8364 | + | ||
8365 | + /* Address of the place where a forward jump should go to the end of | ||
8366 | + the containing expression. Each alternative of an `or' -- except the | ||
8367 | + last -- ends with a forward jump of this sort. */ | ||
8368 | + UCHAR_T *fixup_alt_jump = 0; | ||
8369 | + | ||
8370 | + /* Counts open-groups as they are encountered. Remembered for the | ||
8371 | + matching close-group on the compile stack, so the same register | ||
8372 | + number is put in the stop_memory as the start_memory. */ | ||
8373 | + regnum_t regnum = 0; | ||
8374 | + | ||
8375 | +#ifdef WCHAR | ||
8376 | + /* Initialize the wchar_t PATTERN and offset_buffer. */ | ||
8377 | + p = pend = pattern = TALLOC(csize + 1, CHAR_T); | ||
8378 | + mbs_offset = TALLOC(csize + 1, int); | ||
8379 | + is_binary = TALLOC(csize + 1, char); | ||
8380 | + if (pattern == NULL || mbs_offset == NULL || is_binary == NULL) | ||
8381 | + { | ||
8382 | + free(pattern); | ||
8383 | + free(mbs_offset); | ||
8384 | + free(is_binary); | ||
8385 | + return REG_ESPACE; | ||
8386 | + } | ||
8387 | + pattern[csize] = L'\0'; /* sentinel */ | ||
8388 | + size = convert_mbs_to_wcs(pattern, cpattern, csize, mbs_offset, is_binary); | ||
8389 | + pend = p + size; | ||
8390 | + if (size < 0) | ||
8391 | + { | ||
8392 | + free(pattern); | ||
8393 | + free(mbs_offset); | ||
8394 | + free(is_binary); | ||
8395 | + return REG_BADPAT; | ||
8396 | + } | ||
8397 | +#endif | ||
8398 | + | ||
8399 | +#ifdef DEBUG | ||
8400 | + DEBUG_PRINT1 ("\nCompiling pattern: "); | ||
8401 | + if (debug) | ||
8402 | + { | ||
8403 | + unsigned debug_count; | ||
8404 | + | ||
8405 | + for (debug_count = 0; debug_count < size; debug_count++) | ||
8406 | + PUT_CHAR (pattern[debug_count]); | ||
8407 | + putchar ('\n'); | ||
8408 | + } | ||
8409 | +#endif /* DEBUG */ | ||
8410 | + | ||
8411 | + /* Initialize the compile stack. */ | ||
8412 | + compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); | ||
8413 | + if (compile_stack.stack == NULL) | ||
8414 | + { | ||
8415 | +#ifdef WCHAR | ||
8416 | + free(pattern); | ||
8417 | + free(mbs_offset); | ||
8418 | + free(is_binary); | ||
8419 | +#endif | ||
8420 | + return REG_ESPACE; | ||
8421 | + } | ||
8422 | + | ||
8423 | + compile_stack.size = INIT_COMPILE_STACK_SIZE; | ||
8424 | + compile_stack.avail = 0; | ||
8425 | + | ||
8426 | + /* Initialize the pattern buffer. */ | ||
8427 | + bufp->syntax = syntax; | ||
8428 | + bufp->fastmap_accurate = 0; | ||
8429 | + bufp->not_bol = bufp->not_eol = 0; | ||
8430 | + | ||
8431 | + /* Set `used' to zero, so that if we return an error, the pattern | ||
8432 | + printer (for debugging) will think there's no pattern. We reset it | ||
8433 | + at the end. */ | ||
8434 | + bufp->used = 0; | ||
8435 | + | ||
8436 | + /* Always count groups, whether or not bufp->no_sub is set. */ | ||
8437 | + bufp->re_nsub = 0; | ||
8438 | + | ||
8439 | +#if !defined emacs && !defined SYNTAX_TABLE | ||
8440 | + /* Initialize the syntax table. */ | ||
8441 | + init_syntax_once (); | ||
8442 | +#endif | ||
8443 | + | ||
8444 | + if (bufp->allocated == 0) | ||
8445 | + { | ||
8446 | + if (bufp->buffer) | ||
8447 | + { /* If zero allocated, but buffer is non-null, try to realloc | ||
8448 | + enough space. This loses if buffer's address is bogus, but | ||
8449 | + that is the user's responsibility. */ | ||
8450 | +#ifdef WCHAR | ||
8451 | + /* Free bufp->buffer and allocate an array for wchar_t pattern | ||
8452 | + buffer. */ | ||
8453 | + free(bufp->buffer); | ||
8454 | + COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE/sizeof(UCHAR_T), | ||
8455 | + UCHAR_T); | ||
8456 | +#else | ||
8457 | + RETALLOC (COMPILED_BUFFER_VAR, INIT_BUF_SIZE, UCHAR_T); | ||
8458 | +#endif /* WCHAR */ | ||
8459 | + } | ||
8460 | + else | ||
8461 | + { /* Caller did not allocate a buffer. Do it for them. */ | ||
8462 | + COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE / sizeof(UCHAR_T), | ||
8463 | + UCHAR_T); | ||
8464 | + } | ||
8465 | + | ||
8466 | + if (!COMPILED_BUFFER_VAR) FREE_STACK_RETURN (REG_ESPACE); | ||
8467 | +#ifdef WCHAR | ||
8468 | + bufp->buffer = (char*)COMPILED_BUFFER_VAR; | ||
8469 | +#endif /* WCHAR */ | ||
8470 | + bufp->allocated = INIT_BUF_SIZE; | ||
8471 | + } | ||
8472 | +#ifdef WCHAR | ||
8473 | + else | ||
8474 | + COMPILED_BUFFER_VAR = (UCHAR_T*) bufp->buffer; | ||
8475 | +#endif | ||
8476 | + | ||
8477 | + begalt = b = COMPILED_BUFFER_VAR; | ||
8478 | + | ||
8479 | + /* Loop through the uncompiled pattern until we're at the end. */ | ||
8480 | + while (p != pend) | ||
8481 | + { | ||
8482 | + PATFETCH (c); | ||
8483 | + | ||
8484 | + switch (c) | ||
8485 | + { | ||
8486 | + case '^': | ||
8487 | + { | ||
8488 | + if ( /* If at start of pattern, it's an operator. */ | ||
8489 | + p == pattern + 1 | ||
8490 | + /* If context independent, it's an operator. */ | ||
8491 | + || syntax & RE_CONTEXT_INDEP_ANCHORS | ||
8492 | + /* Otherwise, depends on what's come before. */ | ||
8493 | + || PREFIX(at_begline_loc_p) (pattern, p, syntax)) | ||
8494 | + BUF_PUSH (begline); | ||
8495 | + else | ||
8496 | + goto normal_char; | ||
8497 | + } | ||
8498 | + break; | ||
8499 | + | ||
8500 | + | ||
8501 | + case '$': | ||
8502 | + { | ||
8503 | + if ( /* If at end of pattern, it's an operator. */ | ||
8504 | + p == pend | ||
8505 | + /* If context independent, it's an operator. */ | ||
8506 | + || syntax & RE_CONTEXT_INDEP_ANCHORS | ||
8507 | + /* Otherwise, depends on what's next. */ | ||
8508 | + || PREFIX(at_endline_loc_p) (p, pend, syntax)) | ||
8509 | + BUF_PUSH (endline); | ||
8510 | + else | ||
8511 | + goto normal_char; | ||
8512 | + } | ||
8513 | + break; | ||
8514 | + | ||
8515 | + | ||
8516 | + case '+': | ||
8517 | + case '?': | ||
8518 | + if ((syntax & RE_BK_PLUS_QM) | ||
8519 | + || (syntax & RE_LIMITED_OPS)) | ||
8520 | + goto normal_char; | ||
8521 | + handle_plus: | ||
8522 | + case '*': | ||
8523 | + /* If there is no previous pattern... */ | ||
8524 | + if (!laststart) | ||
8525 | + { | ||
8526 | + if (syntax & RE_CONTEXT_INVALID_OPS) | ||
8527 | + FREE_STACK_RETURN (REG_BADRPT); | ||
8528 | + else if (!(syntax & RE_CONTEXT_INDEP_OPS)) | ||
8529 | + goto normal_char; | ||
8530 | + } | ||
8531 | + | ||
8532 | + { | ||
8533 | + /* Are we optimizing this jump? */ | ||
8534 | + boolean keep_string_p = false; | ||
8535 | + | ||
8536 | + /* 1 means zero (many) matches is allowed. */ | ||
8537 | + char zero_times_ok = 0, many_times_ok = 0; | ||
8538 | + | ||
8539 | + /* If there is a sequence of repetition chars, collapse it | ||
8540 | + down to just one (the right one). We can't combine | ||
8541 | + interval operators with these because of, e.g., `a{2}*', | ||
8542 | + which should only match an even number of `a's. */ | ||
8543 | + | ||
8544 | + for (;;) | ||
8545 | + { | ||
8546 | + zero_times_ok |= c != '+'; | ||
8547 | + many_times_ok |= c != '?'; | ||
8548 | + | ||
8549 | + if (p == pend) | ||
8550 | + break; | ||
8551 | + | ||
8552 | + PATFETCH (c); | ||
8553 | + | ||
8554 | + if (c == '*' | ||
8555 | + || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) | ||
8556 | + ; | ||
8557 | + | ||
8558 | + else if (syntax & RE_BK_PLUS_QM && c == '\\') | ||
8559 | + { | ||
8560 | + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); | ||
8561 | + | ||
8562 | + PATFETCH (c1); | ||
8563 | + if (!(c1 == '+' || c1 == '?')) | ||
8564 | + { | ||
8565 | + PATUNFETCH; | ||
8566 | + PATUNFETCH; | ||
8567 | + break; | ||
8568 | + } | ||
8569 | + | ||
8570 | + c = c1; | ||
8571 | + } | ||
8572 | + else | ||
8573 | + { | ||
8574 | + PATUNFETCH; | ||
8575 | + break; | ||
8576 | + } | ||
8577 | + | ||
8578 | + /* If we get here, we found another repeat character. */ | ||
8579 | + } | ||
8580 | + | ||
8581 | + /* Star, etc. applied to an empty pattern is equivalent | ||
8582 | + to an empty pattern. */ | ||
8583 | + if (!laststart) | ||
8584 | + break; | ||
8585 | + | ||
8586 | + /* Now we know whether or not zero matches is allowed | ||
8587 | + and also whether or not two or more matches is allowed. */ | ||
8588 | + if (many_times_ok) | ||
8589 | + { /* More than one repetition is allowed, so put in at the | ||
8590 | + end a backward relative jump from `b' to before the next | ||
8591 | + jump we're going to put in below (which jumps from | ||
8592 | + laststart to after this jump). | ||
8593 | + | ||
8594 | + But if we are at the `*' in the exact sequence `.*\n', | ||
8595 | + insert an unconditional jump backwards to the ., | ||
8596 | + instead of the beginning of the loop. This way we only | ||
8597 | + push a failure point once, instead of every time | ||
8598 | + through the loop. */ | ||
8599 | + assert (p - 1 > pattern); | ||
8600 | + | ||
8601 | + /* Allocate the space for the jump. */ | ||
8602 | + GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE); | ||
8603 | + | ||
8604 | + /* We know we are not at the first character of the pattern, | ||
8605 | + because laststart was nonzero. And we've already | ||
8606 | + incremented `p', by the way, to be the character after | ||
8607 | + the `*'. Do we have to do something analogous here | ||
8608 | + for null bytes, because of RE_DOT_NOT_NULL? */ | ||
8609 | + if (TRANSLATE (*(p - 2)) == TRANSLATE ('.') | ||
8610 | + && zero_times_ok | ||
8611 | + && p < pend && TRANSLATE (*p) == TRANSLATE ('\n') | ||
8612 | + && !(syntax & RE_DOT_NEWLINE)) | ||
8613 | + { /* We have .*\n. */ | ||
8614 | + STORE_JUMP (jump, b, laststart); | ||
8615 | + keep_string_p = true; | ||
8616 | + } | ||
8617 | + else | ||
8618 | + /* Anything else. */ | ||
8619 | + STORE_JUMP (maybe_pop_jump, b, laststart - | ||
8620 | + (1 + OFFSET_ADDRESS_SIZE)); | ||
8621 | + | ||
8622 | + /* We've added more stuff to the buffer. */ | ||
8623 | + b += 1 + OFFSET_ADDRESS_SIZE; | ||
8624 | + } | ||
8625 | + | ||
8626 | + /* On failure, jump from laststart to b + 3, which will be the | ||
8627 | + end of the buffer after this jump is inserted. */ | ||
8628 | + /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE' instead of | ||
8629 | + 'b + 3'. */ | ||
8630 | + GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE); | ||
8631 | + INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump | ||
8632 | + : on_failure_jump, | ||
8633 | + laststart, b + 1 + OFFSET_ADDRESS_SIZE); | ||
8634 | + pending_exact = 0; | ||
8635 | + b += 1 + OFFSET_ADDRESS_SIZE; | ||
8636 | + | ||
8637 | + if (!zero_times_ok) | ||
8638 | + { | ||
8639 | + /* At least one repetition is required, so insert a | ||
8640 | + `dummy_failure_jump' before the initial | ||
8641 | + `on_failure_jump' instruction of the loop. This | ||
8642 | + effects a skip over that instruction the first time | ||
8643 | + we hit that loop. */ | ||
8644 | + GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE); | ||
8645 | + INSERT_JUMP (dummy_failure_jump, laststart, laststart + | ||
8646 | + 2 + 2 * OFFSET_ADDRESS_SIZE); | ||
8647 | + b += 1 + OFFSET_ADDRESS_SIZE; | ||
8648 | + } | ||
8649 | + } | ||
8650 | + break; | ||
8651 | + | ||
8652 | + | ||
8653 | + case '.': | ||
8654 | + laststart = b; | ||
8655 | + BUF_PUSH (anychar); | ||
8656 | + break; | ||
8657 | + | ||
8658 | + | ||
8659 | + case '[': | ||
8660 | + { | ||
8661 | + boolean had_char_class = false; | ||
8662 | +#ifdef WCHAR | ||
8663 | + CHAR_T range_start = 0xffffffff; | ||
8664 | +#else | ||
8665 | + unsigned int range_start = 0xffffffff; | ||
8666 | +#endif | ||
8667 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
8668 | + | ||
8669 | +#ifdef WCHAR | ||
8670 | + /* We assume a charset(_not) structure as a wchar_t array. | ||
8671 | + charset[0] = (re_opcode_t) charset(_not) | ||
8672 | + charset[1] = l (= length of char_classes) | ||
8673 | + charset[2] = m (= length of collating_symbols) | ||
8674 | + charset[3] = n (= length of equivalence_classes) | ||
8675 | + charset[4] = o (= length of char_ranges) | ||
8676 | + charset[5] = p (= length of chars) | ||
8677 | + | ||
8678 | + charset[6] = char_class (wctype_t) | ||
8679 | + charset[6+CHAR_CLASS_SIZE] = char_class (wctype_t) | ||
8680 | + ... | ||
8681 | + charset[l+5] = char_class (wctype_t) | ||
8682 | + | ||
8683 | + charset[l+6] = collating_symbol (wchar_t) | ||
8684 | + ... | ||
8685 | + charset[l+m+5] = collating_symbol (wchar_t) | ||
8686 | + ifdef _LIBC we use the index if | ||
8687 | + _NL_COLLATE_SYMB_EXTRAMB instead of | ||
8688 | + wchar_t string. | ||
8689 | + | ||
8690 | + charset[l+m+6] = equivalence_classes (wchar_t) | ||
8691 | + ... | ||
8692 | + charset[l+m+n+5] = equivalence_classes (wchar_t) | ||
8693 | + ifdef _LIBC we use the index in | ||
8694 | + _NL_COLLATE_WEIGHT instead of | ||
8695 | + wchar_t string. | ||
8696 | + | ||
8697 | + charset[l+m+n+6] = range_start | ||
8698 | + charset[l+m+n+7] = range_end | ||
8699 | + ... | ||
8700 | + charset[l+m+n+2o+4] = range_start | ||
8701 | + charset[l+m+n+2o+5] = range_end | ||
8702 | + ifdef _LIBC we use the value looked up | ||
8703 | + in _NL_COLLATE_COLLSEQ instead of | ||
8704 | + wchar_t character. | ||
8705 | + | ||
8706 | + charset[l+m+n+2o+6] = char | ||
8707 | + ... | ||
8708 | + charset[l+m+n+2o+p+5] = char | ||
8709 | + | ||
8710 | + */ | ||
8711 | + | ||
8712 | + /* We need at least 6 spaces: the opcode, the length of | ||
8713 | + char_classes, the length of collating_symbols, the length of | ||
8714 | + equivalence_classes, the length of char_ranges, the length of | ||
8715 | + chars. */ | ||
8716 | + GET_BUFFER_SPACE (6); | ||
8717 | + | ||
8718 | + /* Save b as laststart. And We use laststart as the pointer | ||
8719 | + to the first element of the charset here. | ||
8720 | + In other words, laststart[i] indicates charset[i]. */ | ||
8721 | + laststart = b; | ||
8722 | + | ||
8723 | + /* We test `*p == '^' twice, instead of using an if | ||
8724 | + statement, so we only need one BUF_PUSH. */ | ||
8725 | + BUF_PUSH (*p == '^' ? charset_not : charset); | ||
8726 | + if (*p == '^') | ||
8727 | + p++; | ||
8728 | + | ||
8729 | + /* Push the length of char_classes, the length of | ||
8730 | + collating_symbols, the length of equivalence_classes, the | ||
8731 | + length of char_ranges and the length of chars. */ | ||
8732 | + BUF_PUSH_3 (0, 0, 0); | ||
8733 | + BUF_PUSH_2 (0, 0); | ||
8734 | + | ||
8735 | + /* Remember the first position in the bracket expression. */ | ||
8736 | + p1 = p; | ||
8737 | + | ||
8738 | + /* charset_not matches newline according to a syntax bit. */ | ||
8739 | + if ((re_opcode_t) b[-6] == charset_not | ||
8740 | + && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) | ||
8741 | + { | ||
8742 | + BUF_PUSH('\n'); | ||
8743 | + laststart[5]++; /* Update the length of characters */ | ||
8744 | + } | ||
8745 | + | ||
8746 | + /* Read in characters and ranges, setting map bits. */ | ||
8747 | + for (;;) | ||
8748 | + { | ||
8749 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
8750 | + | ||
8751 | + PATFETCH (c); | ||
8752 | + | ||
8753 | + /* \ might escape characters inside [...] and [^...]. */ | ||
8754 | + if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') | ||
8755 | + { | ||
8756 | + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); | ||
8757 | + | ||
8758 | + PATFETCH (c1); | ||
8759 | + BUF_PUSH(c1); | ||
8760 | + laststart[5]++; /* Update the length of chars */ | ||
8761 | + range_start = c1; | ||
8762 | + continue; | ||
8763 | + } | ||
8764 | + | ||
8765 | + /* Could be the end of the bracket expression. If it's | ||
8766 | + not (i.e., when the bracket expression is `[]' so | ||
8767 | + far), the ']' character bit gets set way below. */ | ||
8768 | + if (c == ']' && p != p1 + 1) | ||
8769 | + break; | ||
8770 | + | ||
8771 | + /* Look ahead to see if it's a range when the last thing | ||
8772 | + was a character class. */ | ||
8773 | + if (had_char_class && c == '-' && *p != ']') | ||
8774 | + FREE_STACK_RETURN (REG_ERANGE); | ||
8775 | + | ||
8776 | + /* Look ahead to see if it's a range when the last thing | ||
8777 | + was a character: if this is a hyphen not at the | ||
8778 | + beginning or the end of a list, then it's the range | ||
8779 | + operator. */ | ||
8780 | + if (c == '-' | ||
8781 | + && !(p - 2 >= pattern && p[-2] == '[') | ||
8782 | + && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') | ||
8783 | + && *p != ']') | ||
8784 | + { | ||
8785 | + reg_errcode_t ret; | ||
8786 | + /* Allocate the space for range_start and range_end. */ | ||
8787 | + GET_BUFFER_SPACE (2); | ||
8788 | + /* Update the pointer to indicate end of buffer. */ | ||
8789 | + b += 2; | ||
8790 | + ret = wcs_compile_range (range_start, &p, pend, translate, | ||
8791 | + syntax, b, laststart); | ||
8792 | + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); | ||
8793 | + range_start = 0xffffffff; | ||
8794 | + } | ||
8795 | + else if (p[0] == '-' && p[1] != ']') | ||
8796 | + { /* This handles ranges made up of characters only. */ | ||
8797 | + reg_errcode_t ret; | ||
8798 | + | ||
8799 | + /* Move past the `-'. */ | ||
8800 | + PATFETCH (c1); | ||
8801 | + /* Allocate the space for range_start and range_end. */ | ||
8802 | + GET_BUFFER_SPACE (2); | ||
8803 | + /* Update the pointer to indicate end of buffer. */ | ||
8804 | + b += 2; | ||
8805 | + ret = wcs_compile_range (c, &p, pend, translate, syntax, b, | ||
8806 | + laststart); | ||
8807 | + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); | ||
8808 | + range_start = 0xffffffff; | ||
8809 | + } | ||
8810 | + | ||
8811 | + /* See if we're at the beginning of a possible character | ||
8812 | + class. */ | ||
8813 | + else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') | ||
8814 | + { /* Leave room for the null. */ | ||
8815 | + char str[CHAR_CLASS_MAX_LENGTH + 1]; | ||
8816 | + | ||
8817 | + PATFETCH (c); | ||
8818 | + c1 = 0; | ||
8819 | + | ||
8820 | + /* If pattern is `[[:'. */ | ||
8821 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
8822 | + | ||
8823 | + for (;;) | ||
8824 | + { | ||
8825 | + PATFETCH (c); | ||
8826 | + if ((c == ':' && *p == ']') || p == pend) | ||
8827 | + break; | ||
8828 | + if (c1 < CHAR_CLASS_MAX_LENGTH) | ||
8829 | + str[c1++] = c; | ||
8830 | + else | ||
8831 | + /* This is in any case an invalid class name. */ | ||
8832 | + str[0] = '\0'; | ||
8833 | + } | ||
8834 | + str[c1] = '\0'; | ||
8835 | + | ||
8836 | + /* If isn't a word bracketed by `[:' and `:]': | ||
8837 | + undo the ending character, the letters, and leave | ||
8838 | + the leading `:' and `[' (but store them as character). */ | ||
8839 | + if (c == ':' && *p == ']') | ||
8840 | + { | ||
8841 | + wctype_t wt; | ||
8842 | + uintptr_t alignedp; | ||
8843 | + | ||
8844 | + /* Query the character class as wctype_t. */ | ||
8845 | + wt = IS_CHAR_CLASS (str); | ||
8846 | + if (wt == 0) | ||
8847 | + FREE_STACK_RETURN (REG_ECTYPE); | ||
8848 | + | ||
8849 | + /* Throw away the ] at the end of the character | ||
8850 | + class. */ | ||
8851 | + PATFETCH (c); | ||
8852 | + | ||
8853 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
8854 | + | ||
8855 | + /* Allocate the space for character class. */ | ||
8856 | + GET_BUFFER_SPACE(CHAR_CLASS_SIZE); | ||
8857 | + /* Update the pointer to indicate end of buffer. */ | ||
8858 | + b += CHAR_CLASS_SIZE; | ||
8859 | + /* Move data which follow character classes | ||
8860 | + not to violate the data. */ | ||
8861 | + insert_space(CHAR_CLASS_SIZE, | ||
8862 | + laststart + 6 + laststart[1], | ||
8863 | + b - 1); | ||
8864 | + alignedp = ((uintptr_t)(laststart + 6 + laststart[1]) | ||
8865 | + + __alignof__(wctype_t) - 1) | ||
8866 | + & ~(uintptr_t)(__alignof__(wctype_t) - 1); | ||
8867 | + /* Store the character class. */ | ||
8868 | + *((wctype_t*)alignedp) = wt; | ||
8869 | + /* Update length of char_classes */ | ||
8870 | + laststart[1] += CHAR_CLASS_SIZE; | ||
8871 | + | ||
8872 | + had_char_class = true; | ||
8873 | + } | ||
8874 | + else | ||
8875 | + { | ||
8876 | + c1++; | ||
8877 | + while (c1--) | ||
8878 | + PATUNFETCH; | ||
8879 | + BUF_PUSH ('['); | ||
8880 | + BUF_PUSH (':'); | ||
8881 | + laststart[5] += 2; /* Update the length of characters */ | ||
8882 | + range_start = ':'; | ||
8883 | + had_char_class = false; | ||
8884 | + } | ||
8885 | + } | ||
8886 | + else if (syntax & RE_CHAR_CLASSES && c == '[' && (*p == '=' | ||
8887 | + || *p == '.')) | ||
8888 | + { | ||
8889 | + CHAR_T str[128]; /* Should be large enough. */ | ||
8890 | + CHAR_T delim = *p; /* '=' or '.' */ | ||
8891 | +# ifdef _LIBC | ||
8892 | + uint32_t nrules = | ||
8893 | + _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); | ||
8894 | +# endif | ||
8895 | + PATFETCH (c); | ||
8896 | + c1 = 0; | ||
8897 | + | ||
8898 | + /* If pattern is `[[=' or '[[.'. */ | ||
8899 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
8900 | + | ||
8901 | + for (;;) | ||
8902 | + { | ||
8903 | + PATFETCH (c); | ||
8904 | + if ((c == delim && *p == ']') || p == pend) | ||
8905 | + break; | ||
8906 | + if (c1 < sizeof (str) - 1) | ||
8907 | + str[c1++] = c; | ||
8908 | + else | ||
8909 | + /* This is in any case an invalid class name. */ | ||
8910 | + str[0] = '\0'; | ||
8911 | + } | ||
8912 | + str[c1] = '\0'; | ||
8913 | + | ||
8914 | + if (c == delim && *p == ']' && str[0] != '\0') | ||
8915 | + { | ||
8916 | + unsigned int i, offset; | ||
8917 | + /* If we have no collation data we use the default | ||
8918 | + collation in which each character is in a class | ||
8919 | + by itself. It also means that ASCII is the | ||
8920 | + character set and therefore we cannot have character | ||
8921 | + with more than one byte in the multibyte | ||
8922 | + representation. */ | ||
8923 | + | ||
8924 | + /* If not defined _LIBC, we push the name and | ||
8925 | + `\0' for the sake of matching performance. */ | ||
8926 | + int datasize = c1 + 1; | ||
8927 | + | ||
8928 | +# ifdef _LIBC | ||
8929 | + int32_t idx = 0; | ||
8930 | + if (nrules == 0) | ||
8931 | +# endif | ||
8932 | + { | ||
8933 | + if (c1 != 1) | ||
8934 | + FREE_STACK_RETURN (REG_ECOLLATE); | ||
8935 | + } | ||
8936 | +# ifdef _LIBC | ||
8937 | + else | ||
8938 | + { | ||
8939 | + const int32_t *table; | ||
8940 | + const int32_t *weights; | ||
8941 | + const int32_t *extra; | ||
8942 | + const int32_t *indirect; | ||
8943 | + wint_t *cp; | ||
8944 | + | ||
8945 | + /* This #include defines a local function! */ | ||
8946 | +# include <locale/weightwc.h> | ||
8947 | + | ||
8948 | + if(delim == '=') | ||
8949 | + { | ||
8950 | + /* We push the index for equivalence class. */ | ||
8951 | + cp = (wint_t*)str; | ||
8952 | + | ||
8953 | + table = (const int32_t *) | ||
8954 | + _NL_CURRENT (LC_COLLATE, | ||
8955 | + _NL_COLLATE_TABLEWC); | ||
8956 | + weights = (const int32_t *) | ||
8957 | + _NL_CURRENT (LC_COLLATE, | ||
8958 | + _NL_COLLATE_WEIGHTWC); | ||
8959 | + extra = (const int32_t *) | ||
8960 | + _NL_CURRENT (LC_COLLATE, | ||
8961 | + _NL_COLLATE_EXTRAWC); | ||
8962 | + indirect = (const int32_t *) | ||
8963 | + _NL_CURRENT (LC_COLLATE, | ||
8964 | + _NL_COLLATE_INDIRECTWC); | ||
8965 | + | ||
8966 | + idx = findidx ((const wint_t**)&cp, c1); | ||
8967 | + if (idx == 0 || cp < (wint_t*) str + c1) | ||
8968 | + /* This is no valid character. */ | ||
8969 | + FREE_STACK_RETURN (REG_ECOLLATE); | ||
8970 | + | ||
8971 | + str[0] = (wchar_t)idx; | ||
8972 | + } | ||
8973 | + else /* delim == '.' */ | ||
8974 | + { | ||
8975 | + /* We push collation sequence value | ||
8976 | + for collating symbol. */ | ||
8977 | + int32_t table_size; | ||
8978 | + const int32_t *symb_table; | ||
8979 | + const unsigned char *extra; | ||
8980 | + int32_t idx; | ||
8981 | + int32_t elem; | ||
8982 | + int32_t second; | ||
8983 | + int32_t hash; | ||
8984 | + char char_str[c1]; | ||
8985 | + | ||
8986 | + /* We have to convert the name to a single-byte | ||
8987 | + string. This is possible since the names | ||
8988 | + consist of ASCII characters and the internal | ||
8989 | + representation is UCS4. */ | ||
8990 | + for (i = 0; i < c1; ++i) | ||
8991 | + char_str[i] = str[i]; | ||
8992 | + | ||
8993 | + table_size = | ||
8994 | + _NL_CURRENT_WORD (LC_COLLATE, | ||
8995 | + _NL_COLLATE_SYMB_HASH_SIZEMB); | ||
8996 | + symb_table = (const int32_t *) | ||
8997 | + _NL_CURRENT (LC_COLLATE, | ||
8998 | + _NL_COLLATE_SYMB_TABLEMB); | ||
8999 | + extra = (const unsigned char *) | ||
9000 | + _NL_CURRENT (LC_COLLATE, | ||
9001 | + _NL_COLLATE_SYMB_EXTRAMB); | ||
9002 | + | ||
9003 | + /* Locate the character in the hashing table. */ | ||
9004 | + hash = elem_hash (char_str, c1); | ||
9005 | + | ||
9006 | + idx = 0; | ||
9007 | + elem = hash % table_size; | ||
9008 | + second = hash % (table_size - 2); | ||
9009 | + while (symb_table[2 * elem] != 0) | ||
9010 | + { | ||
9011 | + /* First compare the hashing value. */ | ||
9012 | + if (symb_table[2 * elem] == hash | ||
9013 | + && c1 == extra[symb_table[2 * elem + 1]] | ||
9014 | + && memcmp (char_str, | ||
9015 | + &extra[symb_table[2 * elem + 1] | ||
9016 | + + 1], c1) == 0) | ||
9017 | + { | ||
9018 | + /* Yep, this is the entry. */ | ||
9019 | + idx = symb_table[2 * elem + 1]; | ||
9020 | + idx += 1 + extra[idx]; | ||
9021 | + break; | ||
9022 | + } | ||
9023 | + | ||
9024 | + /* Next entry. */ | ||
9025 | + elem += second; | ||
9026 | + } | ||
9027 | + | ||
9028 | + if (symb_table[2 * elem] != 0) | ||
9029 | + { | ||
9030 | + /* Compute the index of the byte sequence | ||
9031 | + in the table. */ | ||
9032 | + idx += 1 + extra[idx]; | ||
9033 | + /* Adjust for the alignment. */ | ||
9034 | + idx = (idx + 3) & ~3; | ||
9035 | + | ||
9036 | + str[0] = (wchar_t) idx + 4; | ||
9037 | + } | ||
9038 | + else if (symb_table[2 * elem] == 0 && c1 == 1) | ||
9039 | + { | ||
9040 | + /* No valid character. Match it as a | ||
9041 | + single byte character. */ | ||
9042 | + had_char_class = false; | ||
9043 | + BUF_PUSH(str[0]); | ||
9044 | + /* Update the length of characters */ | ||
9045 | + laststart[5]++; | ||
9046 | + range_start = str[0]; | ||
9047 | + | ||
9048 | + /* Throw away the ] at the end of the | ||
9049 | + collating symbol. */ | ||
9050 | + PATFETCH (c); | ||
9051 | + /* exit from the switch block. */ | ||
9052 | + continue; | ||
9053 | + } | ||
9054 | + else | ||
9055 | + FREE_STACK_RETURN (REG_ECOLLATE); | ||
9056 | + } | ||
9057 | + datasize = 1; | ||
9058 | + } | ||
9059 | +# endif | ||
9060 | + /* Throw away the ] at the end of the equivalence | ||
9061 | + class (or collating symbol). */ | ||
9062 | + PATFETCH (c); | ||
9063 | + | ||
9064 | + /* Allocate the space for the equivalence class | ||
9065 | + (or collating symbol) (and '\0' if needed). */ | ||
9066 | + GET_BUFFER_SPACE(datasize); | ||
9067 | + /* Update the pointer to indicate end of buffer. */ | ||
9068 | + b += datasize; | ||
9069 | + | ||
9070 | + if (delim == '=') | ||
9071 | + { /* equivalence class */ | ||
9072 | + /* Calculate the offset of char_ranges, | ||
9073 | + which is next to equivalence_classes. */ | ||
9074 | + offset = laststart[1] + laststart[2] | ||
9075 | + + laststart[3] +6; | ||
9076 | + /* Insert space. */ | ||
9077 | + insert_space(datasize, laststart + offset, b - 1); | ||
9078 | + | ||
9079 | + /* Write the equivalence_class and \0. */ | ||
9080 | + for (i = 0 ; i < datasize ; i++) | ||
9081 | + laststart[offset + i] = str[i]; | ||
9082 | + | ||
9083 | + /* Update the length of equivalence_classes. */ | ||
9084 | + laststart[3] += datasize; | ||
9085 | + had_char_class = true; | ||
9086 | + } | ||
9087 | + else /* delim == '.' */ | ||
9088 | + { /* collating symbol */ | ||
9089 | + /* Calculate the offset of the equivalence_classes, | ||
9090 | + which is next to collating_symbols. */ | ||
9091 | + offset = laststart[1] + laststart[2] + 6; | ||
9092 | + /* Insert space and write the collationg_symbol | ||
9093 | + and \0. */ | ||
9094 | + insert_space(datasize, laststart + offset, b-1); | ||
9095 | + for (i = 0 ; i < datasize ; i++) | ||
9096 | + laststart[offset + i] = str[i]; | ||
9097 | + | ||
9098 | + /* In re_match_2_internal if range_start < -1, we | ||
9099 | + assume -range_start is the offset of the | ||
9100 | + collating symbol which is specified as | ||
9101 | + the character of the range start. So we assign | ||
9102 | + -(laststart[1] + laststart[2] + 6) to | ||
9103 | + range_start. */ | ||
9104 | + range_start = -(laststart[1] + laststart[2] + 6); | ||
9105 | + /* Update the length of collating_symbol. */ | ||
9106 | + laststart[2] += datasize; | ||
9107 | + had_char_class = false; | ||
9108 | + } | ||
9109 | + } | ||
9110 | + else | ||
9111 | + { | ||
9112 | + c1++; | ||
9113 | + while (c1--) | ||
9114 | + PATUNFETCH; | ||
9115 | + BUF_PUSH ('['); | ||
9116 | + BUF_PUSH (delim); | ||
9117 | + laststart[5] += 2; /* Update the length of characters */ | ||
9118 | + range_start = delim; | ||
9119 | + had_char_class = false; | ||
9120 | + } | ||
9121 | + } | ||
9122 | + else | ||
9123 | + { | ||
9124 | + had_char_class = false; | ||
9125 | + BUF_PUSH(c); | ||
9126 | + laststart[5]++; /* Update the length of characters */ | ||
9127 | + range_start = c; | ||
9128 | + } | ||
9129 | + } | ||
9130 | + | ||
9131 | +#else /* BYTE */ | ||
9132 | + /* Ensure that we have enough space to push a charset: the | ||
9133 | + opcode, the length count, and the bitset; 34 bytes in all. */ | ||
9134 | + GET_BUFFER_SPACE (34); | ||
9135 | + | ||
9136 | + laststart = b; | ||
9137 | + | ||
9138 | + /* We test `*p == '^' twice, instead of using an if | ||
9139 | + statement, so we only need one BUF_PUSH. */ | ||
9140 | + BUF_PUSH (*p == '^' ? charset_not : charset); | ||
9141 | + if (*p == '^') | ||
9142 | + p++; | ||
9143 | + | ||
9144 | + /* Remember the first position in the bracket expression. */ | ||
9145 | + p1 = p; | ||
9146 | + | ||
9147 | + /* Push the number of bytes in the bitmap. */ | ||
9148 | + BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); | ||
9149 | + | ||
9150 | + /* Clear the whole map. */ | ||
9151 | + bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); | ||
9152 | + | ||
9153 | + /* charset_not matches newline according to a syntax bit. */ | ||
9154 | + if ((re_opcode_t) b[-2] == charset_not | ||
9155 | + && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) | ||
9156 | + SET_LIST_BIT ('\n'); | ||
9157 | + | ||
9158 | + /* Read in characters and ranges, setting map bits. */ | ||
9159 | + for (;;) | ||
9160 | + { | ||
9161 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
9162 | + | ||
9163 | + PATFETCH (c); | ||
9164 | + | ||
9165 | + /* \ might escape characters inside [...] and [^...]. */ | ||
9166 | + if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') | ||
9167 | + { | ||
9168 | + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); | ||
9169 | + | ||
9170 | + PATFETCH (c1); | ||
9171 | + SET_LIST_BIT (c1); | ||
9172 | + range_start = c1; | ||
9173 | + continue; | ||
9174 | + } | ||
9175 | + | ||
9176 | + /* Could be the end of the bracket expression. If it's | ||
9177 | + not (i.e., when the bracket expression is `[]' so | ||
9178 | + far), the ']' character bit gets set way below. */ | ||
9179 | + if (c == ']' && p != p1 + 1) | ||
9180 | + break; | ||
9181 | + | ||
9182 | + /* Look ahead to see if it's a range when the last thing | ||
9183 | + was a character class. */ | ||
9184 | + if (had_char_class && c == '-' && *p != ']') | ||
9185 | + FREE_STACK_RETURN (REG_ERANGE); | ||
9186 | + | ||
9187 | + /* Look ahead to see if it's a range when the last thing | ||
9188 | + was a character: if this is a hyphen not at the | ||
9189 | + beginning or the end of a list, then it's the range | ||
9190 | + operator. */ | ||
9191 | + if (c == '-' | ||
9192 | + && !(p - 2 >= pattern && p[-2] == '[') | ||
9193 | + && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') | ||
9194 | + && *p != ']') | ||
9195 | + { | ||
9196 | + reg_errcode_t ret | ||
9197 | + = byte_compile_range (range_start, &p, pend, translate, | ||
9198 | + syntax, b); | ||
9199 | + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); | ||
9200 | + range_start = 0xffffffff; | ||
9201 | + } | ||
9202 | + | ||
9203 | + else if (p[0] == '-' && p[1] != ']') | ||
9204 | + { /* This handles ranges made up of characters only. */ | ||
9205 | + reg_errcode_t ret; | ||
9206 | + | ||
9207 | + /* Move past the `-'. */ | ||
9208 | + PATFETCH (c1); | ||
9209 | + | ||
9210 | + ret = byte_compile_range (c, &p, pend, translate, syntax, b); | ||
9211 | + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); | ||
9212 | + range_start = 0xffffffff; | ||
9213 | + } | ||
9214 | + | ||
9215 | + /* See if we're at the beginning of a possible character | ||
9216 | + class. */ | ||
9217 | + | ||
9218 | + else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') | ||
9219 | + { /* Leave room for the null. */ | ||
9220 | + char str[CHAR_CLASS_MAX_LENGTH + 1]; | ||
9221 | + | ||
9222 | + PATFETCH (c); | ||
9223 | + c1 = 0; | ||
9224 | + | ||
9225 | + /* If pattern is `[[:'. */ | ||
9226 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
9227 | + | ||
9228 | + for (;;) | ||
9229 | + { | ||
9230 | + PATFETCH (c); | ||
9231 | + if ((c == ':' && *p == ']') || p == pend) | ||
9232 | + break; | ||
9233 | + if (((int) c1) < CHAR_CLASS_MAX_LENGTH) | ||
9234 | + str[c1++] = c; | ||
9235 | + else | ||
9236 | + /* This is in any case an invalid class name. */ | ||
9237 | + str[0] = '\0'; | ||
9238 | + } | ||
9239 | + str[c1] = '\0'; | ||
9240 | + | ||
9241 | + /* If isn't a word bracketed by `[:' and `:]': | ||
9242 | + undo the ending character, the letters, and leave | ||
9243 | + the leading `:' and `[' (but set bits for them). */ | ||
9244 | + if (c == ':' && *p == ']') | ||
9245 | + { | ||
9246 | +# if WIDE_CHAR_SUPPORT | ||
9247 | + boolean is_lower = STREQ (str, "lower"); | ||
9248 | + boolean is_upper = STREQ (str, "upper"); | ||
9249 | + wctype_t wt; | ||
9250 | + int ch; | ||
9251 | + | ||
9252 | + wt = IS_CHAR_CLASS (str); | ||
9253 | + if (wt == 0) | ||
9254 | + FREE_STACK_RETURN (REG_ECTYPE); | ||
9255 | + | ||
9256 | + /* Throw away the ] at the end of the character | ||
9257 | + class. */ | ||
9258 | + PATFETCH (c); | ||
9259 | + | ||
9260 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
9261 | + | ||
9262 | + for (ch = 0; ch < 1 << BYTEWIDTH; ++ch) | ||
9263 | + { | ||
9264 | +# ifdef _LIBC | ||
9265 | + if (__iswctype (__btowc (ch), wt)) | ||
9266 | + SET_LIST_BIT (ch); | ||
9267 | +# else | ||
9268 | + if (iswctype (btowc (ch), wt)) | ||
9269 | + SET_LIST_BIT (ch); | ||
9270 | +# endif | ||
9271 | + | ||
9272 | + if (translate && (is_upper || is_lower) | ||
9273 | + && (ISUPPER (ch) || ISLOWER (ch))) | ||
9274 | + SET_LIST_BIT (ch); | ||
9275 | + } | ||
9276 | + | ||
9277 | + had_char_class = true; | ||
9278 | +# else | ||
9279 | + int ch; | ||
9280 | + boolean is_alnum = STREQ (str, "alnum"); | ||
9281 | + boolean is_alpha = STREQ (str, "alpha"); | ||
9282 | + boolean is_blank = STREQ (str, "blank"); | ||
9283 | + boolean is_cntrl = STREQ (str, "cntrl"); | ||
9284 | + boolean is_digit = STREQ (str, "digit"); | ||
9285 | + boolean is_graph = STREQ (str, "graph"); | ||
9286 | + boolean is_lower = STREQ (str, "lower"); | ||
9287 | + boolean is_print = STREQ (str, "print"); | ||
9288 | + boolean is_punct = STREQ (str, "punct"); | ||
9289 | + boolean is_space = STREQ (str, "space"); | ||
9290 | + boolean is_upper = STREQ (str, "upper"); | ||
9291 | + boolean is_xdigit = STREQ (str, "xdigit"); | ||
9292 | + | ||
9293 | + if (!IS_CHAR_CLASS (str)) | ||
9294 | + FREE_STACK_RETURN (REG_ECTYPE); | ||
9295 | + | ||
9296 | + /* Throw away the ] at the end of the character | ||
9297 | + class. */ | ||
9298 | + PATFETCH (c); | ||
9299 | + | ||
9300 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
9301 | + | ||
9302 | + for (ch = 0; ch < 1 << BYTEWIDTH; ch++) | ||
9303 | + { | ||
9304 | + /* This was split into 3 if's to | ||
9305 | + avoid an arbitrary limit in some compiler. */ | ||
9306 | + if ( (is_alnum && ISALNUM (ch)) | ||
9307 | + || (is_alpha && ISALPHA (ch)) | ||
9308 | + || (is_blank && ISBLANK (ch)) | ||
9309 | + || (is_cntrl && ISCNTRL (ch))) | ||
9310 | + SET_LIST_BIT (ch); | ||
9311 | + if ( (is_digit && ISDIGIT (ch)) | ||
9312 | + || (is_graph && ISGRAPH (ch)) | ||
9313 | + || (is_lower && ISLOWER (ch)) | ||
9314 | + || (is_print && ISPRINT (ch))) | ||
9315 | + SET_LIST_BIT (ch); | ||
9316 | + if ( (is_punct && ISPUNCT (ch)) | ||
9317 | + || (is_space && ISSPACE (ch)) | ||
9318 | + || (is_upper && ISUPPER (ch)) | ||
9319 | + || (is_xdigit && ISXDIGIT (ch))) | ||
9320 | + SET_LIST_BIT (ch); | ||
9321 | + if ( translate && (is_upper || is_lower) | ||
9322 | + && (ISUPPER (ch) || ISLOWER (ch))) | ||
9323 | + SET_LIST_BIT (ch); | ||
9324 | + } | ||
9325 | + had_char_class = true; | ||
9326 | +# endif /* libc || wctype.h */ | ||
9327 | + } | ||
9328 | + else | ||
9329 | + { | ||
9330 | + c1++; | ||
9331 | + while (c1--) | ||
9332 | + PATUNFETCH; | ||
9333 | + SET_LIST_BIT ('['); | ||
9334 | + SET_LIST_BIT (':'); | ||
9335 | + range_start = ':'; | ||
9336 | + had_char_class = false; | ||
9337 | + } | ||
9338 | + } | ||
9339 | + else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '=') | ||
9340 | + { | ||
9341 | + unsigned char str[MB_LEN_MAX + 1]; | ||
9342 | +# ifdef _LIBC | ||
9343 | + uint32_t nrules = | ||
9344 | + _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); | ||
9345 | +# endif | ||
9346 | + | ||
9347 | + PATFETCH (c); | ||
9348 | + c1 = 0; | ||
9349 | + | ||
9350 | + /* If pattern is `[[='. */ | ||
9351 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
9352 | + | ||
9353 | + for (;;) | ||
9354 | + { | ||
9355 | + PATFETCH (c); | ||
9356 | + if ((c == '=' && *p == ']') || p == pend) | ||
9357 | + break; | ||
9358 | + if (c1 < MB_LEN_MAX) | ||
9359 | + str[c1++] = c; | ||
9360 | + else | ||
9361 | + /* This is in any case an invalid class name. */ | ||
9362 | + str[0] = '\0'; | ||
9363 | + } | ||
9364 | + str[c1] = '\0'; | ||
9365 | + | ||
9366 | + if (c == '=' && *p == ']' && str[0] != '\0') | ||
9367 | + { | ||
9368 | + /* If we have no collation data we use the default | ||
9369 | + collation in which each character is in a class | ||
9370 | + by itself. It also means that ASCII is the | ||
9371 | + character set and therefore we cannot have character | ||
9372 | + with more than one byte in the multibyte | ||
9373 | + representation. */ | ||
9374 | +# ifdef _LIBC | ||
9375 | + if (nrules == 0) | ||
9376 | +# endif | ||
9377 | + { | ||
9378 | + if (c1 != 1) | ||
9379 | + FREE_STACK_RETURN (REG_ECOLLATE); | ||
9380 | + | ||
9381 | + /* Throw away the ] at the end of the equivalence | ||
9382 | + class. */ | ||
9383 | + PATFETCH (c); | ||
9384 | + | ||
9385 | + /* Set the bit for the character. */ | ||
9386 | + SET_LIST_BIT (str[0]); | ||
9387 | + } | ||
9388 | +# ifdef _LIBC | ||
9389 | + else | ||
9390 | + { | ||
9391 | + /* Try to match the byte sequence in `str' against | ||
9392 | + those known to the collate implementation. | ||
9393 | + First find out whether the bytes in `str' are | ||
9394 | + actually from exactly one character. */ | ||
9395 | + const int32_t *table; | ||
9396 | + const unsigned char *weights; | ||
9397 | + const unsigned char *extra; | ||
9398 | + const int32_t *indirect; | ||
9399 | + int32_t idx; | ||
9400 | + const unsigned char *cp = str; | ||
9401 | + int ch; | ||
9402 | + | ||
9403 | + /* This #include defines a local function! */ | ||
9404 | +# include <locale/weight.h> | ||
9405 | + | ||
9406 | + table = (const int32_t *) | ||
9407 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); | ||
9408 | + weights = (const unsigned char *) | ||
9409 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); | ||
9410 | + extra = (const unsigned char *) | ||
9411 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); | ||
9412 | + indirect = (const int32_t *) | ||
9413 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); | ||
9414 | + | ||
9415 | + idx = findidx (&cp, c1); | ||
9416 | + if (idx == 0 || cp < str + c1) | ||
9417 | + /* This is no valid character. */ | ||
9418 | + FREE_STACK_RETURN (REG_ECOLLATE); | ||
9419 | + | ||
9420 | + /* Throw away the ] at the end of the equivalence | ||
9421 | + class. */ | ||
9422 | + PATFETCH (c); | ||
9423 | + | ||
9424 | + /* Now we have to go throught the whole table | ||
9425 | + and find all characters which have the same | ||
9426 | + first level weight. | ||
9427 | + | ||
9428 | + XXX Note that this is not entirely correct. | ||
9429 | + we would have to match multibyte sequences | ||
9430 | + but this is not possible with the current | ||
9431 | + implementation. */ | ||
9432 | + for (ch = 1; ch < 256; ++ch) | ||
9433 | + /* XXX This test would have to be changed if we | ||
9434 | + would allow matching multibyte sequences. */ | ||
9435 | + if (table[ch] > 0) | ||
9436 | + { | ||
9437 | + int32_t idx2 = table[ch]; | ||
9438 | + size_t len = weights[idx2]; | ||
9439 | + | ||
9440 | + /* Test whether the lenghts match. */ | ||
9441 | + if (weights[idx] == len) | ||
9442 | + { | ||
9443 | + /* They do. New compare the bytes of | ||
9444 | + the weight. */ | ||
9445 | + size_t cnt = 0; | ||
9446 | + | ||
9447 | + while (cnt < len | ||
9448 | + && (weights[idx + 1 + cnt] | ||
9449 | + == weights[idx2 + 1 + cnt])) | ||
9450 | + ++cnt; | ||
9451 | + | ||
9452 | + if (cnt == len) | ||
9453 | + /* They match. Mark the character as | ||
9454 | + acceptable. */ | ||
9455 | + SET_LIST_BIT (ch); | ||
9456 | + } | ||
9457 | + } | ||
9458 | + } | ||
9459 | +# endif | ||
9460 | + had_char_class = true; | ||
9461 | + } | ||
9462 | + else | ||
9463 | + { | ||
9464 | + c1++; | ||
9465 | + while (c1--) | ||
9466 | + PATUNFETCH; | ||
9467 | + SET_LIST_BIT ('['); | ||
9468 | + SET_LIST_BIT ('='); | ||
9469 | + range_start = '='; | ||
9470 | + had_char_class = false; | ||
9471 | + } | ||
9472 | + } | ||
9473 | + else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '.') | ||
9474 | + { | ||
9475 | + unsigned char str[128]; /* Should be large enough. */ | ||
9476 | +# ifdef _LIBC | ||
9477 | + uint32_t nrules = | ||
9478 | + _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); | ||
9479 | +# endif | ||
9480 | + | ||
9481 | + PATFETCH (c); | ||
9482 | + c1 = 0; | ||
9483 | + | ||
9484 | + /* If pattern is `[[.'. */ | ||
9485 | + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); | ||
9486 | + | ||
9487 | + for (;;) | ||
9488 | + { | ||
9489 | + PATFETCH (c); | ||
9490 | + if ((c == '.' && *p == ']') || p == pend) | ||
9491 | + break; | ||
9492 | + if (c1 < sizeof (str)) | ||
9493 | + str[c1++] = c; | ||
9494 | + else | ||
9495 | + /* This is in any case an invalid class name. */ | ||
9496 | + str[0] = '\0'; | ||
9497 | + } | ||
9498 | + str[c1] = '\0'; | ||
9499 | + | ||
9500 | + if (c == '.' && *p == ']' && str[0] != '\0') | ||
9501 | + { | ||
9502 | + /* If we have no collation data we use the default | ||
9503 | + collation in which each character is the name | ||
9504 | + for its own class which contains only the one | ||
9505 | + character. It also means that ASCII is the | ||
9506 | + character set and therefore we cannot have character | ||
9507 | + with more than one byte in the multibyte | ||
9508 | + representation. */ | ||
9509 | +# ifdef _LIBC | ||
9510 | + if (nrules == 0) | ||
9511 | +# endif | ||
9512 | + { | ||
9513 | + if (c1 != 1) | ||
9514 | + FREE_STACK_RETURN (REG_ECOLLATE); | ||
9515 | + | ||
9516 | + /* Throw away the ] at the end of the equivalence | ||
9517 | + class. */ | ||
9518 | + PATFETCH (c); | ||
9519 | + | ||
9520 | + /* Set the bit for the character. */ | ||
9521 | + SET_LIST_BIT (str[0]); | ||
9522 | + range_start = ((const unsigned char *) str)[0]; | ||
9523 | + } | ||
9524 | +# ifdef _LIBC | ||
9525 | + else | ||
9526 | + { | ||
9527 | + /* Try to match the byte sequence in `str' against | ||
9528 | + those known to the collate implementation. | ||
9529 | + First find out whether the bytes in `str' are | ||
9530 | + actually from exactly one character. */ | ||
9531 | + int32_t table_size; | ||
9532 | + const int32_t *symb_table; | ||
9533 | + const unsigned char *extra; | ||
9534 | + int32_t idx; | ||
9535 | + int32_t elem; | ||
9536 | + int32_t second; | ||
9537 | + int32_t hash; | ||
9538 | + | ||
9539 | + table_size = | ||
9540 | + _NL_CURRENT_WORD (LC_COLLATE, | ||
9541 | + _NL_COLLATE_SYMB_HASH_SIZEMB); | ||
9542 | + symb_table = (const int32_t *) | ||
9543 | + _NL_CURRENT (LC_COLLATE, | ||
9544 | + _NL_COLLATE_SYMB_TABLEMB); | ||
9545 | + extra = (const unsigned char *) | ||
9546 | + _NL_CURRENT (LC_COLLATE, | ||
9547 | + _NL_COLLATE_SYMB_EXTRAMB); | ||
9548 | + | ||
9549 | + /* Locate the character in the hashing table. */ | ||
9550 | + hash = elem_hash ((const char *) str, c1); | ||
9551 | + | ||
9552 | + idx = 0; | ||
9553 | + elem = hash % table_size; | ||
9554 | + second = hash % (table_size - 2); | ||
9555 | + while (symb_table[2 * elem] != 0) | ||
9556 | + { | ||
9557 | + /* First compare the hashing value. */ | ||
9558 | + if (symb_table[2 * elem] == hash | ||
9559 | + && c1 == extra[symb_table[2 * elem + 1]] | ||
9560 | + && memcmp (str, | ||
9561 | + &extra[symb_table[2 * elem + 1] | ||
9562 | + + 1], | ||
9563 | + c1) == 0) | ||
9564 | + { | ||
9565 | + /* Yep, this is the entry. */ | ||
9566 | + idx = symb_table[2 * elem + 1]; | ||
9567 | + idx += 1 + extra[idx]; | ||
9568 | + break; | ||
9569 | + } | ||
9570 | + | ||
9571 | + /* Next entry. */ | ||
9572 | + elem += second; | ||
9573 | + } | ||
9574 | + | ||
9575 | + if (symb_table[2 * elem] == 0) | ||
9576 | + /* This is no valid character. */ | ||
9577 | + FREE_STACK_RETURN (REG_ECOLLATE); | ||
9578 | + | ||
9579 | + /* Throw away the ] at the end of the equivalence | ||
9580 | + class. */ | ||
9581 | + PATFETCH (c); | ||
9582 | + | ||
9583 | + /* Now add the multibyte character(s) we found | ||
9584 | + to the accept list. | ||
9585 | + | ||
9586 | + XXX Note that this is not entirely correct. | ||
9587 | + we would have to match multibyte sequences | ||
9588 | + but this is not possible with the current | ||
9589 | + implementation. Also, we have to match | ||
9590 | + collating symbols, which expand to more than | ||
9591 | + one file, as a whole and not allow the | ||
9592 | + individual bytes. */ | ||
9593 | + c1 = extra[idx++]; | ||
9594 | + if (c1 == 1) | ||
9595 | + range_start = extra[idx]; | ||
9596 | + while (c1-- > 0) | ||
9597 | + { | ||
9598 | + SET_LIST_BIT (extra[idx]); | ||
9599 | + ++idx; | ||
9600 | + } | ||
9601 | + } | ||
9602 | +# endif | ||
9603 | + had_char_class = false; | ||
9604 | + } | ||
9605 | + else | ||
9606 | + { | ||
9607 | + c1++; | ||
9608 | + while (c1--) | ||
9609 | + PATUNFETCH; | ||
9610 | + SET_LIST_BIT ('['); | ||
9611 | + SET_LIST_BIT ('.'); | ||
9612 | + range_start = '.'; | ||
9613 | + had_char_class = false; | ||
9614 | + } | ||
9615 | + } | ||
9616 | + else | ||
9617 | + { | ||
9618 | + had_char_class = false; | ||
9619 | + SET_LIST_BIT (c); | ||
9620 | + range_start = c; | ||
9621 | + } | ||
9622 | + } | ||
9623 | + | ||
9624 | + /* Discard any (non)matching list bytes that are all 0 at the | ||
9625 | + end of the map. Decrease the map-length byte too. */ | ||
9626 | + while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) | ||
9627 | + b[-1]--; | ||
9628 | + b += b[-1]; | ||
9629 | +#endif /* WCHAR */ | ||
9630 | + } | ||
9631 | + break; | ||
9632 | + | ||
9633 | + | ||
9634 | + case '(': | ||
9635 | + if (syntax & RE_NO_BK_PARENS) | ||
9636 | + goto handle_open; | ||
9637 | + else | ||
9638 | + goto normal_char; | ||
9639 | + | ||
9640 | + | ||
9641 | + case ')': | ||
9642 | + if (syntax & RE_NO_BK_PARENS) | ||
9643 | + goto handle_close; | ||
9644 | + else | ||
9645 | + goto normal_char; | ||
9646 | + | ||
9647 | + | ||
9648 | + case '\n': | ||
9649 | + if (syntax & RE_NEWLINE_ALT) | ||
9650 | + goto handle_alt; | ||
9651 | + else | ||
9652 | + goto normal_char; | ||
9653 | + | ||
9654 | + | ||
9655 | + case '|': | ||
9656 | + if (syntax & RE_NO_BK_VBAR) | ||
9657 | + goto handle_alt; | ||
9658 | + else | ||
9659 | + goto normal_char; | ||
9660 | + | ||
9661 | + | ||
9662 | + case '{': | ||
9663 | + if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) | ||
9664 | + goto handle_interval; | ||
9665 | + else | ||
9666 | + goto normal_char; | ||
9667 | + | ||
9668 | + | ||
9669 | + case '\\': | ||
9670 | + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); | ||
9671 | + | ||
9672 | + /* Do not translate the character after the \, so that we can | ||
9673 | + distinguish, e.g., \B from \b, even if we normally would | ||
9674 | + translate, e.g., B to b. */ | ||
9675 | + PATFETCH_RAW (c); | ||
9676 | + | ||
9677 | + switch (c) | ||
9678 | + { | ||
9679 | + case '(': | ||
9680 | + if (syntax & RE_NO_BK_PARENS) | ||
9681 | + goto normal_backslash; | ||
9682 | + | ||
9683 | + handle_open: | ||
9684 | + bufp->re_nsub++; | ||
9685 | + regnum++; | ||
9686 | + | ||
9687 | + if (COMPILE_STACK_FULL) | ||
9688 | + { | ||
9689 | + RETALLOC (compile_stack.stack, compile_stack.size << 1, | ||
9690 | + compile_stack_elt_t); | ||
9691 | + if (compile_stack.stack == NULL) return REG_ESPACE; | ||
9692 | + | ||
9693 | + compile_stack.size <<= 1; | ||
9694 | + } | ||
9695 | + | ||
9696 | + /* These are the values to restore when we hit end of this | ||
9697 | + group. They are all relative offsets, so that if the | ||
9698 | + whole pattern moves because of realloc, they will still | ||
9699 | + be valid. */ | ||
9700 | + COMPILE_STACK_TOP.begalt_offset = begalt - COMPILED_BUFFER_VAR; | ||
9701 | + COMPILE_STACK_TOP.fixup_alt_jump | ||
9702 | + = fixup_alt_jump ? fixup_alt_jump - COMPILED_BUFFER_VAR + 1 : 0; | ||
9703 | + COMPILE_STACK_TOP.laststart_offset = b - COMPILED_BUFFER_VAR; | ||
9704 | + COMPILE_STACK_TOP.regnum = regnum; | ||
9705 | + | ||
9706 | + /* We will eventually replace the 0 with the number of | ||
9707 | + groups inner to this one. But do not push a | ||
9708 | + start_memory for groups beyond the last one we can | ||
9709 | + represent in the compiled pattern. */ | ||
9710 | + if (regnum <= MAX_REGNUM) | ||
9711 | + { | ||
9712 | + COMPILE_STACK_TOP.inner_group_offset = b | ||
9713 | + - COMPILED_BUFFER_VAR + 2; | ||
9714 | + BUF_PUSH_3 (start_memory, regnum, 0); | ||
9715 | + } | ||
9716 | + | ||
9717 | + compile_stack.avail++; | ||
9718 | + | ||
9719 | + fixup_alt_jump = 0; | ||
9720 | + laststart = 0; | ||
9721 | + begalt = b; | ||
9722 | + /* If we've reached MAX_REGNUM groups, then this open | ||
9723 | + won't actually generate any code, so we'll have to | ||
9724 | + clear pending_exact explicitly. */ | ||
9725 | + pending_exact = 0; | ||
9726 | + break; | ||
9727 | + | ||
9728 | + | ||
9729 | + case ')': | ||
9730 | + if (syntax & RE_NO_BK_PARENS) goto normal_backslash; | ||
9731 | + | ||
9732 | + if (COMPILE_STACK_EMPTY) | ||
9733 | + { | ||
9734 | + if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) | ||
9735 | + goto normal_backslash; | ||
9736 | + else | ||
9737 | + FREE_STACK_RETURN (REG_ERPAREN); | ||
9738 | + } | ||
9739 | + | ||
9740 | + handle_close: | ||
9741 | + if (fixup_alt_jump) | ||
9742 | + { /* Push a dummy failure point at the end of the | ||
9743 | + alternative for a possible future | ||
9744 | + `pop_failure_jump' to pop. See comments at | ||
9745 | + `push_dummy_failure' in `re_match_2'. */ | ||
9746 | + BUF_PUSH (push_dummy_failure); | ||
9747 | + | ||
9748 | + /* We allocated space for this jump when we assigned | ||
9749 | + to `fixup_alt_jump', in the `handle_alt' case below. */ | ||
9750 | + STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); | ||
9751 | + } | ||
9752 | + | ||
9753 | + /* See similar code for backslashed left paren above. */ | ||
9754 | + if (COMPILE_STACK_EMPTY) | ||
9755 | + { | ||
9756 | + if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) | ||
9757 | + goto normal_char; | ||
9758 | + else | ||
9759 | + FREE_STACK_RETURN (REG_ERPAREN); | ||
9760 | + } | ||
9761 | + | ||
9762 | + /* Since we just checked for an empty stack above, this | ||
9763 | + ``can't happen''. */ | ||
9764 | + assert (compile_stack.avail != 0); | ||
9765 | + { | ||
9766 | + /* We don't just want to restore into `regnum', because | ||
9767 | + later groups should continue to be numbered higher, | ||
9768 | + as in `(ab)c(de)' -- the second group is #2. */ | ||
9769 | + regnum_t this_group_regnum; | ||
9770 | + | ||
9771 | + compile_stack.avail--; | ||
9772 | + begalt = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.begalt_offset; | ||
9773 | + fixup_alt_jump | ||
9774 | + = COMPILE_STACK_TOP.fixup_alt_jump | ||
9775 | + ? COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.fixup_alt_jump - 1 | ||
9776 | + : 0; | ||
9777 | + laststart = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.laststart_offset; | ||
9778 | + this_group_regnum = COMPILE_STACK_TOP.regnum; | ||
9779 | + /* If we've reached MAX_REGNUM groups, then this open | ||
9780 | + won't actually generate any code, so we'll have to | ||
9781 | + clear pending_exact explicitly. */ | ||
9782 | + pending_exact = 0; | ||
9783 | + | ||
9784 | + /* We're at the end of the group, so now we know how many | ||
9785 | + groups were inside this one. */ | ||
9786 | + if (this_group_regnum <= MAX_REGNUM) | ||
9787 | + { | ||
9788 | + UCHAR_T *inner_group_loc | ||
9789 | + = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.inner_group_offset; | ||
9790 | + | ||
9791 | + *inner_group_loc = regnum - this_group_regnum; | ||
9792 | + BUF_PUSH_3 (stop_memory, this_group_regnum, | ||
9793 | + regnum - this_group_regnum); | ||
9794 | + } | ||
9795 | + } | ||
9796 | + break; | ||
9797 | + | ||
9798 | + | ||
9799 | + case '|': /* `\|'. */ | ||
9800 | + if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) | ||
9801 | + goto normal_backslash; | ||
9802 | + handle_alt: | ||
9803 | + if (syntax & RE_LIMITED_OPS) | ||
9804 | + goto normal_char; | ||
9805 | + | ||
9806 | + /* Insert before the previous alternative a jump which | ||
9807 | + jumps to this alternative if the former fails. */ | ||
9808 | + GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE); | ||
9809 | + INSERT_JUMP (on_failure_jump, begalt, | ||
9810 | + b + 2 + 2 * OFFSET_ADDRESS_SIZE); | ||
9811 | + pending_exact = 0; | ||
9812 | + b += 1 + OFFSET_ADDRESS_SIZE; | ||
9813 | + | ||
9814 | + /* The alternative before this one has a jump after it | ||
9815 | + which gets executed if it gets matched. Adjust that | ||
9816 | + jump so it will jump to this alternative's analogous | ||
9817 | + jump (put in below, which in turn will jump to the next | ||
9818 | + (if any) alternative's such jump, etc.). The last such | ||
9819 | + jump jumps to the correct final destination. A picture: | ||
9820 | + _____ _____ | ||
9821 | + | | | | | ||
9822 | + | v | v | ||
9823 | + a | b | c | ||
9824 | + | ||
9825 | + If we are at `b', then fixup_alt_jump right now points to a | ||
9826 | + three-byte space after `a'. We'll put in the jump, set | ||
9827 | + fixup_alt_jump to right after `b', and leave behind three | ||
9828 | + bytes which we'll fill in when we get to after `c'. */ | ||
9829 | + | ||
9830 | + if (fixup_alt_jump) | ||
9831 | + STORE_JUMP (jump_past_alt, fixup_alt_jump, b); | ||
9832 | + | ||
9833 | + /* Mark and leave space for a jump after this alternative, | ||
9834 | + to be filled in later either by next alternative or | ||
9835 | + when know we're at the end of a series of alternatives. */ | ||
9836 | + fixup_alt_jump = b; | ||
9837 | + GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE); | ||
9838 | + b += 1 + OFFSET_ADDRESS_SIZE; | ||
9839 | + | ||
9840 | + laststart = 0; | ||
9841 | + begalt = b; | ||
9842 | + break; | ||
9843 | + | ||
9844 | + | ||
9845 | + case '{': | ||
9846 | + /* If \{ is a literal. */ | ||
9847 | + if (!(syntax & RE_INTERVALS) | ||
9848 | + /* If we're at `\{' and it's not the open-interval | ||
9849 | + operator. */ | ||
9850 | + || (syntax & RE_NO_BK_BRACES)) | ||
9851 | + goto normal_backslash; | ||
9852 | + | ||
9853 | + handle_interval: | ||
9854 | + { | ||
9855 | + /* If got here, then the syntax allows intervals. */ | ||
9856 | + | ||
9857 | + /* At least (most) this many matches must be made. */ | ||
9858 | + int lower_bound = -1, upper_bound = -1; | ||
9859 | + | ||
9860 | + /* Place in the uncompiled pattern (i.e., just after | ||
9861 | + the '{') to go back to if the interval is invalid. */ | ||
9862 | + const CHAR_T *beg_interval = p; | ||
9863 | + | ||
9864 | + if (p == pend) | ||
9865 | + goto invalid_interval; | ||
9866 | + | ||
9867 | + GET_UNSIGNED_NUMBER (lower_bound); | ||
9868 | + | ||
9869 | + if (c == ',') | ||
9870 | + { | ||
9871 | + GET_UNSIGNED_NUMBER (upper_bound); | ||
9872 | + if (upper_bound < 0) | ||
9873 | + upper_bound = RE_DUP_MAX; | ||
9874 | + } | ||
9875 | + else | ||
9876 | + /* Interval such as `{1}' => match exactly once. */ | ||
9877 | + upper_bound = lower_bound; | ||
9878 | + | ||
9879 | + if (! (0 <= lower_bound && lower_bound <= upper_bound)) | ||
9880 | + goto invalid_interval; | ||
9881 | + | ||
9882 | + if (!(syntax & RE_NO_BK_BRACES)) | ||
9883 | + { | ||
9884 | + if (c != '\\' || p == pend) | ||
9885 | + goto invalid_interval; | ||
9886 | + PATFETCH (c); | ||
9887 | + } | ||
9888 | + | ||
9889 | + if (c != '}') | ||
9890 | + goto invalid_interval; | ||
9891 | + | ||
9892 | + /* If it's invalid to have no preceding re. */ | ||
9893 | + if (!laststart) | ||
9894 | + { | ||
9895 | + if (syntax & RE_CONTEXT_INVALID_OPS | ||
9896 | + && !(syntax & RE_INVALID_INTERVAL_ORD)) | ||
9897 | + FREE_STACK_RETURN (REG_BADRPT); | ||
9898 | + else if (syntax & RE_CONTEXT_INDEP_OPS) | ||
9899 | + laststart = b; | ||
9900 | + else | ||
9901 | + goto unfetch_interval; | ||
9902 | + } | ||
9903 | + | ||
9904 | + /* We just parsed a valid interval. */ | ||
9905 | + | ||
9906 | + if (RE_DUP_MAX < upper_bound) | ||
9907 | + FREE_STACK_RETURN (REG_BADBR); | ||
9908 | + | ||
9909 | + /* If the upper bound is zero, don't want to succeed at | ||
9910 | + all; jump from `laststart' to `b + 3', which will be | ||
9911 | + the end of the buffer after we insert the jump. */ | ||
9912 | + /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE' | ||
9913 | + instead of 'b + 3'. */ | ||
9914 | + if (upper_bound == 0) | ||
9915 | + { | ||
9916 | + GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE); | ||
9917 | + INSERT_JUMP (jump, laststart, b + 1 | ||
9918 | + + OFFSET_ADDRESS_SIZE); | ||
9919 | + b += 1 + OFFSET_ADDRESS_SIZE; | ||
9920 | + } | ||
9921 | + | ||
9922 | + /* Otherwise, we have a nontrivial interval. When | ||
9923 | + we're all done, the pattern will look like: | ||
9924 | + set_number_at <jump count> <upper bound> | ||
9925 | + set_number_at <succeed_n count> <lower bound> | ||
9926 | + succeed_n <after jump addr> <succeed_n count> | ||
9927 | + <body of loop> | ||
9928 | + jump_n <succeed_n addr> <jump count> | ||
9929 | + (The upper bound and `jump_n' are omitted if | ||
9930 | + `upper_bound' is 1, though.) */ | ||
9931 | + else | ||
9932 | + { /* If the upper bound is > 1, we need to insert | ||
9933 | + more at the end of the loop. */ | ||
9934 | + unsigned nbytes = 2 + 4 * OFFSET_ADDRESS_SIZE + | ||
9935 | + (upper_bound > 1) * (2 + 4 * OFFSET_ADDRESS_SIZE); | ||
9936 | + | ||
9937 | + GET_BUFFER_SPACE (nbytes); | ||
9938 | + | ||
9939 | + /* Initialize lower bound of the `succeed_n', even | ||
9940 | + though it will be set during matching by its | ||
9941 | + attendant `set_number_at' (inserted next), | ||
9942 | + because `re_compile_fastmap' needs to know. | ||
9943 | + Jump to the `jump_n' we might insert below. */ | ||
9944 | + INSERT_JUMP2 (succeed_n, laststart, | ||
9945 | + b + 1 + 2 * OFFSET_ADDRESS_SIZE | ||
9946 | + + (upper_bound > 1) * (1 + 2 * OFFSET_ADDRESS_SIZE) | ||
9947 | + , lower_bound); | ||
9948 | + b += 1 + 2 * OFFSET_ADDRESS_SIZE; | ||
9949 | + | ||
9950 | + /* Code to initialize the lower bound. Insert | ||
9951 | + before the `succeed_n'. The `5' is the last two | ||
9952 | + bytes of this `set_number_at', plus 3 bytes of | ||
9953 | + the following `succeed_n'. */ | ||
9954 | + /* ifdef WCHAR, The '1+2*OFFSET_ADDRESS_SIZE' | ||
9955 | + is the 'set_number_at', plus '1+OFFSET_ADDRESS_SIZE' | ||
9956 | + of the following `succeed_n'. */ | ||
9957 | + PREFIX(insert_op2) (set_number_at, laststart, 1 | ||
9958 | + + 2 * OFFSET_ADDRESS_SIZE, lower_bound, b); | ||
9959 | + b += 1 + 2 * OFFSET_ADDRESS_SIZE; | ||
9960 | + | ||
9961 | + if (upper_bound > 1) | ||
9962 | + { /* More than one repetition is allowed, so | ||
9963 | + append a backward jump to the `succeed_n' | ||
9964 | + that starts this interval. | ||
9965 | + | ||
9966 | + When we've reached this during matching, | ||
9967 | + we'll have matched the interval once, so | ||
9968 | + jump back only `upper_bound - 1' times. */ | ||
9969 | + STORE_JUMP2 (jump_n, b, laststart | ||
9970 | + + 2 * OFFSET_ADDRESS_SIZE + 1, | ||
9971 | + upper_bound - 1); | ||
9972 | + b += 1 + 2 * OFFSET_ADDRESS_SIZE; | ||
9973 | + | ||
9974 | + /* The location we want to set is the second | ||
9975 | + parameter of the `jump_n'; that is `b-2' as | ||
9976 | + an absolute address. `laststart' will be | ||
9977 | + the `set_number_at' we're about to insert; | ||
9978 | + `laststart+3' the number to set, the source | ||
9979 | + for the relative address. But we are | ||
9980 | + inserting into the middle of the pattern -- | ||
9981 | + so everything is getting moved up by 5. | ||
9982 | + Conclusion: (b - 2) - (laststart + 3) + 5, | ||
9983 | + i.e., b - laststart. | ||
9984 | + | ||
9985 | + We insert this at the beginning of the loop | ||
9986 | + so that if we fail during matching, we'll | ||
9987 | + reinitialize the bounds. */ | ||
9988 | + PREFIX(insert_op2) (set_number_at, laststart, | ||
9989 | + b - laststart, | ||
9990 | + upper_bound - 1, b); | ||
9991 | + b += 1 + 2 * OFFSET_ADDRESS_SIZE; | ||
9992 | + } | ||
9993 | + } | ||
9994 | + pending_exact = 0; | ||
9995 | + break; | ||
9996 | + | ||
9997 | + invalid_interval: | ||
9998 | + if (!(syntax & RE_INVALID_INTERVAL_ORD)) | ||
9999 | + FREE_STACK_RETURN (p == pend ? REG_EBRACE : REG_BADBR); | ||
10000 | + unfetch_interval: | ||
10001 | + /* Match the characters as literals. */ | ||
10002 | + p = beg_interval; | ||
10003 | + c = '{'; | ||
10004 | + if (syntax & RE_NO_BK_BRACES) | ||
10005 | + goto normal_char; | ||
10006 | + else | ||
10007 | + goto normal_backslash; | ||
10008 | + } | ||
10009 | + | ||
10010 | +#ifdef emacs | ||
10011 | + /* There is no way to specify the before_dot and after_dot | ||
10012 | + operators. rms says this is ok. --karl */ | ||
10013 | + case '=': | ||
10014 | + BUF_PUSH (at_dot); | ||
10015 | + break; | ||
10016 | + | ||
10017 | + case 's': | ||
10018 | + laststart = b; | ||
10019 | + PATFETCH (c); | ||
10020 | + BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); | ||
10021 | + break; | ||
10022 | + | ||
10023 | + case 'S': | ||
10024 | + laststart = b; | ||
10025 | + PATFETCH (c); | ||
10026 | + BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); | ||
10027 | + break; | ||
10028 | +#endif /* emacs */ | ||
10029 | + | ||
10030 | + | ||
10031 | + case 'w': | ||
10032 | + if (syntax & RE_NO_GNU_OPS) | ||
10033 | + goto normal_char; | ||
10034 | + laststart = b; | ||
10035 | + BUF_PUSH (wordchar); | ||
10036 | + break; | ||
10037 | + | ||
10038 | + | ||
10039 | + case 'W': | ||
10040 | + if (syntax & RE_NO_GNU_OPS) | ||
10041 | + goto normal_char; | ||
10042 | + laststart = b; | ||
10043 | + BUF_PUSH (notwordchar); | ||
10044 | + break; | ||
10045 | + | ||
10046 | + | ||
10047 | + case '<': | ||
10048 | + if (syntax & RE_NO_GNU_OPS) | ||
10049 | + goto normal_char; | ||
10050 | + BUF_PUSH (wordbeg); | ||
10051 | + break; | ||
10052 | + | ||
10053 | + case '>': | ||
10054 | + if (syntax & RE_NO_GNU_OPS) | ||
10055 | + goto normal_char; | ||
10056 | + BUF_PUSH (wordend); | ||
10057 | + break; | ||
10058 | + | ||
10059 | + case 'b': | ||
10060 | + if (syntax & RE_NO_GNU_OPS) | ||
10061 | + goto normal_char; | ||
10062 | + BUF_PUSH (wordbound); | ||
10063 | + break; | ||
10064 | + | ||
10065 | + case 'B': | ||
10066 | + if (syntax & RE_NO_GNU_OPS) | ||
10067 | + goto normal_char; | ||
10068 | + BUF_PUSH (notwordbound); | ||
10069 | + break; | ||
10070 | + | ||
10071 | + case '`': | ||
10072 | + if (syntax & RE_NO_GNU_OPS) | ||
10073 | + goto normal_char; | ||
10074 | + BUF_PUSH (begbuf); | ||
10075 | + break; | ||
10076 | + | ||
10077 | + case '\'': | ||
10078 | + if (syntax & RE_NO_GNU_OPS) | ||
10079 | + goto normal_char; | ||
10080 | + BUF_PUSH (endbuf); | ||
10081 | + break; | ||
10082 | + | ||
10083 | + case '1': case '2': case '3': case '4': case '5': | ||
10084 | + case '6': case '7': case '8': case '9': | ||
10085 | + if (syntax & RE_NO_BK_REFS) | ||
10086 | + goto normal_char; | ||
10087 | + | ||
10088 | + c1 = c - '0'; | ||
10089 | + | ||
10090 | + if (c1 > regnum) | ||
10091 | + FREE_STACK_RETURN (REG_ESUBREG); | ||
10092 | + | ||
10093 | + /* Can't back reference to a subexpression if inside of it. */ | ||
10094 | + if (group_in_compile_stack (compile_stack, (regnum_t) c1)) | ||
10095 | + goto normal_char; | ||
10096 | + | ||
10097 | + laststart = b; | ||
10098 | + BUF_PUSH_2 (duplicate, c1); | ||
10099 | + break; | ||
10100 | + | ||
10101 | + | ||
10102 | + case '+': | ||
10103 | + case '?': | ||
10104 | + if (syntax & RE_BK_PLUS_QM) | ||
10105 | + goto handle_plus; | ||
10106 | + else | ||
10107 | + goto normal_backslash; | ||
10108 | + | ||
10109 | + default: | ||
10110 | + normal_backslash: | ||
10111 | + /* You might think it would be useful for \ to mean | ||
10112 | + not to translate; but if we don't translate it | ||
10113 | + it will never match anything. */ | ||
10114 | + c = TRANSLATE (c); | ||
10115 | + goto normal_char; | ||
10116 | + } | ||
10117 | + break; | ||
10118 | + | ||
10119 | + | ||
10120 | + default: | ||
10121 | + /* Expects the character in `c'. */ | ||
10122 | + normal_char: | ||
10123 | + /* If no exactn currently being built. */ | ||
10124 | + if (!pending_exact | ||
10125 | +#ifdef WCHAR | ||
10126 | + /* If last exactn handle binary(or character) and | ||
10127 | + new exactn handle character(or binary). */ | ||
10128 | + || is_exactn_bin != is_binary[p - 1 - pattern] | ||
10129 | +#endif /* WCHAR */ | ||
10130 | + | ||
10131 | + /* If last exactn not at current position. */ | ||
10132 | + || pending_exact + *pending_exact + 1 != b | ||
10133 | + | ||
10134 | + /* We have only one byte following the exactn for the count. */ | ||
10135 | + || *pending_exact == (1 << BYTEWIDTH) - 1 | ||
10136 | + | ||
10137 | + /* If followed by a repetition operator. */ | ||
10138 | + || *p == '*' || *p == '^' | ||
10139 | + || ((syntax & RE_BK_PLUS_QM) | ||
10140 | + ? *p == '\\' && (p[1] == '+' || p[1] == '?') | ||
10141 | + : (*p == '+' || *p == '?')) | ||
10142 | + || ((syntax & RE_INTERVALS) | ||
10143 | + && ((syntax & RE_NO_BK_BRACES) | ||
10144 | + ? *p == '{' | ||
10145 | + : (p[0] == '\\' && p[1] == '{')))) | ||
10146 | + { | ||
10147 | + /* Start building a new exactn. */ | ||
10148 | + | ||
10149 | + laststart = b; | ||
10150 | + | ||
10151 | +#ifdef WCHAR | ||
10152 | + /* Is this exactn binary data or character? */ | ||
10153 | + is_exactn_bin = is_binary[p - 1 - pattern]; | ||
10154 | + if (is_exactn_bin) | ||
10155 | + BUF_PUSH_2 (exactn_bin, 0); | ||
10156 | + else | ||
10157 | + BUF_PUSH_2 (exactn, 0); | ||
10158 | +#else | ||
10159 | + BUF_PUSH_2 (exactn, 0); | ||
10160 | +#endif /* WCHAR */ | ||
10161 | + pending_exact = b - 1; | ||
10162 | + } | ||
10163 | + | ||
10164 | + BUF_PUSH (c); | ||
10165 | + (*pending_exact)++; | ||
10166 | + break; | ||
10167 | + } /* switch (c) */ | ||
10168 | + } /* while p != pend */ | ||
10169 | + | ||
10170 | + | ||
10171 | + /* Through the pattern now. */ | ||
10172 | + | ||
10173 | + if (fixup_alt_jump) | ||
10174 | + STORE_JUMP (jump_past_alt, fixup_alt_jump, b); | ||
10175 | + | ||
10176 | + if (!COMPILE_STACK_EMPTY) | ||
10177 | + FREE_STACK_RETURN (REG_EPAREN); | ||
10178 | + | ||
10179 | + /* If we don't want backtracking, force success | ||
10180 | + the first time we reach the end of the compiled pattern. */ | ||
10181 | + if (syntax & RE_NO_POSIX_BACKTRACKING) | ||
10182 | + BUF_PUSH (succeed); | ||
10183 | + | ||
10184 | +#ifdef WCHAR | ||
10185 | + free (pattern); | ||
10186 | + free (mbs_offset); | ||
10187 | + free (is_binary); | ||
10188 | +#endif | ||
10189 | + free (compile_stack.stack); | ||
10190 | + | ||
10191 | + /* We have succeeded; set the length of the buffer. */ | ||
10192 | +#ifdef WCHAR | ||
10193 | + bufp->used = (uintptr_t) b - (uintptr_t) COMPILED_BUFFER_VAR; | ||
10194 | +#else | ||
10195 | + bufp->used = b - bufp->buffer; | ||
10196 | +#endif | ||
10197 | + | ||
10198 | +#ifdef DEBUG | ||
10199 | + if (debug) | ||
10200 | + { | ||
10201 | + DEBUG_PRINT1 ("\nCompiled pattern: \n"); | ||
10202 | + PREFIX(print_compiled_pattern) (bufp); | ||
10203 | + } | ||
10204 | +#endif /* DEBUG */ | ||
10205 | + | ||
10206 | +#ifndef MATCH_MAY_ALLOCATE | ||
10207 | + /* Initialize the failure stack to the largest possible stack. This | ||
10208 | + isn't necessary unless we're trying to avoid calling alloca in | ||
10209 | + the search and match routines. */ | ||
10210 | + { | ||
10211 | + int num_regs = bufp->re_nsub + 1; | ||
10212 | + | ||
10213 | + /* Since DOUBLE_FAIL_STACK refuses to double only if the current size | ||
10214 | + is strictly greater than re_max_failures, the largest possible stack | ||
10215 | + is 2 * re_max_failures failure points. */ | ||
10216 | + if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS)) | ||
10217 | + { | ||
10218 | + fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS); | ||
10219 | + | ||
10220 | +# ifdef emacs | ||
10221 | + if (! fail_stack.stack) | ||
10222 | + fail_stack.stack | ||
10223 | + = (PREFIX(fail_stack_elt_t) *) xmalloc (fail_stack.size | ||
10224 | + * sizeof (PREFIX(fail_stack_elt_t))); | ||
10225 | + else | ||
10226 | + fail_stack.stack | ||
10227 | + = (PREFIX(fail_stack_elt_t) *) xrealloc (fail_stack.stack, | ||
10228 | + (fail_stack.size | ||
10229 | + * sizeof (PREFIX(fail_stack_elt_t)))); | ||
10230 | +# else /* not emacs */ | ||
10231 | + if (! fail_stack.stack) | ||
10232 | + fail_stack.stack | ||
10233 | + = (PREFIX(fail_stack_elt_t) *) malloc (fail_stack.size | ||
10234 | + * sizeof (PREFIX(fail_stack_elt_t))); | ||
10235 | + else | ||
10236 | + fail_stack.stack | ||
10237 | + = (PREFIX(fail_stack_elt_t) *) realloc (fail_stack.stack, | ||
10238 | + (fail_stack.size | ||
10239 | + * sizeof (PREFIX(fail_stack_elt_t)))); | ||
10240 | +# endif /* not emacs */ | ||
10241 | + } | ||
10242 | + | ||
10243 | + PREFIX(regex_grow_registers) (num_regs); | ||
10244 | + } | ||
10245 | +#endif /* not MATCH_MAY_ALLOCATE */ | ||
10246 | + | ||
10247 | + return REG_NOERROR; | ||
10248 | +} /* regex_compile */ | ||
10249 | + | ||
10250 | +/* Subroutines for `regex_compile'. */ | ||
10251 | + | ||
10252 | +/* Store OP at LOC followed by two-byte integer parameter ARG. */ | ||
10253 | +/* ifdef WCHAR, integer parameter is 1 wchar_t. */ | ||
10254 | + | ||
10255 | +static void | ||
10256 | +PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg) | ||
10257 | +{ | ||
10258 | + *loc = (UCHAR_T) op; | ||
10259 | + STORE_NUMBER (loc + 1, arg); | ||
10260 | +} | ||
10261 | + | ||
10262 | + | ||
10263 | +/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ | ||
10264 | +/* ifdef WCHAR, integer parameter is 1 wchar_t. */ | ||
10265 | + | ||
10266 | +static void | ||
10267 | +PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, int arg2) | ||
10268 | +{ | ||
10269 | + *loc = (UCHAR_T) op; | ||
10270 | + STORE_NUMBER (loc + 1, arg1); | ||
10271 | + STORE_NUMBER (loc + 1 + OFFSET_ADDRESS_SIZE, arg2); | ||
10272 | +} | ||
10273 | + | ||
10274 | + | ||
10275 | +/* Copy the bytes from LOC to END to open up three bytes of space at LOC | ||
10276 | + for OP followed by two-byte integer parameter ARG. */ | ||
10277 | +/* ifdef WCHAR, integer parameter is 1 wchar_t. */ | ||
10278 | + | ||
10279 | +static void | ||
10280 | +PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, int arg, UCHAR_T *end) | ||
10281 | +{ | ||
10282 | + register UCHAR_T *pfrom = end; | ||
10283 | + register UCHAR_T *pto = end + 1 + OFFSET_ADDRESS_SIZE; | ||
10284 | + | ||
10285 | + while (pfrom != loc) | ||
10286 | + *--pto = *--pfrom; | ||
10287 | + | ||
10288 | + PREFIX(store_op1) (op, loc, arg); | ||
10289 | +} | ||
10290 | + | ||
10291 | + | ||
10292 | +/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ | ||
10293 | +/* ifdef WCHAR, integer parameter is 1 wchar_t. */ | ||
10294 | + | ||
10295 | +static void | ||
10296 | +PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, | ||
10297 | + int arg2, UCHAR_T *end) | ||
10298 | +{ | ||
10299 | + register UCHAR_T *pfrom = end; | ||
10300 | + register UCHAR_T *pto = end + 1 + 2 * OFFSET_ADDRESS_SIZE; | ||
10301 | + | ||
10302 | + while (pfrom != loc) | ||
10303 | + *--pto = *--pfrom; | ||
10304 | + | ||
10305 | + PREFIX(store_op2) (op, loc, arg1, arg2); | ||
10306 | +} | ||
10307 | + | ||
10308 | + | ||
10309 | +/* P points to just after a ^ in PATTERN. Return true if that ^ comes | ||
10310 | + after an alternative or a begin-subexpression. We assume there is at | ||
10311 | + least one character before the ^. */ | ||
10312 | + | ||
10313 | +static boolean | ||
10314 | +PREFIX(at_begline_loc_p) (const CHAR_T *pattern, const CHAR_T *p, | ||
10315 | + reg_syntax_t syntax) | ||
10316 | +{ | ||
10317 | + const CHAR_T *prev = p - 2; | ||
10318 | + boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; | ||
10319 | + | ||
10320 | + return | ||
10321 | + /* After a subexpression? */ | ||
10322 | + (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) | ||
10323 | + /* After an alternative? */ | ||
10324 | + || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); | ||
10325 | +} | ||
10326 | + | ||
10327 | + | ||
10328 | +/* The dual of at_begline_loc_p. This one is for $. We assume there is | ||
10329 | + at least one character after the $, i.e., `P < PEND'. */ | ||
10330 | + | ||
10331 | +static boolean | ||
10332 | +PREFIX(at_endline_loc_p) (const CHAR_T *p, const CHAR_T *pend, | ||
10333 | + reg_syntax_t syntax) | ||
10334 | +{ | ||
10335 | + const CHAR_T *next = p; | ||
10336 | + boolean next_backslash = *next == '\\'; | ||
10337 | + const CHAR_T *next_next = p + 1 < pend ? p + 1 : 0; | ||
10338 | + | ||
10339 | + return | ||
10340 | + /* Before a subexpression? */ | ||
10341 | + (syntax & RE_NO_BK_PARENS ? *next == ')' | ||
10342 | + : next_backslash && next_next && *next_next == ')') | ||
10343 | + /* Before an alternative? */ | ||
10344 | + || (syntax & RE_NO_BK_VBAR ? *next == '|' | ||
10345 | + : next_backslash && next_next && *next_next == '|'); | ||
10346 | +} | ||
10347 | + | ||
10348 | +#else /* not INSIDE_RECURSION */ | ||
10349 | + | ||
10350 | +/* Returns true if REGNUM is in one of COMPILE_STACK's elements and | ||
10351 | + false if it's not. */ | ||
10352 | + | ||
10353 | +static boolean | ||
10354 | +group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum) | ||
10355 | +{ | ||
10356 | + int this_element; | ||
10357 | + | ||
10358 | + for (this_element = compile_stack.avail - 1; | ||
10359 | + this_element >= 0; | ||
10360 | + this_element--) | ||
10361 | + if (compile_stack.stack[this_element].regnum == regnum) | ||
10362 | + return true; | ||
10363 | + | ||
10364 | + return false; | ||
10365 | +} | ||
10366 | +#endif /* not INSIDE_RECURSION */ | ||
10367 | + | ||
10368 | +#ifdef INSIDE_RECURSION | ||
10369 | + | ||
10370 | +#ifdef WCHAR | ||
10371 | +/* This insert space, which size is "num", into the pattern at "loc". | ||
10372 | + "end" must point the end of the allocated buffer. */ | ||
10373 | +static void | ||
10374 | +insert_space (int num, CHAR_T *loc, CHAR_T *end) | ||
10375 | +{ | ||
10376 | + register CHAR_T *pto = end; | ||
10377 | + register CHAR_T *pfrom = end - num; | ||
10378 | + | ||
10379 | + while (pfrom >= loc) | ||
10380 | + *pto-- = *pfrom--; | ||
10381 | +} | ||
10382 | +#endif /* WCHAR */ | ||
10383 | + | ||
10384 | +#ifdef WCHAR | ||
10385 | +static reg_errcode_t | ||
10386 | +wcs_compile_range (CHAR_T range_start_char, const CHAR_T **p_ptr, | ||
10387 | + const CHAR_T *pend, RE_TRANSLATE_TYPE translate, | ||
10388 | + reg_syntax_t syntax, CHAR_T *b, CHAR_T *char_set) | ||
10389 | +{ | ||
10390 | + const CHAR_T *p = *p_ptr; | ||
10391 | + CHAR_T range_start, range_end; | ||
10392 | + reg_errcode_t ret; | ||
10393 | +# ifdef _LIBC | ||
10394 | + uint32_t nrules; | ||
10395 | + uint32_t start_val, end_val; | ||
10396 | +# endif | ||
10397 | + if (p == pend) | ||
10398 | + return REG_ERANGE; | ||
10399 | + | ||
10400 | +# ifdef _LIBC | ||
10401 | + nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); | ||
10402 | + if (nrules != 0) | ||
10403 | + { | ||
10404 | + const char *collseq = (const char *) _NL_CURRENT(LC_COLLATE, | ||
10405 | + _NL_COLLATE_COLLSEQWC); | ||
10406 | + const unsigned char *extra = (const unsigned char *) | ||
10407 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); | ||
10408 | + | ||
10409 | + if (range_start_char < -1) | ||
10410 | + { | ||
10411 | + /* range_start is a collating symbol. */ | ||
10412 | + int32_t *wextra; | ||
10413 | + /* Retreive the index and get collation sequence value. */ | ||
10414 | + wextra = (int32_t*)(extra + char_set[-range_start_char]); | ||
10415 | + start_val = wextra[1 + *wextra]; | ||
10416 | + } | ||
10417 | + else | ||
10418 | + start_val = collseq_table_lookup(collseq, TRANSLATE(range_start_char)); | ||
10419 | + | ||
10420 | + end_val = collseq_table_lookup (collseq, TRANSLATE (p[0])); | ||
10421 | + | ||
10422 | + /* Report an error if the range is empty and the syntax prohibits | ||
10423 | + this. */ | ||
10424 | + ret = ((syntax & RE_NO_EMPTY_RANGES) | ||
10425 | + && (start_val > end_val))? REG_ERANGE : REG_NOERROR; | ||
10426 | + | ||
10427 | + /* Insert space to the end of the char_ranges. */ | ||
10428 | + insert_space(2, b - char_set[5] - 2, b - 1); | ||
10429 | + *(b - char_set[5] - 2) = (wchar_t)start_val; | ||
10430 | + *(b - char_set[5] - 1) = (wchar_t)end_val; | ||
10431 | + char_set[4]++; /* ranges_index */ | ||
10432 | + } | ||
10433 | + else | ||
10434 | +# endif | ||
10435 | + { | ||
10436 | + range_start = (range_start_char >= 0)? TRANSLATE (range_start_char): | ||
10437 | + range_start_char; | ||
10438 | + range_end = TRANSLATE (p[0]); | ||
10439 | + /* Report an error if the range is empty and the syntax prohibits | ||
10440 | + this. */ | ||
10441 | + ret = ((syntax & RE_NO_EMPTY_RANGES) | ||
10442 | + && (range_start > range_end))? REG_ERANGE : REG_NOERROR; | ||
10443 | + | ||
10444 | + /* Insert space to the end of the char_ranges. */ | ||
10445 | + insert_space(2, b - char_set[5] - 2, b - 1); | ||
10446 | + *(b - char_set[5] - 2) = range_start; | ||
10447 | + *(b - char_set[5] - 1) = range_end; | ||
10448 | + char_set[4]++; /* ranges_index */ | ||
10449 | + } | ||
10450 | + /* Have to increment the pointer into the pattern string, so the | ||
10451 | + caller isn't still at the ending character. */ | ||
10452 | + (*p_ptr)++; | ||
10453 | + | ||
10454 | + return ret; | ||
10455 | +} | ||
10456 | +#else /* BYTE */ | ||
10457 | +/* Read the ending character of a range (in a bracket expression) from the | ||
10458 | + uncompiled pattern *P_PTR (which ends at PEND). We assume the | ||
10459 | + starting character is in `P[-2]'. (`P[-1]' is the character `-'.) | ||
10460 | + Then we set the translation of all bits between the starting and | ||
10461 | + ending characters (inclusive) in the compiled pattern B. | ||
10462 | + | ||
10463 | + Return an error code. | ||
10464 | + | ||
10465 | + We use these short variable names so we can use the same macros as | ||
10466 | + `regex_compile' itself. */ | ||
10467 | + | ||
10468 | +static reg_errcode_t | ||
10469 | +byte_compile_range (unsigned int range_start_char, const char **p_ptr, | ||
10470 | + const char *pend, RE_TRANSLATE_TYPE translate, | ||
10471 | + reg_syntax_t syntax, unsigned char *b) | ||
10472 | +{ | ||
10473 | + unsigned this_char; | ||
10474 | + const char *p = *p_ptr; | ||
10475 | + reg_errcode_t ret; | ||
10476 | +# if _LIBC | ||
10477 | + const unsigned char *collseq; | ||
10478 | + unsigned int start_colseq; | ||
10479 | + unsigned int end_colseq; | ||
10480 | +# else | ||
10481 | + unsigned end_char; | ||
10482 | +# endif | ||
10483 | + | ||
10484 | + if (p == pend) | ||
10485 | + return REG_ERANGE; | ||
10486 | + | ||
10487 | + /* Have to increment the pointer into the pattern string, so the | ||
10488 | + caller isn't still at the ending character. */ | ||
10489 | + (*p_ptr)++; | ||
10490 | + | ||
10491 | + /* Report an error if the range is empty and the syntax prohibits this. */ | ||
10492 | + ret = syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; | ||
10493 | + | ||
10494 | +# if _LIBC | ||
10495 | + collseq = (const unsigned char *) _NL_CURRENT (LC_COLLATE, | ||
10496 | + _NL_COLLATE_COLLSEQMB); | ||
10497 | + | ||
10498 | + start_colseq = collseq[(unsigned char) TRANSLATE (range_start_char)]; | ||
10499 | + end_colseq = collseq[(unsigned char) TRANSLATE (p[0])]; | ||
10500 | + for (this_char = 0; this_char <= (unsigned char) -1; ++this_char) | ||
10501 | + { | ||
10502 | + unsigned int this_colseq = collseq[(unsigned char) TRANSLATE (this_char)]; | ||
10503 | + | ||
10504 | + if (start_colseq <= this_colseq && this_colseq <= end_colseq) | ||
10505 | + { | ||
10506 | + SET_LIST_BIT (TRANSLATE (this_char)); | ||
10507 | + ret = REG_NOERROR; | ||
10508 | + } | ||
10509 | + } | ||
10510 | +# else | ||
10511 | + /* Here we see why `this_char' has to be larger than an `unsigned | ||
10512 | + char' -- we would otherwise go into an infinite loop, since all | ||
10513 | + characters <= 0xff. */ | ||
10514 | + range_start_char = TRANSLATE (range_start_char); | ||
10515 | + /* TRANSLATE(p[0]) is casted to char (not unsigned char) in TRANSLATE, | ||
10516 | + and some compilers cast it to int implicitly, so following for_loop | ||
10517 | + may fall to (almost) infinite loop. | ||
10518 | + e.g. If translate[p[0]] = 0xff, end_char may equals to 0xffffffff. | ||
10519 | + To avoid this, we cast p[0] to unsigned int and truncate it. */ | ||
10520 | + end_char = ((unsigned)TRANSLATE(p[0]) & ((1 << BYTEWIDTH) - 1)); | ||
10521 | + | ||
10522 | + for (this_char = range_start_char; this_char <= end_char; ++this_char) | ||
10523 | + { | ||
10524 | + SET_LIST_BIT (TRANSLATE (this_char)); | ||
10525 | + ret = REG_NOERROR; | ||
10526 | + } | ||
10527 | +# endif | ||
10528 | + | ||
10529 | + return ret; | ||
10530 | +} | ||
10531 | +#endif /* WCHAR */ | ||
10532 | + | ||
10533 | +/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in | ||
10534 | + BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible | ||
10535 | + characters can start a string that matches the pattern. This fastmap | ||
10536 | + is used by re_search to skip quickly over impossible starting points. | ||
10537 | + | ||
10538 | + The caller must supply the address of a (1 << BYTEWIDTH)-byte data | ||
10539 | + area as BUFP->fastmap. | ||
10540 | + | ||
10541 | + We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in | ||
10542 | + the pattern buffer. | ||
10543 | + | ||
10544 | + Returns 0 if we succeed, -2 if an internal error. */ | ||
10545 | + | ||
10546 | +#ifdef WCHAR | ||
10547 | +/* local function for re_compile_fastmap. | ||
10548 | + truncate wchar_t character to char. */ | ||
10549 | +static unsigned char truncate_wchar (CHAR_T c); | ||
10550 | + | ||
10551 | +static unsigned char | ||
10552 | +truncate_wchar (CHAR_T c) | ||
10553 | +{ | ||
10554 | + unsigned char buf[MB_CUR_MAX]; | ||
10555 | + mbstate_t state; | ||
10556 | + int retval; | ||
10557 | + memset (&state, '\0', sizeof (state)); | ||
10558 | +# ifdef _LIBC | ||
10559 | + retval = __wcrtomb (buf, c, &state); | ||
10560 | +# else | ||
10561 | + retval = wcrtomb (buf, c, &state); | ||
10562 | +# endif | ||
10563 | + return retval > 0 ? buf[0] : (unsigned char) c; | ||
10564 | +} | ||
10565 | +#endif /* WCHAR */ | ||
10566 | + | ||
10567 | +static int | ||
10568 | +PREFIX(re_compile_fastmap) (struct re_pattern_buffer *bufp) | ||
10569 | +{ | ||
10570 | + int j, k; | ||
10571 | +#ifdef MATCH_MAY_ALLOCATE | ||
10572 | + PREFIX(fail_stack_type) fail_stack; | ||
10573 | +#endif | ||
10574 | +#ifndef REGEX_MALLOC | ||
10575 | + char *destination; | ||
10576 | +#endif | ||
10577 | + | ||
10578 | + register char *fastmap = bufp->fastmap; | ||
10579 | + | ||
10580 | +#ifdef WCHAR | ||
10581 | + /* We need to cast pattern to (wchar_t*), because we casted this compiled | ||
10582 | + pattern to (char*) in regex_compile. */ | ||
10583 | + UCHAR_T *pattern = (UCHAR_T*)bufp->buffer; | ||
10584 | + register UCHAR_T *pend = (UCHAR_T*) (bufp->buffer + bufp->used); | ||
10585 | +#else /* BYTE */ | ||
10586 | + UCHAR_T *pattern = bufp->buffer; | ||
10587 | + register UCHAR_T *pend = pattern + bufp->used; | ||
10588 | +#endif /* WCHAR */ | ||
10589 | + UCHAR_T *p = pattern; | ||
10590 | + | ||
10591 | +#ifdef REL_ALLOC | ||
10592 | + /* This holds the pointer to the failure stack, when | ||
10593 | + it is allocated relocatably. */ | ||
10594 | + fail_stack_elt_t *failure_stack_ptr; | ||
10595 | +#endif | ||
10596 | + | ||
10597 | + /* Assume that each path through the pattern can be null until | ||
10598 | + proven otherwise. We set this false at the bottom of switch | ||
10599 | + statement, to which we get only if a particular path doesn't | ||
10600 | + match the empty string. */ | ||
10601 | + boolean path_can_be_null = true; | ||
10602 | + | ||
10603 | + /* We aren't doing a `succeed_n' to begin with. */ | ||
10604 | + boolean succeed_n_p = false; | ||
10605 | + | ||
10606 | + assert (fastmap != NULL && p != NULL); | ||
10607 | + | ||
10608 | + INIT_FAIL_STACK (); | ||
10609 | + bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ | ||
10610 | + bufp->fastmap_accurate = 1; /* It will be when we're done. */ | ||
10611 | + bufp->can_be_null = 0; | ||
10612 | + | ||
10613 | + while (1) | ||
10614 | + { | ||
10615 | + if (p == pend || *p == (UCHAR_T) succeed) | ||
10616 | + { | ||
10617 | + /* We have reached the (effective) end of pattern. */ | ||
10618 | + if (!FAIL_STACK_EMPTY ()) | ||
10619 | + { | ||
10620 | + bufp->can_be_null |= path_can_be_null; | ||
10621 | + | ||
10622 | + /* Reset for next path. */ | ||
10623 | + path_can_be_null = true; | ||
10624 | + | ||
10625 | + p = fail_stack.stack[--fail_stack.avail].pointer; | ||
10626 | + | ||
10627 | + continue; | ||
10628 | + } | ||
10629 | + else | ||
10630 | + break; | ||
10631 | + } | ||
10632 | + | ||
10633 | + /* We should never be about to go beyond the end of the pattern. */ | ||
10634 | + assert (p < pend); | ||
10635 | + | ||
10636 | + switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) | ||
10637 | + { | ||
10638 | + | ||
10639 | + /* I guess the idea here is to simply not bother with a fastmap | ||
10640 | + if a backreference is used, since it's too hard to figure out | ||
10641 | + the fastmap for the corresponding group. Setting | ||
10642 | + `can_be_null' stops `re_search_2' from using the fastmap, so | ||
10643 | + that is all we do. */ | ||
10644 | + case duplicate: | ||
10645 | + bufp->can_be_null = 1; | ||
10646 | + goto done; | ||
10647 | + | ||
10648 | + | ||
10649 | + /* Following are the cases which match a character. These end | ||
10650 | + with `break'. */ | ||
10651 | + | ||
10652 | +#ifdef WCHAR | ||
10653 | + case exactn: | ||
10654 | + fastmap[truncate_wchar(p[1])] = 1; | ||
10655 | + break; | ||
10656 | +#else /* BYTE */ | ||
10657 | + case exactn: | ||
10658 | + fastmap[p[1]] = 1; | ||
10659 | + break; | ||
10660 | +#endif /* WCHAR */ | ||
10661 | +#ifdef MBS_SUPPORT | ||
10662 | + case exactn_bin: | ||
10663 | + fastmap[p[1]] = 1; | ||
10664 | + break; | ||
10665 | +#endif | ||
10666 | + | ||
10667 | +#ifdef WCHAR | ||
10668 | + /* It is hard to distinguish fastmap from (multi byte) characters | ||
10669 | + which depends on current locale. */ | ||
10670 | + case charset: | ||
10671 | + case charset_not: | ||
10672 | + case wordchar: | ||
10673 | + case notwordchar: | ||
10674 | + bufp->can_be_null = 1; | ||
10675 | + goto done; | ||
10676 | +#else /* BYTE */ | ||
10677 | + case charset: | ||
10678 | + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) | ||
10679 | + if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) | ||
10680 | + fastmap[j] = 1; | ||
10681 | + break; | ||
10682 | + | ||
10683 | + | ||
10684 | + case charset_not: | ||
10685 | + /* Chars beyond end of map must be allowed. */ | ||
10686 | + for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) | ||
10687 | + fastmap[j] = 1; | ||
10688 | + | ||
10689 | + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) | ||
10690 | + if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) | ||
10691 | + fastmap[j] = 1; | ||
10692 | + break; | ||
10693 | + | ||
10694 | + | ||
10695 | + case wordchar: | ||
10696 | + for (j = 0; j < (1 << BYTEWIDTH); j++) | ||
10697 | + if (SYNTAX (j) == Sword) | ||
10698 | + fastmap[j] = 1; | ||
10699 | + break; | ||
10700 | + | ||
10701 | + | ||
10702 | + case notwordchar: | ||
10703 | + for (j = 0; j < (1 << BYTEWIDTH); j++) | ||
10704 | + if (SYNTAX (j) != Sword) | ||
10705 | + fastmap[j] = 1; | ||
10706 | + break; | ||
10707 | +#endif /* WCHAR */ | ||
10708 | + | ||
10709 | + case anychar: | ||
10710 | + { | ||
10711 | + int fastmap_newline = fastmap['\n']; | ||
10712 | + | ||
10713 | + /* `.' matches anything ... */ | ||
10714 | + for (j = 0; j < (1 << BYTEWIDTH); j++) | ||
10715 | + fastmap[j] = 1; | ||
10716 | + | ||
10717 | + /* ... except perhaps newline. */ | ||
10718 | + if (!(bufp->syntax & RE_DOT_NEWLINE)) | ||
10719 | + fastmap['\n'] = fastmap_newline; | ||
10720 | + | ||
10721 | + /* Return if we have already set `can_be_null'; if we have, | ||
10722 | + then the fastmap is irrelevant. Something's wrong here. */ | ||
10723 | + else if (bufp->can_be_null) | ||
10724 | + goto done; | ||
10725 | + | ||
10726 | + /* Otherwise, have to check alternative paths. */ | ||
10727 | + break; | ||
10728 | + } | ||
10729 | + | ||
10730 | +#ifdef emacs | ||
10731 | + case syntaxspec: | ||
10732 | + k = *p++; | ||
10733 | + for (j = 0; j < (1 << BYTEWIDTH); j++) | ||
10734 | + if (SYNTAX (j) == (enum syntaxcode) k) | ||
10735 | + fastmap[j] = 1; | ||
10736 | + break; | ||
10737 | + | ||
10738 | + | ||
10739 | + case notsyntaxspec: | ||
10740 | + k = *p++; | ||
10741 | + for (j = 0; j < (1 << BYTEWIDTH); j++) | ||
10742 | + if (SYNTAX (j) != (enum syntaxcode) k) | ||
10743 | + fastmap[j] = 1; | ||
10744 | + break; | ||
10745 | + | ||
10746 | + | ||
10747 | + /* All cases after this match the empty string. These end with | ||
10748 | + `continue'. */ | ||
10749 | + | ||
10750 | + | ||
10751 | + case before_dot: | ||
10752 | + case at_dot: | ||
10753 | + case after_dot: | ||
10754 | + continue; | ||
10755 | +#endif /* emacs */ | ||
10756 | + | ||
10757 | + | ||
10758 | + case no_op: | ||
10759 | + case begline: | ||
10760 | + case endline: | ||
10761 | + case begbuf: | ||
10762 | + case endbuf: | ||
10763 | + case wordbound: | ||
10764 | + case notwordbound: | ||
10765 | + case wordbeg: | ||
10766 | + case wordend: | ||
10767 | + case push_dummy_failure: | ||
10768 | + continue; | ||
10769 | + | ||
10770 | + | ||
10771 | + case jump_n: | ||
10772 | + case pop_failure_jump: | ||
10773 | + case maybe_pop_jump: | ||
10774 | + case jump: | ||
10775 | + case jump_past_alt: | ||
10776 | + case dummy_failure_jump: | ||
10777 | + EXTRACT_NUMBER_AND_INCR (j, p); | ||
10778 | + p += j; | ||
10779 | + if (j > 0) | ||
10780 | + continue; | ||
10781 | + | ||
10782 | + /* Jump backward implies we just went through the body of a | ||
10783 | + loop and matched nothing. Opcode jumped to should be | ||
10784 | + `on_failure_jump' or `succeed_n'. Just treat it like an | ||
10785 | + ordinary jump. For a * loop, it has pushed its failure | ||
10786 | + point already; if so, discard that as redundant. */ | ||
10787 | + if ((re_opcode_t) *p != on_failure_jump | ||
10788 | + && (re_opcode_t) *p != succeed_n) | ||
10789 | + continue; | ||
10790 | + | ||
10791 | + p++; | ||
10792 | + EXTRACT_NUMBER_AND_INCR (j, p); | ||
10793 | + p += j; | ||
10794 | + | ||
10795 | + /* If what's on the stack is where we are now, pop it. */ | ||
10796 | + if (!FAIL_STACK_EMPTY () | ||
10797 | + && fail_stack.stack[fail_stack.avail - 1].pointer == p) | ||
10798 | + fail_stack.avail--; | ||
10799 | + | ||
10800 | + continue; | ||
10801 | + | ||
10802 | + | ||
10803 | + case on_failure_jump: | ||
10804 | + case on_failure_keep_string_jump: | ||
10805 | + handle_on_failure_jump: | ||
10806 | + EXTRACT_NUMBER_AND_INCR (j, p); | ||
10807 | + | ||
10808 | + /* For some patterns, e.g., `(a?)?', `p+j' here points to the | ||
10809 | + end of the pattern. We don't want to push such a point, | ||
10810 | + since when we restore it above, entering the switch will | ||
10811 | + increment `p' past the end of the pattern. We don't need | ||
10812 | + to push such a point since we obviously won't find any more | ||
10813 | + fastmap entries beyond `pend'. Such a pattern can match | ||
10814 | + the null string, though. */ | ||
10815 | + if (p + j < pend) | ||
10816 | + { | ||
10817 | + if (!PUSH_PATTERN_OP (p + j, fail_stack)) | ||
10818 | + { | ||
10819 | + RESET_FAIL_STACK (); | ||
10820 | + return -2; | ||
10821 | + } | ||
10822 | + } | ||
10823 | + else | ||
10824 | + bufp->can_be_null = 1; | ||
10825 | + | ||
10826 | + if (succeed_n_p) | ||
10827 | + { | ||
10828 | + EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ | ||
10829 | + succeed_n_p = false; | ||
10830 | + } | ||
10831 | + | ||
10832 | + continue; | ||
10833 | + | ||
10834 | + | ||
10835 | + case succeed_n: | ||
10836 | + /* Get to the number of times to succeed. */ | ||
10837 | + p += OFFSET_ADDRESS_SIZE; | ||
10838 | + | ||
10839 | + /* Increment p past the n for when k != 0. */ | ||
10840 | + EXTRACT_NUMBER_AND_INCR (k, p); | ||
10841 | + if (k == 0) | ||
10842 | + { | ||
10843 | + p -= 2 * OFFSET_ADDRESS_SIZE; | ||
10844 | + succeed_n_p = true; /* Spaghetti code alert. */ | ||
10845 | + goto handle_on_failure_jump; | ||
10846 | + } | ||
10847 | + continue; | ||
10848 | + | ||
10849 | + | ||
10850 | + case set_number_at: | ||
10851 | + p += 2 * OFFSET_ADDRESS_SIZE; | ||
10852 | + continue; | ||
10853 | + | ||
10854 | + | ||
10855 | + case start_memory: | ||
10856 | + case stop_memory: | ||
10857 | + p += 2; | ||
10858 | + continue; | ||
10859 | + | ||
10860 | + | ||
10861 | + default: | ||
10862 | + abort (); /* We have listed all the cases. */ | ||
10863 | + } /* switch *p++ */ | ||
10864 | + | ||
10865 | + /* Getting here means we have found the possible starting | ||
10866 | + characters for one path of the pattern -- and that the empty | ||
10867 | + string does not match. We need not follow this path further. | ||
10868 | + Instead, look at the next alternative (remembered on the | ||
10869 | + stack), or quit if no more. The test at the top of the loop | ||
10870 | + does these things. */ | ||
10871 | + path_can_be_null = false; | ||
10872 | + p = pend; | ||
10873 | + } /* while p */ | ||
10874 | + | ||
10875 | + /* Set `can_be_null' for the last path (also the first path, if the | ||
10876 | + pattern is empty). */ | ||
10877 | + bufp->can_be_null |= path_can_be_null; | ||
10878 | + | ||
10879 | + done: | ||
10880 | + RESET_FAIL_STACK (); | ||
10881 | + return 0; | ||
10882 | +} | ||
10883 | + | ||
10884 | +#else /* not INSIDE_RECURSION */ | ||
10885 | + | ||
10886 | +int | ||
10887 | +re_compile_fastmap (struct re_pattern_buffer *bufp) | ||
10888 | +{ | ||
10889 | +# ifdef MBS_SUPPORT | ||
10890 | + if (MB_CUR_MAX != 1) | ||
10891 | + return wcs_re_compile_fastmap(bufp); | ||
10892 | + else | ||
10893 | +# endif | ||
10894 | + return byte_re_compile_fastmap(bufp); | ||
10895 | +} /* re_compile_fastmap */ | ||
10896 | +#ifdef _LIBC | ||
10897 | +weak_alias (__re_compile_fastmap, re_compile_fastmap) | ||
10898 | +#endif | ||
10899 | + | ||
10900 | + | ||
10901 | +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and | ||
10902 | + ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use | ||
10903 | + this memory for recording register information. STARTS and ENDS | ||
10904 | + must be allocated using the malloc library routine, and must each | ||
10905 | + be at least NUM_REGS * sizeof (regoff_t) bytes long. | ||
10906 | + | ||
10907 | + If NUM_REGS == 0, then subsequent matches should allocate their own | ||
10908 | + register data. | ||
10909 | + | ||
10910 | + Unless this function is called, the first search or match using | ||
10911 | + PATTERN_BUFFER will allocate its own register data, without | ||
10912 | + freeing the old data. */ | ||
10913 | + | ||
10914 | +void | ||
10915 | +re_set_registers (struct re_pattern_buffer *bufp, | ||
10916 | + struct re_registers *regs, unsigned num_regs, | ||
10917 | + regoff_t *starts, regoff_t *ends) | ||
10918 | +{ | ||
10919 | + if (num_regs) | ||
10920 | + { | ||
10921 | + bufp->regs_allocated = REGS_REALLOCATE; | ||
10922 | + regs->num_regs = num_regs; | ||
10923 | + regs->start = starts; | ||
10924 | + regs->end = ends; | ||
10925 | + } | ||
10926 | + else | ||
10927 | + { | ||
10928 | + bufp->regs_allocated = REGS_UNALLOCATED; | ||
10929 | + regs->num_regs = 0; | ||
10930 | + regs->start = regs->end = (regoff_t *) 0; | ||
10931 | + } | ||
10932 | +} | ||
10933 | +#ifdef _LIBC | ||
10934 | +weak_alias (__re_set_registers, re_set_registers) | ||
10935 | +#endif | ||
10936 | + | ||
10937 | +/* Searching routines. */ | ||
10938 | + | ||
10939 | +/* Like re_search_2, below, but only one string is specified, and | ||
10940 | + doesn't let you say where to stop matching. */ | ||
10941 | + | ||
10942 | +int | ||
10943 | +re_search (struct re_pattern_buffer *bufp, const char *string, int size, | ||
10944 | + int startpos, int range, struct re_registers *regs) | ||
10945 | +{ | ||
10946 | + return re_search_2 (bufp, NULL, 0, string, size, startpos, range, | ||
10947 | + regs, size); | ||
10948 | +} | ||
10949 | +#ifdef _LIBC | ||
10950 | +weak_alias (__re_search, re_search) | ||
10951 | +#endif | ||
10952 | + | ||
10953 | + | ||
10954 | +/* Using the compiled pattern in BUFP->buffer, first tries to match the | ||
10955 | + virtual concatenation of STRING1 and STRING2, starting first at index | ||
10956 | + STARTPOS, then at STARTPOS + 1, and so on. | ||
10957 | + | ||
10958 | + STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. | ||
10959 | + | ||
10960 | + RANGE is how far to scan while trying to match. RANGE = 0 means try | ||
10961 | + only at STARTPOS; in general, the last start tried is STARTPOS + | ||
10962 | + RANGE. | ||
10963 | + | ||
10964 | + In REGS, return the indices of the virtual concatenation of STRING1 | ||
10965 | + and STRING2 that matched the entire BUFP->buffer and its contained | ||
10966 | + subexpressions. | ||
10967 | + | ||
10968 | + Do not consider matching one past the index STOP in the virtual | ||
10969 | + concatenation of STRING1 and STRING2. | ||
10970 | + | ||
10971 | + We return either the position in the strings at which the match was | ||
10972 | + found, -1 if no match, or -2 if error (such as failure | ||
10973 | + stack overflow). */ | ||
10974 | + | ||
10975 | +int | ||
10976 | +re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int size1, | ||
10977 | + const char *string2, int size2, int startpos, int range, | ||
10978 | + struct re_registers *regs, int stop) | ||
10979 | +{ | ||
10980 | +# ifdef MBS_SUPPORT | ||
10981 | + if (MB_CUR_MAX != 1) | ||
10982 | + return wcs_re_search_2 (bufp, string1, size1, string2, size2, startpos, | ||
10983 | + range, regs, stop); | ||
10984 | + else | ||
10985 | +# endif | ||
10986 | + return byte_re_search_2 (bufp, string1, size1, string2, size2, startpos, | ||
10987 | + range, regs, stop); | ||
10988 | +} /* re_search_2 */ | ||
10989 | +#ifdef _LIBC | ||
10990 | +weak_alias (__re_search_2, re_search_2) | ||
10991 | +#endif | ||
10992 | + | ||
10993 | +#endif /* not INSIDE_RECURSION */ | ||
10994 | + | ||
10995 | +#ifdef INSIDE_RECURSION | ||
10996 | + | ||
10997 | +#ifdef MATCH_MAY_ALLOCATE | ||
10998 | +# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL | ||
10999 | +#else | ||
11000 | +# define FREE_VAR(var) if (var) free (var); var = NULL | ||
11001 | +#endif | ||
11002 | + | ||
11003 | +#ifdef WCHAR | ||
11004 | +# define MAX_ALLOCA_SIZE 2000 | ||
11005 | + | ||
11006 | +# define FREE_WCS_BUFFERS() \ | ||
11007 | + do { \ | ||
11008 | + if (size1 > MAX_ALLOCA_SIZE) \ | ||
11009 | + { \ | ||
11010 | + free (wcs_string1); \ | ||
11011 | + free (mbs_offset1); \ | ||
11012 | + } \ | ||
11013 | + else \ | ||
11014 | + { \ | ||
11015 | + FREE_VAR (wcs_string1); \ | ||
11016 | + FREE_VAR (mbs_offset1); \ | ||
11017 | + } \ | ||
11018 | + if (size2 > MAX_ALLOCA_SIZE) \ | ||
11019 | + { \ | ||
11020 | + free (wcs_string2); \ | ||
11021 | + free (mbs_offset2); \ | ||
11022 | + } \ | ||
11023 | + else \ | ||
11024 | + { \ | ||
11025 | + FREE_VAR (wcs_string2); \ | ||
11026 | + FREE_VAR (mbs_offset2); \ | ||
11027 | + } \ | ||
11028 | + } while (0) | ||
11029 | + | ||
11030 | +#endif | ||
11031 | + | ||
11032 | + | ||
11033 | +static int | ||
11034 | +PREFIX(re_search_2) (struct re_pattern_buffer *bufp, const char *string1, | ||
11035 | + int size1, const char *string2, int size2, | ||
11036 | + int startpos, int range, | ||
11037 | + struct re_registers *regs, int stop) | ||
11038 | +{ | ||
11039 | + int val; | ||
11040 | + register char *fastmap = bufp->fastmap; | ||
11041 | + register RE_TRANSLATE_TYPE translate = bufp->translate; | ||
11042 | + int total_size = size1 + size2; | ||
11043 | + int endpos = startpos + range; | ||
11044 | +#ifdef WCHAR | ||
11045 | + /* We need wchar_t* buffers correspond to cstring1, cstring2. */ | ||
11046 | + wchar_t *wcs_string1 = NULL, *wcs_string2 = NULL; | ||
11047 | + /* We need the size of wchar_t buffers correspond to csize1, csize2. */ | ||
11048 | + int wcs_size1 = 0, wcs_size2 = 0; | ||
11049 | + /* offset buffer for optimizatoin. See convert_mbs_to_wc. */ | ||
11050 | + int *mbs_offset1 = NULL, *mbs_offset2 = NULL; | ||
11051 | + /* They hold whether each wchar_t is binary data or not. */ | ||
11052 | + char *is_binary = NULL; | ||
11053 | +#endif /* WCHAR */ | ||
11054 | + | ||
11055 | + /* Check for out-of-range STARTPOS. */ | ||
11056 | + if (startpos < 0 || startpos > total_size) | ||
11057 | + return -1; | ||
11058 | + | ||
11059 | + /* Fix up RANGE if it might eventually take us outside | ||
11060 | + the virtual concatenation of STRING1 and STRING2. | ||
11061 | + Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */ | ||
11062 | + if (endpos < 0) | ||
11063 | + range = 0 - startpos; | ||
11064 | + else if (endpos > total_size) | ||
11065 | + range = total_size - startpos; | ||
11066 | + | ||
11067 | + /* If the search isn't to be a backwards one, don't waste time in a | ||
11068 | + search for a pattern that must be anchored. */ | ||
11069 | + if (bufp->used > 0 && range > 0 | ||
11070 | + && ((re_opcode_t) bufp->buffer[0] == begbuf | ||
11071 | + /* `begline' is like `begbuf' if it cannot match at newlines. */ | ||
11072 | + || ((re_opcode_t) bufp->buffer[0] == begline | ||
11073 | + && !bufp->newline_anchor))) | ||
11074 | + { | ||
11075 | + if (startpos > 0) | ||
11076 | + return -1; | ||
11077 | + else | ||
11078 | + range = 1; | ||
11079 | + } | ||
11080 | + | ||
11081 | +#ifdef emacs | ||
11082 | + /* In a forward search for something that starts with \=. | ||
11083 | + don't keep searching past point. */ | ||
11084 | + if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0) | ||
11085 | + { | ||
11086 | + range = PT - startpos; | ||
11087 | + if (range <= 0) | ||
11088 | + return -1; | ||
11089 | + } | ||
11090 | +#endif /* emacs */ | ||
11091 | + | ||
11092 | + /* Update the fastmap now if not correct already. */ | ||
11093 | + if (fastmap && !bufp->fastmap_accurate) | ||
11094 | + if (re_compile_fastmap (bufp) == -2) | ||
11095 | + return -2; | ||
11096 | + | ||
11097 | +#ifdef WCHAR | ||
11098 | + /* Allocate wchar_t array for wcs_string1 and wcs_string2 and | ||
11099 | + fill them with converted string. */ | ||
11100 | + if (size1 != 0) | ||
11101 | + { | ||
11102 | + if (size1 > MAX_ALLOCA_SIZE) | ||
11103 | + { | ||
11104 | + wcs_string1 = TALLOC (size1 + 1, CHAR_T); | ||
11105 | + mbs_offset1 = TALLOC (size1 + 1, int); | ||
11106 | + is_binary = TALLOC (size1 + 1, char); | ||
11107 | + } | ||
11108 | + else | ||
11109 | + { | ||
11110 | + wcs_string1 = REGEX_TALLOC (size1 + 1, CHAR_T); | ||
11111 | + mbs_offset1 = REGEX_TALLOC (size1 + 1, int); | ||
11112 | + is_binary = REGEX_TALLOC (size1 + 1, char); | ||
11113 | + } | ||
11114 | + if (!wcs_string1 || !mbs_offset1 || !is_binary) | ||
11115 | + { | ||
11116 | + if (size1 > MAX_ALLOCA_SIZE) | ||
11117 | + { | ||
11118 | + free (wcs_string1); | ||
11119 | + free (mbs_offset1); | ||
11120 | + free (is_binary); | ||
11121 | + } | ||
11122 | + else | ||
11123 | + { | ||
11124 | + FREE_VAR (wcs_string1); | ||
11125 | + FREE_VAR (mbs_offset1); | ||
11126 | + FREE_VAR (is_binary); | ||
11127 | + } | ||
11128 | + return -2; | ||
11129 | + } | ||
11130 | + wcs_size1 = convert_mbs_to_wcs(wcs_string1, string1, size1, | ||
11131 | + mbs_offset1, is_binary); | ||
11132 | + wcs_string1[wcs_size1] = L'\0'; /* for a sentinel */ | ||
11133 | + if (size1 > MAX_ALLOCA_SIZE) | ||
11134 | + free (is_binary); | ||
11135 | + else | ||
11136 | + FREE_VAR (is_binary); | ||
11137 | + } | ||
11138 | + if (size2 != 0) | ||
11139 | + { | ||
11140 | + if (size2 > MAX_ALLOCA_SIZE) | ||
11141 | + { | ||
11142 | + wcs_string2 = TALLOC (size2 + 1, CHAR_T); | ||
11143 | + mbs_offset2 = TALLOC (size2 + 1, int); | ||
11144 | + is_binary = TALLOC (size2 + 1, char); | ||
11145 | + } | ||
11146 | + else | ||
11147 | + { | ||
11148 | + wcs_string2 = REGEX_TALLOC (size2 + 1, CHAR_T); | ||
11149 | + mbs_offset2 = REGEX_TALLOC (size2 + 1, int); | ||
11150 | + is_binary = REGEX_TALLOC (size2 + 1, char); | ||
11151 | + } | ||
11152 | + if (!wcs_string2 || !mbs_offset2 || !is_binary) | ||
11153 | + { | ||
11154 | + FREE_WCS_BUFFERS (); | ||
11155 | + if (size2 > MAX_ALLOCA_SIZE) | ||
11156 | + free (is_binary); | ||
11157 | + else | ||
11158 | + FREE_VAR (is_binary); | ||
11159 | + return -2; | ||
11160 | + } | ||
11161 | + wcs_size2 = convert_mbs_to_wcs(wcs_string2, string2, size2, | ||
11162 | + mbs_offset2, is_binary); | ||
11163 | + wcs_string2[wcs_size2] = L'\0'; /* for a sentinel */ | ||
11164 | + if (size2 > MAX_ALLOCA_SIZE) | ||
11165 | + free (is_binary); | ||
11166 | + else | ||
11167 | + FREE_VAR (is_binary); | ||
11168 | + } | ||
11169 | +#endif /* WCHAR */ | ||
11170 | + | ||
11171 | + | ||
11172 | + /* Loop through the string, looking for a place to start matching. */ | ||
11173 | + for (;;) | ||
11174 | + { | ||
11175 | + /* If a fastmap is supplied, skip quickly over characters that | ||
11176 | + cannot be the start of a match. If the pattern can match the | ||
11177 | + null string, however, we don't need to skip characters; we want | ||
11178 | + the first null string. */ | ||
11179 | + if (fastmap && startpos < total_size && !bufp->can_be_null) | ||
11180 | + { | ||
11181 | + if (range > 0) /* Searching forwards. */ | ||
11182 | + { | ||
11183 | + register const char *d; | ||
11184 | + register int lim = 0; | ||
11185 | + int irange = range; | ||
11186 | + | ||
11187 | + if (startpos < size1 && startpos + range >= size1) | ||
11188 | + lim = range - (size1 - startpos); | ||
11189 | + | ||
11190 | + d = (startpos >= size1 ? string2 - size1 : string1) + startpos; | ||
11191 | + | ||
11192 | + /* Written out as an if-else to avoid testing `translate' | ||
11193 | + inside the loop. */ | ||
11194 | + if (translate) | ||
11195 | + while (range > lim | ||
11196 | + && !fastmap[(unsigned char) | ||
11197 | + translate[(unsigned char) *d++]]) | ||
11198 | + range--; | ||
11199 | + else | ||
11200 | + while (range > lim && !fastmap[(unsigned char) *d++]) | ||
11201 | + range--; | ||
11202 | + | ||
11203 | + startpos += irange - range; | ||
11204 | + } | ||
11205 | + else /* Searching backwards. */ | ||
11206 | + { | ||
11207 | + register CHAR_T c = (size1 == 0 || startpos >= size1 | ||
11208 | + ? string2[startpos - size1] | ||
11209 | + : string1[startpos]); | ||
11210 | + | ||
11211 | + if (!fastmap[(unsigned char) TRANSLATE (c)]) | ||
11212 | + goto advance; | ||
11213 | + } | ||
11214 | + } | ||
11215 | + | ||
11216 | + /* If can't match the null string, and that's all we have left, fail. */ | ||
11217 | + if (range >= 0 && startpos == total_size && fastmap | ||
11218 | + && !bufp->can_be_null) | ||
11219 | + { | ||
11220 | +#ifdef WCHAR | ||
11221 | + FREE_WCS_BUFFERS (); | ||
11222 | +#endif | ||
11223 | + return -1; | ||
11224 | + } | ||
11225 | + | ||
11226 | +#ifdef WCHAR | ||
11227 | + val = wcs_re_match_2_internal (bufp, string1, size1, string2, | ||
11228 | + size2, startpos, regs, stop, | ||
11229 | + wcs_string1, wcs_size1, | ||
11230 | + wcs_string2, wcs_size2, | ||
11231 | + mbs_offset1, mbs_offset2); | ||
11232 | +#else /* BYTE */ | ||
11233 | + val = byte_re_match_2_internal (bufp, string1, size1, string2, | ||
11234 | + size2, startpos, regs, stop); | ||
11235 | +#endif /* BYTE */ | ||
11236 | + | ||
11237 | +#ifndef REGEX_MALLOC | ||
11238 | +# ifdef C_ALLOCA | ||
11239 | + alloca (0); | ||
11240 | +# endif | ||
11241 | +#endif | ||
11242 | + | ||
11243 | + if (val >= 0) | ||
11244 | + { | ||
11245 | +#ifdef WCHAR | ||
11246 | + FREE_WCS_BUFFERS (); | ||
11247 | +#endif | ||
11248 | + return startpos; | ||
11249 | + } | ||
11250 | + | ||
11251 | + if (val == -2) | ||
11252 | + { | ||
11253 | +#ifdef WCHAR | ||
11254 | + FREE_WCS_BUFFERS (); | ||
11255 | +#endif | ||
11256 | + return -2; | ||
11257 | + } | ||
11258 | + | ||
11259 | + advance: | ||
11260 | + if (!range) | ||
11261 | + break; | ||
11262 | + else if (range > 0) | ||
11263 | + { | ||
11264 | + range--; | ||
11265 | + startpos++; | ||
11266 | + } | ||
11267 | + else | ||
11268 | + { | ||
11269 | + range++; | ||
11270 | + startpos--; | ||
11271 | + } | ||
11272 | + } | ||
11273 | +#ifdef WCHAR | ||
11274 | + FREE_WCS_BUFFERS (); | ||
11275 | +#endif | ||
11276 | + return -1; | ||
11277 | +} | ||
11278 | + | ||
11279 | +#ifdef WCHAR | ||
11280 | +/* This converts PTR, a pointer into one of the search wchar_t strings | ||
11281 | + `string1' and `string2' into an multibyte string offset from the | ||
11282 | + beginning of that string. We use mbs_offset to optimize. | ||
11283 | + See convert_mbs_to_wcs. */ | ||
11284 | +# define POINTER_TO_OFFSET(ptr) \ | ||
11285 | + (FIRST_STRING_P (ptr) \ | ||
11286 | + ? ((regoff_t)(mbs_offset1 != NULL? mbs_offset1[(ptr)-string1] : 0)) \ | ||
11287 | + : ((regoff_t)((mbs_offset2 != NULL? mbs_offset2[(ptr)-string2] : 0) \ | ||
11288 | + + csize1))) | ||
11289 | +#else /* BYTE */ | ||
11290 | +/* This converts PTR, a pointer into one of the search strings `string1' | ||
11291 | + and `string2' into an offset from the beginning of that string. */ | ||
11292 | +# define POINTER_TO_OFFSET(ptr) \ | ||
11293 | + (FIRST_STRING_P (ptr) \ | ||
11294 | + ? ((regoff_t) ((ptr) - string1)) \ | ||
11295 | + : ((regoff_t) ((ptr) - string2 + size1))) | ||
11296 | +#endif /* WCHAR */ | ||
11297 | + | ||
11298 | +/* Macros for dealing with the split strings in re_match_2. */ | ||
11299 | + | ||
11300 | +#define MATCHING_IN_FIRST_STRING (dend == end_match_1) | ||
11301 | + | ||
11302 | +/* Call before fetching a character with *d. This switches over to | ||
11303 | + string2 if necessary. */ | ||
11304 | +#define PREFETCH() \ | ||
11305 | + while (d == dend) \ | ||
11306 | + { \ | ||
11307 | + /* End of string2 => fail. */ \ | ||
11308 | + if (dend == end_match_2) \ | ||
11309 | + goto fail; \ | ||
11310 | + /* End of string1 => advance to string2. */ \ | ||
11311 | + d = string2; \ | ||
11312 | + dend = end_match_2; \ | ||
11313 | + } | ||
11314 | + | ||
11315 | +/* Test if at very beginning or at very end of the virtual concatenation | ||
11316 | + of `string1' and `string2'. If only one string, it's `string2'. */ | ||
11317 | +#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) | ||
11318 | +#define AT_STRINGS_END(d) ((d) == end2) | ||
11319 | + | ||
11320 | + | ||
11321 | +/* Test if D points to a character which is word-constituent. We have | ||
11322 | + two special cases to check for: if past the end of string1, look at | ||
11323 | + the first character in string2; and if before the beginning of | ||
11324 | + string2, look at the last character in string1. */ | ||
11325 | +#ifdef WCHAR | ||
11326 | +/* Use internationalized API instead of SYNTAX. */ | ||
11327 | +# define WORDCHAR_P(d) \ | ||
11328 | + (iswalnum ((wint_t)((d) == end1 ? *string2 \ | ||
11329 | + : (d) == string2 - 1 ? *(end1 - 1) : *(d))) != 0 \ | ||
11330 | + || ((d) == end1 ? *string2 \ | ||
11331 | + : (d) == string2 - 1 ? *(end1 - 1) : *(d)) == L'_') | ||
11332 | +#else /* BYTE */ | ||
11333 | +# define WORDCHAR_P(d) \ | ||
11334 | + (SYNTAX ((d) == end1 ? *string2 \ | ||
11335 | + : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ | ||
11336 | + == Sword) | ||
11337 | +#endif /* WCHAR */ | ||
11338 | + | ||
11339 | +/* Disabled due to a compiler bug -- see comment at case wordbound */ | ||
11340 | +#if 0 | ||
11341 | +/* Test if the character before D and the one at D differ with respect | ||
11342 | + to being word-constituent. */ | ||
11343 | +#define AT_WORD_BOUNDARY(d) \ | ||
11344 | + (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ | ||
11345 | + || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) | ||
11346 | +#endif | ||
11347 | + | ||
11348 | +/* Free everything we malloc. */ | ||
11349 | +#ifdef MATCH_MAY_ALLOCATE | ||
11350 | +# ifdef WCHAR | ||
11351 | +# define FREE_VARIABLES() \ | ||
11352 | + do { \ | ||
11353 | + REGEX_FREE_STACK (fail_stack.stack); \ | ||
11354 | + FREE_VAR (regstart); \ | ||
11355 | + FREE_VAR (regend); \ | ||
11356 | + FREE_VAR (old_regstart); \ | ||
11357 | + FREE_VAR (old_regend); \ | ||
11358 | + FREE_VAR (best_regstart); \ | ||
11359 | + FREE_VAR (best_regend); \ | ||
11360 | + FREE_VAR (reg_info); \ | ||
11361 | + FREE_VAR (reg_dummy); \ | ||
11362 | + FREE_VAR (reg_info_dummy); \ | ||
11363 | + if (!cant_free_wcs_buf) \ | ||
11364 | + { \ | ||
11365 | + FREE_VAR (string1); \ | ||
11366 | + FREE_VAR (string2); \ | ||
11367 | + FREE_VAR (mbs_offset1); \ | ||
11368 | + FREE_VAR (mbs_offset2); \ | ||
11369 | + } \ | ||
11370 | + } while (0) | ||
11371 | +# else /* BYTE */ | ||
11372 | +# define FREE_VARIABLES() \ | ||
11373 | + do { \ | ||
11374 | + REGEX_FREE_STACK (fail_stack.stack); \ | ||
11375 | + FREE_VAR (regstart); \ | ||
11376 | + FREE_VAR (regend); \ | ||
11377 | + FREE_VAR (old_regstart); \ | ||
11378 | + FREE_VAR (old_regend); \ | ||
11379 | + FREE_VAR (best_regstart); \ | ||
11380 | + FREE_VAR (best_regend); \ | ||
11381 | + FREE_VAR (reg_info); \ | ||
11382 | + FREE_VAR (reg_dummy); \ | ||
11383 | + FREE_VAR (reg_info_dummy); \ | ||
11384 | + } while (0) | ||
11385 | +# endif /* WCHAR */ | ||
11386 | +#else | ||
11387 | +# ifdef WCHAR | ||
11388 | +# define FREE_VARIABLES() \ | ||
11389 | + do { \ | ||
11390 | + if (!cant_free_wcs_buf) \ | ||
11391 | + { \ | ||
11392 | + FREE_VAR (string1); \ | ||
11393 | + FREE_VAR (string2); \ | ||
11394 | + FREE_VAR (mbs_offset1); \ | ||
11395 | + FREE_VAR (mbs_offset2); \ | ||
11396 | + } \ | ||
11397 | + } while (0) | ||
11398 | +# else /* BYTE */ | ||
11399 | +# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */ | ||
11400 | +# endif /* WCHAR */ | ||
11401 | +#endif /* not MATCH_MAY_ALLOCATE */ | ||
11402 | + | ||
11403 | +/* These values must meet several constraints. They must not be valid | ||
11404 | + register values; since we have a limit of 255 registers (because | ||
11405 | + we use only one byte in the pattern for the register number), we can | ||
11406 | + use numbers larger than 255. They must differ by 1, because of | ||
11407 | + NUM_FAILURE_ITEMS above. And the value for the lowest register must | ||
11408 | + be larger than the value for the highest register, so we do not try | ||
11409 | + to actually save any registers when none are active. */ | ||
11410 | +#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) | ||
11411 | +#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) | ||
11412 | + | ||
11413 | +#else /* not INSIDE_RECURSION */ | ||
11414 | +/* Matching routines. */ | ||
11415 | + | ||
11416 | +#ifndef emacs /* Emacs never uses this. */ | ||
11417 | +/* re_match is like re_match_2 except it takes only a single string. */ | ||
11418 | + | ||
11419 | +int | ||
11420 | +re_match (struct re_pattern_buffer *bufp, const char *string, | ||
11421 | + int size, int pos, struct re_registers *regs) | ||
11422 | +{ | ||
11423 | + int result; | ||
11424 | +# ifdef MBS_SUPPORT | ||
11425 | + if (MB_CUR_MAX != 1) | ||
11426 | + result = wcs_re_match_2_internal (bufp, NULL, 0, string, size, | ||
11427 | + pos, regs, size, | ||
11428 | + NULL, 0, NULL, 0, NULL, NULL); | ||
11429 | + else | ||
11430 | +# endif | ||
11431 | + result = byte_re_match_2_internal (bufp, NULL, 0, string, size, | ||
11432 | + pos, regs, size); | ||
11433 | +# ifndef REGEX_MALLOC | ||
11434 | +# ifdef C_ALLOCA | ||
11435 | + alloca (0); | ||
11436 | +# endif | ||
11437 | +# endif | ||
11438 | + return result; | ||
11439 | +} | ||
11440 | +# ifdef _LIBC | ||
11441 | +weak_alias (__re_match, re_match) | ||
11442 | +# endif | ||
11443 | +#endif /* not emacs */ | ||
11444 | + | ||
11445 | +#endif /* not INSIDE_RECURSION */ | ||
11446 | + | ||
11447 | +#ifdef INSIDE_RECURSION | ||
11448 | +static boolean PREFIX(group_match_null_string_p) (UCHAR_T **p, | ||
11449 | + UCHAR_T *end, | ||
11450 | + PREFIX(register_info_type) *reg_info); | ||
11451 | +static boolean PREFIX(alt_match_null_string_p) (UCHAR_T *p, | ||
11452 | + UCHAR_T *end, | ||
11453 | + PREFIX(register_info_type) *reg_info); | ||
11454 | +static boolean PREFIX(common_op_match_null_string_p) (UCHAR_T **p, | ||
11455 | + UCHAR_T *end, | ||
11456 | + PREFIX(register_info_type) *reg_info); | ||
11457 | +static int PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, | ||
11458 | + register int len, | ||
11459 | + RE_TRANSLATE_TYPE translate); | ||
11460 | +#else /* not INSIDE_RECURSION */ | ||
11461 | + | ||
11462 | +/* re_match_2 matches the compiled pattern in BUFP against the | ||
11463 | + the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 | ||
11464 | + and SIZE2, respectively). We start matching at POS, and stop | ||
11465 | + matching at STOP. | ||
11466 | + | ||
11467 | + If REGS is non-null and the `no_sub' field of BUFP is nonzero, we | ||
11468 | + store offsets for the substring each group matched in REGS. See the | ||
11469 | + documentation for exactly how many groups we fill. | ||
11470 | + | ||
11471 | + We return -1 if no match, -2 if an internal error (such as the | ||
11472 | + failure stack overflowing). Otherwise, we return the length of the | ||
11473 | + matched substring. */ | ||
11474 | + | ||
11475 | +int | ||
11476 | +re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int size1, | ||
11477 | + const char *string2, int size2, int pos, | ||
11478 | + struct re_registers *regs, int stop) | ||
11479 | +{ | ||
11480 | + int result; | ||
11481 | +# ifdef MBS_SUPPORT | ||
11482 | + if (MB_CUR_MAX != 1) | ||
11483 | + result = wcs_re_match_2_internal (bufp, string1, size1, string2, size2, | ||
11484 | + pos, regs, stop, | ||
11485 | + NULL, 0, NULL, 0, NULL, NULL); | ||
11486 | + else | ||
11487 | +# endif | ||
11488 | + result = byte_re_match_2_internal (bufp, string1, size1, string2, size2, | ||
11489 | + pos, regs, stop); | ||
11490 | + | ||
11491 | +#ifndef REGEX_MALLOC | ||
11492 | +# ifdef C_ALLOCA | ||
11493 | + alloca (0); | ||
11494 | +# endif | ||
11495 | +#endif | ||
11496 | + return result; | ||
11497 | +} | ||
11498 | +#ifdef _LIBC | ||
11499 | +weak_alias (__re_match_2, re_match_2) | ||
11500 | +#endif | ||
11501 | + | ||
11502 | +#endif /* not INSIDE_RECURSION */ | ||
11503 | + | ||
11504 | +#ifdef INSIDE_RECURSION | ||
11505 | + | ||
11506 | +#ifdef WCHAR | ||
11507 | +static int count_mbs_length (int *, int); | ||
11508 | + | ||
11509 | +/* This check the substring (from 0, to length) of the multibyte string, | ||
11510 | + to which offset_buffer correspond. And count how many wchar_t_characters | ||
11511 | + the substring occupy. We use offset_buffer to optimization. | ||
11512 | + See convert_mbs_to_wcs. */ | ||
11513 | + | ||
11514 | +static int | ||
11515 | +count_mbs_length(int *offset_buffer, int length) | ||
11516 | +{ | ||
11517 | + int upper, lower; | ||
11518 | + | ||
11519 | + /* Check whether the size is valid. */ | ||
11520 | + if (length < 0) | ||
11521 | + return -1; | ||
11522 | + | ||
11523 | + if (offset_buffer == NULL) | ||
11524 | + return 0; | ||
11525 | + | ||
11526 | + /* If there are no multibyte character, offset_buffer[i] == i. | ||
11527 | + Optmize for this case. */ | ||
11528 | + if (offset_buffer[length] == length) | ||
11529 | + return length; | ||
11530 | + | ||
11531 | + /* Set up upper with length. (because for all i, offset_buffer[i] >= i) */ | ||
11532 | + upper = length; | ||
11533 | + lower = 0; | ||
11534 | + | ||
11535 | + while (true) | ||
11536 | + { | ||
11537 | + int middle = (lower + upper) / 2; | ||
11538 | + if (middle == lower || middle == upper) | ||
11539 | + break; | ||
11540 | + if (offset_buffer[middle] > length) | ||
11541 | + upper = middle; | ||
11542 | + else if (offset_buffer[middle] < length) | ||
11543 | + lower = middle; | ||
11544 | + else | ||
11545 | + return middle; | ||
11546 | + } | ||
11547 | + | ||
11548 | + return -1; | ||
11549 | +} | ||
11550 | +#endif /* WCHAR */ | ||
11551 | + | ||
11552 | +/* This is a separate function so that we can force an alloca cleanup | ||
11553 | + afterwards. */ | ||
11554 | +#ifdef WCHAR | ||
11555 | +static int | ||
11556 | +wcs_re_match_2_internal (struct re_pattern_buffer *bufp, | ||
11557 | + const char *cstring1, int csize1, | ||
11558 | + const char *cstring2, int csize2, | ||
11559 | + int pos, | ||
11560 | + struct re_registers *regs, | ||
11561 | + int stop, | ||
11562 | + /* string1 == string2 == NULL means string1/2, size1/2 and | ||
11563 | + mbs_offset1/2 need seting up in this function. */ | ||
11564 | + /* We need wchar_t* buffers correspond to cstring1, cstring2. */ | ||
11565 | + wchar_t *string1, int size1, | ||
11566 | + wchar_t *string2, int size2, | ||
11567 | + /* offset buffer for optimizatoin. See convert_mbs_to_wc. */ | ||
11568 | + int *mbs_offset1, int *mbs_offset2) | ||
11569 | +#else /* BYTE */ | ||
11570 | +static int | ||
11571 | +byte_re_match_2_internal (struct re_pattern_buffer *bufp, | ||
11572 | + const char *string1, int size1, | ||
11573 | + const char *string2, int size2, | ||
11574 | + int pos, | ||
11575 | + struct re_registers *regs, int stop) | ||
11576 | +#endif /* BYTE */ | ||
11577 | +{ | ||
11578 | + /* General temporaries. */ | ||
11579 | + int mcnt; | ||
11580 | + UCHAR_T *p1; | ||
11581 | +#ifdef WCHAR | ||
11582 | + /* They hold whether each wchar_t is binary data or not. */ | ||
11583 | + char *is_binary = NULL; | ||
11584 | + /* If true, we can't free string1/2, mbs_offset1/2. */ | ||
11585 | + int cant_free_wcs_buf = 1; | ||
11586 | +#endif /* WCHAR */ | ||
11587 | + | ||
11588 | + /* Just past the end of the corresponding string. */ | ||
11589 | + const CHAR_T *end1, *end2; | ||
11590 | + | ||
11591 | + /* Pointers into string1 and string2, just past the last characters in | ||
11592 | + each to consider matching. */ | ||
11593 | + const CHAR_T *end_match_1, *end_match_2; | ||
11594 | + | ||
11595 | + /* Where we are in the data, and the end of the current string. */ | ||
11596 | + const CHAR_T *d, *dend; | ||
11597 | + | ||
11598 | + /* Where we are in the pattern, and the end of the pattern. */ | ||
11599 | +#ifdef WCHAR | ||
11600 | + UCHAR_T *pattern, *p; | ||
11601 | + register UCHAR_T *pend; | ||
11602 | +#else /* BYTE */ | ||
11603 | + UCHAR_T *p = bufp->buffer; | ||
11604 | + register UCHAR_T *pend = p + bufp->used; | ||
11605 | +#endif /* WCHAR */ | ||
11606 | + | ||
11607 | + /* Mark the opcode just after a start_memory, so we can test for an | ||
11608 | + empty subpattern when we get to the stop_memory. */ | ||
11609 | + UCHAR_T *just_past_start_mem = 0; | ||
11610 | + | ||
11611 | + /* We use this to map every character in the string. */ | ||
11612 | + RE_TRANSLATE_TYPE translate = bufp->translate; | ||
11613 | + | ||
11614 | + /* Failure point stack. Each place that can handle a failure further | ||
11615 | + down the line pushes a failure point on this stack. It consists of | ||
11616 | + restart, regend, and reg_info for all registers corresponding to | ||
11617 | + the subexpressions we're currently inside, plus the number of such | ||
11618 | + registers, and, finally, two char *'s. The first char * is where | ||
11619 | + to resume scanning the pattern; the second one is where to resume | ||
11620 | + scanning the strings. If the latter is zero, the failure point is | ||
11621 | + a ``dummy''; if a failure happens and the failure point is a dummy, | ||
11622 | + it gets discarded and the next next one is tried. */ | ||
11623 | +#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ | ||
11624 | + PREFIX(fail_stack_type) fail_stack; | ||
11625 | +#endif | ||
11626 | +#ifdef DEBUG | ||
11627 | + static unsigned failure_id; | ||
11628 | + unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; | ||
11629 | +#endif | ||
11630 | + | ||
11631 | +#ifdef REL_ALLOC | ||
11632 | + /* This holds the pointer to the failure stack, when | ||
11633 | + it is allocated relocatably. */ | ||
11634 | + fail_stack_elt_t *failure_stack_ptr; | ||
11635 | +#endif | ||
11636 | + | ||
11637 | + /* We fill all the registers internally, independent of what we | ||
11638 | + return, for use in backreferences. The number here includes | ||
11639 | + an element for register zero. */ | ||
11640 | + size_t num_regs = bufp->re_nsub + 1; | ||
11641 | + | ||
11642 | + /* The currently active registers. */ | ||
11643 | + active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG; | ||
11644 | + active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG; | ||
11645 | + | ||
11646 | + /* Information on the contents of registers. These are pointers into | ||
11647 | + the input strings; they record just what was matched (on this | ||
11648 | + attempt) by a subexpression part of the pattern, that is, the | ||
11649 | + regnum-th regstart pointer points to where in the pattern we began | ||
11650 | + matching and the regnum-th regend points to right after where we | ||
11651 | + stopped matching the regnum-th subexpression. (The zeroth register | ||
11652 | + keeps track of what the whole pattern matches.) */ | ||
11653 | +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ | ||
11654 | + const CHAR_T **regstart, **regend; | ||
11655 | +#endif | ||
11656 | + | ||
11657 | + /* If a group that's operated upon by a repetition operator fails to | ||
11658 | + match anything, then the register for its start will need to be | ||
11659 | + restored because it will have been set to wherever in the string we | ||
11660 | + are when we last see its open-group operator. Similarly for a | ||
11661 | + register's end. */ | ||
11662 | +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ | ||
11663 | + const CHAR_T **old_regstart, **old_regend; | ||
11664 | +#endif | ||
11665 | + | ||
11666 | + /* The is_active field of reg_info helps us keep track of which (possibly | ||
11667 | + nested) subexpressions we are currently in. The matched_something | ||
11668 | + field of reg_info[reg_num] helps us tell whether or not we have | ||
11669 | + matched any of the pattern so far this time through the reg_num-th | ||
11670 | + subexpression. These two fields get reset each time through any | ||
11671 | + loop their register is in. */ | ||
11672 | +#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ | ||
11673 | + PREFIX(register_info_type) *reg_info; | ||
11674 | +#endif | ||
11675 | + | ||
11676 | + /* The following record the register info as found in the above | ||
11677 | + variables when we find a match better than any we've seen before. | ||
11678 | + This happens as we backtrack through the failure points, which in | ||
11679 | + turn happens only if we have not yet matched the entire string. */ | ||
11680 | + unsigned best_regs_set = false; | ||
11681 | +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ | ||
11682 | + const CHAR_T **best_regstart, **best_regend; | ||
11683 | +#endif | ||
11684 | + | ||
11685 | + /* Logically, this is `best_regend[0]'. But we don't want to have to | ||
11686 | + allocate space for that if we're not allocating space for anything | ||
11687 | + else (see below). Also, we never need info about register 0 for | ||
11688 | + any of the other register vectors, and it seems rather a kludge to | ||
11689 | + treat `best_regend' differently than the rest. So we keep track of | ||
11690 | + the end of the best match so far in a separate variable. We | ||
11691 | + initialize this to NULL so that when we backtrack the first time | ||
11692 | + and need to test it, it's not garbage. */ | ||
11693 | + const CHAR_T *match_end = NULL; | ||
11694 | + | ||
11695 | + /* This helps SET_REGS_MATCHED avoid doing redundant work. */ | ||
11696 | + int set_regs_matched_done = 0; | ||
11697 | + | ||
11698 | + /* Used when we pop values we don't care about. */ | ||
11699 | +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ | ||
11700 | + const CHAR_T **reg_dummy; | ||
11701 | + PREFIX(register_info_type) *reg_info_dummy; | ||
11702 | +#endif | ||
11703 | + | ||
11704 | +#ifdef DEBUG | ||
11705 | + /* Counts the total number of registers pushed. */ | ||
11706 | + unsigned num_regs_pushed = 0; | ||
11707 | +#endif | ||
11708 | + | ||
11709 | + DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); | ||
11710 | + | ||
11711 | + INIT_FAIL_STACK (); | ||
11712 | + | ||
11713 | +#ifdef MATCH_MAY_ALLOCATE | ||
11714 | + /* Do not bother to initialize all the register variables if there are | ||
11715 | + no groups in the pattern, as it takes a fair amount of time. If | ||
11716 | + there are groups, we include space for register 0 (the whole | ||
11717 | + pattern), even though we never use it, since it simplifies the | ||
11718 | + array indexing. We should fix this. */ | ||
11719 | + if (bufp->re_nsub) | ||
11720 | + { | ||
11721 | + regstart = REGEX_TALLOC (num_regs, const CHAR_T *); | ||
11722 | + regend = REGEX_TALLOC (num_regs, const CHAR_T *); | ||
11723 | + old_regstart = REGEX_TALLOC (num_regs, const CHAR_T *); | ||
11724 | + old_regend = REGEX_TALLOC (num_regs, const CHAR_T *); | ||
11725 | + best_regstart = REGEX_TALLOC (num_regs, const CHAR_T *); | ||
11726 | + best_regend = REGEX_TALLOC (num_regs, const CHAR_T *); | ||
11727 | + reg_info = REGEX_TALLOC (num_regs, PREFIX(register_info_type)); | ||
11728 | + reg_dummy = REGEX_TALLOC (num_regs, const CHAR_T *); | ||
11729 | + reg_info_dummy = REGEX_TALLOC (num_regs, PREFIX(register_info_type)); | ||
11730 | + | ||
11731 | + if (!(regstart && regend && old_regstart && old_regend && reg_info | ||
11732 | + && best_regstart && best_regend && reg_dummy && reg_info_dummy)) | ||
11733 | + { | ||
11734 | + FREE_VARIABLES (); | ||
11735 | + return -2; | ||
11736 | + } | ||
11737 | + } | ||
11738 | + else | ||
11739 | + { | ||
11740 | + /* We must initialize all our variables to NULL, so that | ||
11741 | + `FREE_VARIABLES' doesn't try to free them. */ | ||
11742 | + regstart = regend = old_regstart = old_regend = best_regstart | ||
11743 | + = best_regend = reg_dummy = NULL; | ||
11744 | + reg_info = reg_info_dummy = (PREFIX(register_info_type) *) NULL; | ||
11745 | + } | ||
11746 | +#endif /* MATCH_MAY_ALLOCATE */ | ||
11747 | + | ||
11748 | + /* The starting position is bogus. */ | ||
11749 | +#ifdef WCHAR | ||
11750 | + if (pos < 0 || pos > csize1 + csize2) | ||
11751 | +#else /* BYTE */ | ||
11752 | + if (pos < 0 || pos > size1 + size2) | ||
11753 | +#endif | ||
11754 | + { | ||
11755 | + FREE_VARIABLES (); | ||
11756 | + return -1; | ||
11757 | + } | ||
11758 | + | ||
11759 | +#ifdef WCHAR | ||
11760 | + /* Allocate wchar_t array for string1 and string2 and | ||
11761 | + fill them with converted string. */ | ||
11762 | + if (string1 == NULL && string2 == NULL) | ||
11763 | + { | ||
11764 | + /* We need seting up buffers here. */ | ||
11765 | + | ||
11766 | + /* We must free wcs buffers in this function. */ | ||
11767 | + cant_free_wcs_buf = 0; | ||
11768 | + | ||
11769 | + if (csize1 != 0) | ||
11770 | + { | ||
11771 | + string1 = REGEX_TALLOC (csize1 + 1, CHAR_T); | ||
11772 | + mbs_offset1 = REGEX_TALLOC (csize1 + 1, int); | ||
11773 | + is_binary = REGEX_TALLOC (csize1 + 1, char); | ||
11774 | + if (!string1 || !mbs_offset1 || !is_binary) | ||
11775 | + { | ||
11776 | + FREE_VAR (string1); | ||
11777 | + FREE_VAR (mbs_offset1); | ||
11778 | + FREE_VAR (is_binary); | ||
11779 | + return -2; | ||
11780 | + } | ||
11781 | + } | ||
11782 | + if (csize2 != 0) | ||
11783 | + { | ||
11784 | + string2 = REGEX_TALLOC (csize2 + 1, CHAR_T); | ||
11785 | + mbs_offset2 = REGEX_TALLOC (csize2 + 1, int); | ||
11786 | + is_binary = REGEX_TALLOC (csize2 + 1, char); | ||
11787 | + if (!string2 || !mbs_offset2 || !is_binary) | ||
11788 | + { | ||
11789 | + FREE_VAR (string1); | ||
11790 | + FREE_VAR (mbs_offset1); | ||
11791 | + FREE_VAR (string2); | ||
11792 | + FREE_VAR (mbs_offset2); | ||
11793 | + FREE_VAR (is_binary); | ||
11794 | + return -2; | ||
11795 | + } | ||
11796 | + size2 = convert_mbs_to_wcs(string2, cstring2, csize2, | ||
11797 | + mbs_offset2, is_binary); | ||
11798 | + string2[size2] = L'\0'; /* for a sentinel */ | ||
11799 | + FREE_VAR (is_binary); | ||
11800 | + } | ||
11801 | + } | ||
11802 | + | ||
11803 | + /* We need to cast pattern to (wchar_t*), because we casted this compiled | ||
11804 | + pattern to (char*) in regex_compile. */ | ||
11805 | + p = pattern = (CHAR_T*)bufp->buffer; | ||
11806 | + pend = (CHAR_T*)(bufp->buffer + bufp->used); | ||
11807 | + | ||
11808 | +#endif /* WCHAR */ | ||
11809 | + | ||
11810 | + /* Initialize subexpression text positions to -1 to mark ones that no | ||
11811 | + start_memory/stop_memory has been seen for. Also initialize the | ||
11812 | + register information struct. */ | ||
11813 | + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) | ||
11814 | + { | ||
11815 | + regstart[mcnt] = regend[mcnt] | ||
11816 | + = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; | ||
11817 | + | ||
11818 | + REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; | ||
11819 | + IS_ACTIVE (reg_info[mcnt]) = 0; | ||
11820 | + MATCHED_SOMETHING (reg_info[mcnt]) = 0; | ||
11821 | + EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; | ||
11822 | + } | ||
11823 | + | ||
11824 | + /* We move `string1' into `string2' if the latter's empty -- but not if | ||
11825 | + `string1' is null. */ | ||
11826 | + if (size2 == 0 && string1 != NULL) | ||
11827 | + { | ||
11828 | + string2 = string1; | ||
11829 | + size2 = size1; | ||
11830 | + string1 = 0; | ||
11831 | + size1 = 0; | ||
11832 | +#ifdef WCHAR | ||
11833 | + mbs_offset2 = mbs_offset1; | ||
11834 | + csize2 = csize1; | ||
11835 | + mbs_offset1 = NULL; | ||
11836 | + csize1 = 0; | ||
11837 | +#endif | ||
11838 | + } | ||
11839 | + end1 = string1 + size1; | ||
11840 | + end2 = string2 + size2; | ||
11841 | + | ||
11842 | + /* Compute where to stop matching, within the two strings. */ | ||
11843 | +#ifdef WCHAR | ||
11844 | + if (stop <= csize1) | ||
11845 | + { | ||
11846 | + mcnt = count_mbs_length(mbs_offset1, stop); | ||
11847 | + end_match_1 = string1 + mcnt; | ||
11848 | + end_match_2 = string2; | ||
11849 | + } | ||
11850 | + else | ||
11851 | + { | ||
11852 | + if (stop > csize1 + csize2) | ||
11853 | + stop = csize1 + csize2; | ||
11854 | + end_match_1 = end1; | ||
11855 | + mcnt = count_mbs_length(mbs_offset2, stop-csize1); | ||
11856 | + end_match_2 = string2 + mcnt; | ||
11857 | + } | ||
11858 | + if (mcnt < 0) | ||
11859 | + { /* count_mbs_length return error. */ | ||
11860 | + FREE_VARIABLES (); | ||
11861 | + return -1; | ||
11862 | + } | ||
11863 | +#else | ||
11864 | + if (stop <= size1) | ||
11865 | + { | ||
11866 | + end_match_1 = string1 + stop; | ||
11867 | + end_match_2 = string2; | ||
11868 | + } | ||
11869 | + else | ||
11870 | + { | ||
11871 | + end_match_1 = end1; | ||
11872 | + end_match_2 = string2 + stop - size1; | ||
11873 | + } | ||
11874 | +#endif /* WCHAR */ | ||
11875 | + | ||
11876 | + /* `p' scans through the pattern as `d' scans through the data. | ||
11877 | + `dend' is the end of the input string that `d' points within. `d' | ||
11878 | + is advanced into the following input string whenever necessary, but | ||
11879 | + this happens before fetching; therefore, at the beginning of the | ||
11880 | + loop, `d' can be pointing at the end of a string, but it cannot | ||
11881 | + equal `string2'. */ | ||
11882 | +#ifdef WCHAR | ||
11883 | + if (size1 > 0 && pos <= csize1) | ||
11884 | + { | ||
11885 | + mcnt = count_mbs_length(mbs_offset1, pos); | ||
11886 | + d = string1 + mcnt; | ||
11887 | + dend = end_match_1; | ||
11888 | + } | ||
11889 | + else | ||
11890 | + { | ||
11891 | + mcnt = count_mbs_length(mbs_offset2, pos-csize1); | ||
11892 | + d = string2 + mcnt; | ||
11893 | + dend = end_match_2; | ||
11894 | + } | ||
11895 | + | ||
11896 | + if (mcnt < 0) | ||
11897 | + { /* count_mbs_length return error. */ | ||
11898 | + FREE_VARIABLES (); | ||
11899 | + return -1; | ||
11900 | + } | ||
11901 | +#else | ||
11902 | + if (size1 > 0 && pos <= size1) | ||
11903 | + { | ||
11904 | + d = string1 + pos; | ||
11905 | + dend = end_match_1; | ||
11906 | + } | ||
11907 | + else | ||
11908 | + { | ||
11909 | + d = string2 + pos - size1; | ||
11910 | + dend = end_match_2; | ||
11911 | + } | ||
11912 | +#endif /* WCHAR */ | ||
11913 | + | ||
11914 | + DEBUG_PRINT1 ("The compiled pattern is:\n"); | ||
11915 | + DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); | ||
11916 | + DEBUG_PRINT1 ("The string to match is: `"); | ||
11917 | + DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); | ||
11918 | + DEBUG_PRINT1 ("'\n"); | ||
11919 | + | ||
11920 | + /* This loops over pattern commands. It exits by returning from the | ||
11921 | + function if the match is complete, or it drops through if the match | ||
11922 | + fails at this starting point in the input data. */ | ||
11923 | + for (;;) | ||
11924 | + { | ||
11925 | +#ifdef _LIBC | ||
11926 | + DEBUG_PRINT2 ("\n%p: ", p); | ||
11927 | +#else | ||
11928 | + DEBUG_PRINT2 ("\n0x%x: ", p); | ||
11929 | +#endif | ||
11930 | + | ||
11931 | + if (p == pend) | ||
11932 | + { /* End of pattern means we might have succeeded. */ | ||
11933 | + DEBUG_PRINT1 ("end of pattern ... "); | ||
11934 | + | ||
11935 | + /* If we haven't matched the entire string, and we want the | ||
11936 | + longest match, try backtracking. */ | ||
11937 | + if (d != end_match_2) | ||
11938 | + { | ||
11939 | + /* 1 if this match ends in the same string (string1 or string2) | ||
11940 | + as the best previous match. */ | ||
11941 | + boolean same_str_p = (FIRST_STRING_P (match_end) | ||
11942 | + == MATCHING_IN_FIRST_STRING); | ||
11943 | + /* 1 if this match is the best seen so far. */ | ||
11944 | + boolean best_match_p; | ||
11945 | + | ||
11946 | + /* AIX compiler got confused when this was combined | ||
11947 | + with the previous declaration. */ | ||
11948 | + if (same_str_p) | ||
11949 | + best_match_p = d > match_end; | ||
11950 | + else | ||
11951 | + best_match_p = !MATCHING_IN_FIRST_STRING; | ||
11952 | + | ||
11953 | + DEBUG_PRINT1 ("backtracking.\n"); | ||
11954 | + | ||
11955 | + if (!FAIL_STACK_EMPTY ()) | ||
11956 | + { /* More failure points to try. */ | ||
11957 | + | ||
11958 | + /* If exceeds best match so far, save it. */ | ||
11959 | + if (!best_regs_set || best_match_p) | ||
11960 | + { | ||
11961 | + best_regs_set = true; | ||
11962 | + match_end = d; | ||
11963 | + | ||
11964 | + DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); | ||
11965 | + | ||
11966 | + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) | ||
11967 | + { | ||
11968 | + best_regstart[mcnt] = regstart[mcnt]; | ||
11969 | + best_regend[mcnt] = regend[mcnt]; | ||
11970 | + } | ||
11971 | + } | ||
11972 | + goto fail; | ||
11973 | + } | ||
11974 | + | ||
11975 | + /* If no failure points, don't restore garbage. And if | ||
11976 | + last match is real best match, don't restore second | ||
11977 | + best one. */ | ||
11978 | + else if (best_regs_set && !best_match_p) | ||
11979 | + { | ||
11980 | + restore_best_regs: | ||
11981 | + /* Restore best match. It may happen that `dend == | ||
11982 | + end_match_1' while the restored d is in string2. | ||
11983 | + For example, the pattern `x.*y.*z' against the | ||
11984 | + strings `x-' and `y-z-', if the two strings are | ||
11985 | + not consecutive in memory. */ | ||
11986 | + DEBUG_PRINT1 ("Restoring best registers.\n"); | ||
11987 | + | ||
11988 | + d = match_end; | ||
11989 | + dend = ((d >= string1 && d <= end1) | ||
11990 | + ? end_match_1 : end_match_2); | ||
11991 | + | ||
11992 | + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) | ||
11993 | + { | ||
11994 | + regstart[mcnt] = best_regstart[mcnt]; | ||
11995 | + regend[mcnt] = best_regend[mcnt]; | ||
11996 | + } | ||
11997 | + } | ||
11998 | + } /* d != end_match_2 */ | ||
11999 | + | ||
12000 | + succeed_label: | ||
12001 | + DEBUG_PRINT1 ("Accepting match.\n"); | ||
12002 | + /* If caller wants register contents data back, do it. */ | ||
12003 | + if (regs && !bufp->no_sub) | ||
12004 | + { | ||
12005 | + /* Have the register data arrays been allocated? */ | ||
12006 | + if (bufp->regs_allocated == REGS_UNALLOCATED) | ||
12007 | + { /* No. So allocate them with malloc. We need one | ||
12008 | + extra element beyond `num_regs' for the `-1' marker | ||
12009 | + GNU code uses. */ | ||
12010 | + regs->num_regs = MAX (RE_NREGS, num_regs + 1); | ||
12011 | + regs->start = TALLOC (regs->num_regs, regoff_t); | ||
12012 | + regs->end = TALLOC (regs->num_regs, regoff_t); | ||
12013 | + if (regs->start == NULL || regs->end == NULL) | ||
12014 | + { | ||
12015 | + FREE_VARIABLES (); | ||
12016 | + return -2; | ||
12017 | + } | ||
12018 | + bufp->regs_allocated = REGS_REALLOCATE; | ||
12019 | + } | ||
12020 | + else if (bufp->regs_allocated == REGS_REALLOCATE) | ||
12021 | + { /* Yes. If we need more elements than were already | ||
12022 | + allocated, reallocate them. If we need fewer, just | ||
12023 | + leave it alone. */ | ||
12024 | + if (regs->num_regs < num_regs + 1) | ||
12025 | + { | ||
12026 | + regs->num_regs = num_regs + 1; | ||
12027 | + RETALLOC (regs->start, regs->num_regs, regoff_t); | ||
12028 | + RETALLOC (regs->end, regs->num_regs, regoff_t); | ||
12029 | + if (regs->start == NULL || regs->end == NULL) | ||
12030 | + { | ||
12031 | + FREE_VARIABLES (); | ||
12032 | + return -2; | ||
12033 | + } | ||
12034 | + } | ||
12035 | + } | ||
12036 | + else | ||
12037 | + { | ||
12038 | + /* These braces fend off a "empty body in an else-statement" | ||
12039 | + warning under GCC when assert expands to nothing. */ | ||
12040 | + assert (bufp->regs_allocated == REGS_FIXED); | ||
12041 | + } | ||
12042 | + | ||
12043 | + /* Convert the pointer data in `regstart' and `regend' to | ||
12044 | + indices. Register zero has to be set differently, | ||
12045 | + since we haven't kept track of any info for it. */ | ||
12046 | + if (regs->num_regs > 0) | ||
12047 | + { | ||
12048 | + regs->start[0] = pos; | ||
12049 | +#ifdef WCHAR | ||
12050 | + if (MATCHING_IN_FIRST_STRING) | ||
12051 | + regs->end[0] = mbs_offset1 != NULL ? | ||
12052 | + mbs_offset1[d-string1] : 0; | ||
12053 | + else | ||
12054 | + regs->end[0] = csize1 + (mbs_offset2 != NULL ? | ||
12055 | + mbs_offset2[d-string2] : 0); | ||
12056 | +#else | ||
12057 | + regs->end[0] = (MATCHING_IN_FIRST_STRING | ||
12058 | + ? ((regoff_t) (d - string1)) | ||
12059 | + : ((regoff_t) (d - string2 + size1))); | ||
12060 | +#endif /* WCHAR */ | ||
12061 | + } | ||
12062 | + | ||
12063 | + /* Go through the first `min (num_regs, regs->num_regs)' | ||
12064 | + registers, since that is all we initialized. */ | ||
12065 | + for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs); | ||
12066 | + mcnt++) | ||
12067 | + { | ||
12068 | + if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) | ||
12069 | + regs->start[mcnt] = regs->end[mcnt] = -1; | ||
12070 | + else | ||
12071 | + { | ||
12072 | + regs->start[mcnt] | ||
12073 | + = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]); | ||
12074 | + regs->end[mcnt] | ||
12075 | + = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]); | ||
12076 | + } | ||
12077 | + } | ||
12078 | + | ||
12079 | + /* If the regs structure we return has more elements than | ||
12080 | + were in the pattern, set the extra elements to -1. If | ||
12081 | + we (re)allocated the registers, this is the case, | ||
12082 | + because we always allocate enough to have at least one | ||
12083 | + -1 at the end. */ | ||
12084 | + for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++) | ||
12085 | + regs->start[mcnt] = regs->end[mcnt] = -1; | ||
12086 | + } /* regs && !bufp->no_sub */ | ||
12087 | + | ||
12088 | + DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", | ||
12089 | + nfailure_points_pushed, nfailure_points_popped, | ||
12090 | + nfailure_points_pushed - nfailure_points_popped); | ||
12091 | + DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); | ||
12092 | + | ||
12093 | +#ifdef WCHAR | ||
12094 | + if (MATCHING_IN_FIRST_STRING) | ||
12095 | + mcnt = mbs_offset1 != NULL ? mbs_offset1[d-string1] : 0; | ||
12096 | + else | ||
12097 | + mcnt = (mbs_offset2 != NULL ? mbs_offset2[d-string2] : 0) + | ||
12098 | + csize1; | ||
12099 | + mcnt -= pos; | ||
12100 | +#else | ||
12101 | + mcnt = d - pos - (MATCHING_IN_FIRST_STRING | ||
12102 | + ? string1 | ||
12103 | + : string2 - size1); | ||
12104 | +#endif /* WCHAR */ | ||
12105 | + | ||
12106 | + DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); | ||
12107 | + | ||
12108 | + FREE_VARIABLES (); | ||
12109 | + return mcnt; | ||
12110 | + } | ||
12111 | + | ||
12112 | + /* Otherwise match next pattern command. */ | ||
12113 | + switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) | ||
12114 | + { | ||
12115 | + /* Ignore these. Used to ignore the n of succeed_n's which | ||
12116 | + currently have n == 0. */ | ||
12117 | + case no_op: | ||
12118 | + DEBUG_PRINT1 ("EXECUTING no_op.\n"); | ||
12119 | + break; | ||
12120 | + | ||
12121 | + case succeed: | ||
12122 | + DEBUG_PRINT1 ("EXECUTING succeed.\n"); | ||
12123 | + goto succeed_label; | ||
12124 | + | ||
12125 | + /* Match the next n pattern characters exactly. The following | ||
12126 | + byte in the pattern defines n, and the n bytes after that | ||
12127 | + are the characters to match. */ | ||
12128 | + case exactn: | ||
12129 | +#ifdef MBS_SUPPORT | ||
12130 | + case exactn_bin: | ||
12131 | +#endif | ||
12132 | + mcnt = *p++; | ||
12133 | + DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); | ||
12134 | + | ||
12135 | + /* This is written out as an if-else so we don't waste time | ||
12136 | + testing `translate' inside the loop. */ | ||
12137 | + if (translate) | ||
12138 | + { | ||
12139 | + do | ||
12140 | + { | ||
12141 | + PREFETCH (); | ||
12142 | +#ifdef WCHAR | ||
12143 | + if (*d <= 0xff) | ||
12144 | + { | ||
12145 | + if ((UCHAR_T) translate[(unsigned char) *d++] | ||
12146 | + != (UCHAR_T) *p++) | ||
12147 | + goto fail; | ||
12148 | + } | ||
12149 | + else | ||
12150 | + { | ||
12151 | + if (*d++ != (CHAR_T) *p++) | ||
12152 | + goto fail; | ||
12153 | + } | ||
12154 | +#else | ||
12155 | + if ((UCHAR_T) translate[(unsigned char) *d++] | ||
12156 | + != (UCHAR_T) *p++) | ||
12157 | + goto fail; | ||
12158 | +#endif /* WCHAR */ | ||
12159 | + } | ||
12160 | + while (--mcnt); | ||
12161 | + } | ||
12162 | + else | ||
12163 | + { | ||
12164 | + do | ||
12165 | + { | ||
12166 | + PREFETCH (); | ||
12167 | + if (*d++ != (CHAR_T) *p++) goto fail; | ||
12168 | + } | ||
12169 | + while (--mcnt); | ||
12170 | + } | ||
12171 | + SET_REGS_MATCHED (); | ||
12172 | + break; | ||
12173 | + | ||
12174 | + | ||
12175 | + /* Match any character except possibly a newline or a null. */ | ||
12176 | + case anychar: | ||
12177 | + DEBUG_PRINT1 ("EXECUTING anychar.\n"); | ||
12178 | + | ||
12179 | + PREFETCH (); | ||
12180 | + | ||
12181 | + if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') | ||
12182 | + || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) | ||
12183 | + goto fail; | ||
12184 | + | ||
12185 | + SET_REGS_MATCHED (); | ||
12186 | + DEBUG_PRINT2 (" Matched `%ld'.\n", (long int) *d); | ||
12187 | + d++; | ||
12188 | + break; | ||
12189 | + | ||
12190 | + | ||
12191 | + case charset: | ||
12192 | + case charset_not: | ||
12193 | + { | ||
12194 | + register UCHAR_T c; | ||
12195 | +#ifdef WCHAR | ||
12196 | + unsigned int i, char_class_length, coll_symbol_length, | ||
12197 | + equiv_class_length, ranges_length, chars_length, length; | ||
12198 | + CHAR_T *workp, *workp2, *charset_top; | ||
12199 | +#define WORK_BUFFER_SIZE 128 | ||
12200 | + CHAR_T str_buf[WORK_BUFFER_SIZE]; | ||
12201 | +# ifdef _LIBC | ||
12202 | + uint32_t nrules; | ||
12203 | +# endif /* _LIBC */ | ||
12204 | +#endif /* WCHAR */ | ||
12205 | + boolean negate = (re_opcode_t) *(p - 1) == charset_not; | ||
12206 | + | ||
12207 | + DEBUG_PRINT2 ("EXECUTING charset%s.\n", negate ? "_not" : ""); | ||
12208 | + PREFETCH (); | ||
12209 | + c = TRANSLATE (*d); /* The character to match. */ | ||
12210 | +#ifdef WCHAR | ||
12211 | +# ifdef _LIBC | ||
12212 | + nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); | ||
12213 | +# endif /* _LIBC */ | ||
12214 | + charset_top = p - 1; | ||
12215 | + char_class_length = *p++; | ||
12216 | + coll_symbol_length = *p++; | ||
12217 | + equiv_class_length = *p++; | ||
12218 | + ranges_length = *p++; | ||
12219 | + chars_length = *p++; | ||
12220 | + /* p points charset[6], so the address of the next instruction | ||
12221 | + (charset[l+m+n+2o+k+p']) equals p[l+m+n+2*o+p'], | ||
12222 | + where l=length of char_classes, m=length of collating_symbol, | ||
12223 | + n=equivalence_class, o=length of char_range, | ||
12224 | + p'=length of character. */ | ||
12225 | + workp = p; | ||
12226 | + /* Update p to indicate the next instruction. */ | ||
12227 | + p += char_class_length + coll_symbol_length+ equiv_class_length + | ||
12228 | + 2*ranges_length + chars_length; | ||
12229 | + | ||
12230 | + /* match with char_class? */ | ||
12231 | + for (i = 0; i < char_class_length ; i += CHAR_CLASS_SIZE) | ||
12232 | + { | ||
12233 | + wctype_t wctype; | ||
12234 | + uintptr_t alignedp = ((uintptr_t)workp | ||
12235 | + + __alignof__(wctype_t) - 1) | ||
12236 | + & ~(uintptr_t)(__alignof__(wctype_t) - 1); | ||
12237 | + wctype = *((wctype_t*)alignedp); | ||
12238 | + workp += CHAR_CLASS_SIZE; | ||
12239 | +# ifdef _LIBC | ||
12240 | + if (__iswctype((wint_t)c, wctype)) | ||
12241 | + goto char_set_matched; | ||
12242 | +# else | ||
12243 | + if (iswctype((wint_t)c, wctype)) | ||
12244 | + goto char_set_matched; | ||
12245 | +# endif | ||
12246 | + } | ||
12247 | + | ||
12248 | + /* match with collating_symbol? */ | ||
12249 | +# ifdef _LIBC | ||
12250 | + if (nrules != 0) | ||
12251 | + { | ||
12252 | + const unsigned char *extra = (const unsigned char *) | ||
12253 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); | ||
12254 | + | ||
12255 | + for (workp2 = workp + coll_symbol_length ; workp < workp2 ; | ||
12256 | + workp++) | ||
12257 | + { | ||
12258 | + int32_t *wextra; | ||
12259 | + wextra = (int32_t*)(extra + *workp++); | ||
12260 | + for (i = 0; i < *wextra; ++i) | ||
12261 | + if (TRANSLATE(d[i]) != wextra[1 + i]) | ||
12262 | + break; | ||
12263 | + | ||
12264 | + if (i == *wextra) | ||
12265 | + { | ||
12266 | + /* Update d, however d will be incremented at | ||
12267 | + char_set_matched:, we decrement d here. */ | ||
12268 | + d += i - 1; | ||
12269 | + goto char_set_matched; | ||
12270 | + } | ||
12271 | + } | ||
12272 | + } | ||
12273 | + else /* (nrules == 0) */ | ||
12274 | +# endif | ||
12275 | + /* If we can't look up collation data, we use wcscoll | ||
12276 | + instead. */ | ||
12277 | + { | ||
12278 | + for (workp2 = workp + coll_symbol_length ; workp < workp2 ;) | ||
12279 | + { | ||
12280 | + const CHAR_T *backup_d = d, *backup_dend = dend; | ||
12281 | +# ifdef _LIBC | ||
12282 | + length = __wcslen (workp); | ||
12283 | +# else | ||
12284 | + length = wcslen (workp); | ||
12285 | +# endif | ||
12286 | + | ||
12287 | + /* If wcscoll(the collating symbol, whole string) > 0, | ||
12288 | + any substring of the string never match with the | ||
12289 | + collating symbol. */ | ||
12290 | +# ifdef _LIBC | ||
12291 | + if (__wcscoll (workp, d) > 0) | ||
12292 | +# else | ||
12293 | + if (wcscoll (workp, d) > 0) | ||
12294 | +# endif | ||
12295 | + { | ||
12296 | + workp += length + 1; | ||
12297 | + continue; | ||
12298 | + } | ||
12299 | + | ||
12300 | + /* First, we compare the collating symbol with | ||
12301 | + the first character of the string. | ||
12302 | + If it don't match, we add the next character to | ||
12303 | + the compare buffer in turn. */ | ||
12304 | + for (i = 0 ; i < WORK_BUFFER_SIZE-1 ; i++, d++) | ||
12305 | + { | ||
12306 | + int match; | ||
12307 | + if (d == dend) | ||
12308 | + { | ||
12309 | + if (dend == end_match_2) | ||
12310 | + break; | ||
12311 | + d = string2; | ||
12312 | + dend = end_match_2; | ||
12313 | + } | ||
12314 | + | ||
12315 | + /* add next character to the compare buffer. */ | ||
12316 | + str_buf[i] = TRANSLATE(*d); | ||
12317 | + str_buf[i+1] = '\0'; | ||
12318 | + | ||
12319 | +# ifdef _LIBC | ||
12320 | + match = __wcscoll (workp, str_buf); | ||
12321 | +# else | ||
12322 | + match = wcscoll (workp, str_buf); | ||
12323 | +# endif | ||
12324 | + if (match == 0) | ||
12325 | + goto char_set_matched; | ||
12326 | + | ||
12327 | + if (match < 0) | ||
12328 | + /* (str_buf > workp) indicate (str_buf + X > workp), | ||
12329 | + because for all X (str_buf + X > str_buf). | ||
12330 | + So we don't need continue this loop. */ | ||
12331 | + break; | ||
12332 | + | ||
12333 | + /* Otherwise(str_buf < workp), | ||
12334 | + (str_buf+next_character) may equals (workp). | ||
12335 | + So we continue this loop. */ | ||
12336 | + } | ||
12337 | + /* not matched */ | ||
12338 | + d = backup_d; | ||
12339 | + dend = backup_dend; | ||
12340 | + workp += length + 1; | ||
12341 | + } | ||
12342 | + } | ||
12343 | + /* match with equivalence_class? */ | ||
12344 | +# ifdef _LIBC | ||
12345 | + if (nrules != 0) | ||
12346 | + { | ||
12347 | + const CHAR_T *backup_d = d, *backup_dend = dend; | ||
12348 | + /* Try to match the equivalence class against | ||
12349 | + those known to the collate implementation. */ | ||
12350 | + const int32_t *table; | ||
12351 | + const int32_t *weights; | ||
12352 | + const int32_t *extra; | ||
12353 | + const int32_t *indirect; | ||
12354 | + int32_t idx, idx2; | ||
12355 | + wint_t *cp; | ||
12356 | + size_t len; | ||
12357 | + | ||
12358 | + /* This #include defines a local function! */ | ||
12359 | +# include <locale/weightwc.h> | ||
12360 | + | ||
12361 | + table = (const int32_t *) | ||
12362 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC); | ||
12363 | + weights = (const wint_t *) | ||
12364 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC); | ||
12365 | + extra = (const wint_t *) | ||
12366 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC); | ||
12367 | + indirect = (const int32_t *) | ||
12368 | + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC); | ||
12369 | + | ||
12370 | + /* Write 1 collating element to str_buf, and | ||
12371 | + get its index. */ | ||
12372 | + idx2 = 0; | ||
12373 | + | ||
12374 | + for (i = 0 ; idx2 == 0 && i < WORK_BUFFER_SIZE - 1; i++) | ||
12375 | + { | ||
12376 | + cp = (wint_t*)str_buf; | ||
12377 | + if (d == dend) | ||
12378 | + { | ||
12379 | + if (dend == end_match_2) | ||
12380 | + break; | ||
12381 | + d = string2; | ||
12382 | + dend = end_match_2; | ||
12383 | + } | ||
12384 | + str_buf[i] = TRANSLATE(*(d+i)); | ||
12385 | + str_buf[i+1] = '\0'; /* sentinel */ | ||
12386 | + idx2 = findidx ((const wint_t**)&cp, i); | ||
12387 | + } | ||
12388 | + | ||
12389 | + /* Update d, however d will be incremented at | ||
12390 | + char_set_matched:, we decrement d here. */ | ||
12391 | + d = backup_d + ((wchar_t*)cp - (wchar_t*)str_buf - 1); | ||
12392 | + if (d >= dend) | ||
12393 | + { | ||
12394 | + if (dend == end_match_2) | ||
12395 | + d = dend; | ||
12396 | + else | ||
12397 | + { | ||
12398 | + d = string2; | ||
12399 | + dend = end_match_2; | ||
12400 | + } | ||
12401 | + } | ||
12402 | + | ||
12403 | + len = weights[idx2]; | ||
12404 | + | ||
12405 | + for (workp2 = workp + equiv_class_length ; workp < workp2 ; | ||
12406 | + workp++) | ||
12407 | + { | ||
12408 | + idx = (int32_t)*workp; | ||
12409 | + /* We already checked idx != 0 in regex_compile. */ | ||
12410 | + | ||
12411 | + if (idx2 != 0 && len == weights[idx]) | ||
12412 | + { | ||
12413 | + int cnt = 0; | ||
12414 | + while (cnt < len && (weights[idx + 1 + cnt] | ||
12415 | + == weights[idx2 + 1 + cnt])) | ||
12416 | + ++cnt; | ||
12417 | + | ||
12418 | + if (cnt == len) | ||
12419 | + goto char_set_matched; | ||
12420 | + } | ||
12421 | + } | ||
12422 | + /* not matched */ | ||
12423 | + d = backup_d; | ||
12424 | + dend = backup_dend; | ||
12425 | + } | ||
12426 | + else /* (nrules == 0) */ | ||
12427 | +# endif | ||
12428 | + /* If we can't look up collation data, we use wcscoll | ||
12429 | + instead. */ | ||
12430 | + { | ||
12431 | + for (workp2 = workp + equiv_class_length ; workp < workp2 ;) | ||
12432 | + { | ||
12433 | + const CHAR_T *backup_d = d, *backup_dend = dend; | ||
12434 | +# ifdef _LIBC | ||
12435 | + length = __wcslen (workp); | ||
12436 | +# else | ||
12437 | + length = wcslen (workp); | ||
12438 | +# endif | ||
12439 | + | ||
12440 | + /* If wcscoll(the collating symbol, whole string) > 0, | ||
12441 | + any substring of the string never match with the | ||
12442 | + collating symbol. */ | ||
12443 | +# ifdef _LIBC | ||
12444 | + if (__wcscoll (workp, d) > 0) | ||
12445 | +# else | ||
12446 | + if (wcscoll (workp, d) > 0) | ||
12447 | +# endif | ||
12448 | + { | ||
12449 | + workp += length + 1; | ||
12450 | + break; | ||
12451 | + } | ||
12452 | + | ||
12453 | + /* First, we compare the equivalence class with | ||
12454 | + the first character of the string. | ||
12455 | + If it don't match, we add the next character to | ||
12456 | + the compare buffer in turn. */ | ||
12457 | + for (i = 0 ; i < WORK_BUFFER_SIZE - 1 ; i++, d++) | ||
12458 | + { | ||
12459 | + int match; | ||
12460 | + if (d == dend) | ||
12461 | + { | ||
12462 | + if (dend == end_match_2) | ||
12463 | + break; | ||
12464 | + d = string2; | ||
12465 | + dend = end_match_2; | ||
12466 | + } | ||
12467 | + | ||
12468 | + /* add next character to the compare buffer. */ | ||
12469 | + str_buf[i] = TRANSLATE(*d); | ||
12470 | + str_buf[i+1] = '\0'; | ||
12471 | + | ||
12472 | +# ifdef _LIBC | ||
12473 | + match = __wcscoll (workp, str_buf); | ||
12474 | +# else | ||
12475 | + match = wcscoll (workp, str_buf); | ||
12476 | +# endif | ||
12477 | + | ||
12478 | + if (match == 0) | ||
12479 | + goto char_set_matched; | ||
12480 | + | ||
12481 | + if (match < 0) | ||
12482 | + /* (str_buf > workp) indicate (str_buf + X > workp), | ||
12483 | + because for all X (str_buf + X > str_buf). | ||
12484 | + So we don't need continue this loop. */ | ||
12485 | + break; | ||
12486 | + | ||
12487 | + /* Otherwise(str_buf < workp), | ||
12488 | + (str_buf+next_character) may equals (workp). | ||
12489 | + So we continue this loop. */ | ||
12490 | + } | ||
12491 | + /* not matched */ | ||
12492 | + d = backup_d; | ||
12493 | + dend = backup_dend; | ||
12494 | + workp += length + 1; | ||
12495 | + } | ||
12496 | + } | ||
12497 | + | ||
12498 | + /* match with char_range? */ | ||
12499 | +# ifdef _LIBC | ||
12500 | + if (nrules != 0) | ||
12501 | + { | ||
12502 | + uint32_t collseqval; | ||
12503 | + const char *collseq = (const char *) | ||
12504 | + _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC); | ||
12505 | + | ||
12506 | + collseqval = collseq_table_lookup (collseq, c); | ||
12507 | + | ||
12508 | + for (; workp < p - chars_length ;) | ||
12509 | + { | ||
12510 | + uint32_t start_val, end_val; | ||
12511 | + | ||
12512 | + /* We already compute the collation sequence value | ||
12513 | + of the characters (or collating symbols). */ | ||
12514 | + start_val = (uint32_t) *workp++; /* range_start */ | ||
12515 | + end_val = (uint32_t) *workp++; /* range_end */ | ||
12516 | + | ||
12517 | + if (start_val <= collseqval && collseqval <= end_val) | ||
12518 | + goto char_set_matched; | ||
12519 | + } | ||
12520 | + } | ||
12521 | + else | ||
12522 | +# endif | ||
12523 | + { | ||
12524 | + /* We set range_start_char at str_buf[0], range_end_char | ||
12525 | + at str_buf[4], and compared char at str_buf[2]. */ | ||
12526 | + str_buf[1] = 0; | ||
12527 | + str_buf[2] = c; | ||
12528 | + str_buf[3] = 0; | ||
12529 | + str_buf[5] = 0; | ||
12530 | + for (; workp < p - chars_length ;) | ||
12531 | + { | ||
12532 | + wchar_t *range_start_char, *range_end_char; | ||
12533 | + | ||
12534 | + /* match if (range_start_char <= c <= range_end_char). */ | ||
12535 | + | ||
12536 | + /* If range_start(or end) < 0, we assume -range_start(end) | ||
12537 | + is the offset of the collating symbol which is specified | ||
12538 | + as the character of the range start(end). */ | ||
12539 | + | ||
12540 | + /* range_start */ | ||
12541 | + if (*workp < 0) | ||
12542 | + range_start_char = charset_top - (*workp++); | ||
12543 | + else | ||
12544 | + { | ||
12545 | + str_buf[0] = *workp++; | ||
12546 | + range_start_char = str_buf; | ||
12547 | + } | ||
12548 | + | ||
12549 | + /* range_end */ | ||
12550 | + if (*workp < 0) | ||
12551 | + range_end_char = charset_top - (*workp++); | ||
12552 | + else | ||
12553 | + { | ||
12554 | + str_buf[4] = *workp++; | ||
12555 | + range_end_char = str_buf + 4; | ||
12556 | + } | ||
12557 | + | ||
12558 | +# ifdef _LIBC | ||
12559 | + if (__wcscoll (range_start_char, str_buf+2) <= 0 | ||
12560 | + && __wcscoll (str_buf+2, range_end_char) <= 0) | ||
12561 | +# else | ||
12562 | + if (wcscoll (range_start_char, str_buf+2) <= 0 | ||
12563 | + && wcscoll (str_buf+2, range_end_char) <= 0) | ||
12564 | +# endif | ||
12565 | + goto char_set_matched; | ||
12566 | + } | ||
12567 | + } | ||
12568 | + | ||
12569 | + /* match with char? */ | ||
12570 | + for (; workp < p ; workp++) | ||
12571 | + if (c == *workp) | ||
12572 | + goto char_set_matched; | ||
12573 | + | ||
12574 | + negate = !negate; | ||
12575 | + | ||
12576 | + char_set_matched: | ||
12577 | + if (negate) goto fail; | ||
12578 | +#else | ||
12579 | + /* Cast to `unsigned' instead of `unsigned char' in case the | ||
12580 | + bit list is a full 32 bytes long. */ | ||
12581 | + if (c < (unsigned) (*p * BYTEWIDTH) | ||
12582 | + && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) | ||
12583 | + negate = !negate; | ||
12584 | + | ||
12585 | + p += 1 + *p; | ||
12586 | + | ||
12587 | + if (!negate) goto fail; | ||
12588 | +#undef WORK_BUFFER_SIZE | ||
12589 | +#endif /* WCHAR */ | ||
12590 | + SET_REGS_MATCHED (); | ||
12591 | + d++; | ||
12592 | + break; | ||
12593 | + } | ||
12594 | + | ||
12595 | + | ||
12596 | + /* The beginning of a group is represented by start_memory. | ||
12597 | + The arguments are the register number in the next byte, and the | ||
12598 | + number of groups inner to this one in the next. The text | ||
12599 | + matched within the group is recorded (in the internal | ||
12600 | + registers data structure) under the register number. */ | ||
12601 | + case start_memory: | ||
12602 | + DEBUG_PRINT3 ("EXECUTING start_memory %ld (%ld):\n", | ||
12603 | + (long int) *p, (long int) p[1]); | ||
12604 | + | ||
12605 | + /* Find out if this group can match the empty string. */ | ||
12606 | + p1 = p; /* To send to group_match_null_string_p. */ | ||
12607 | + | ||
12608 | + if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) | ||
12609 | + REG_MATCH_NULL_STRING_P (reg_info[*p]) | ||
12610 | + = PREFIX(group_match_null_string_p) (&p1, pend, reg_info); | ||
12611 | + | ||
12612 | + /* Save the position in the string where we were the last time | ||
12613 | + we were at this open-group operator in case the group is | ||
12614 | + operated upon by a repetition operator, e.g., with `(a*)*b' | ||
12615 | + against `ab'; then we want to ignore where we are now in | ||
12616 | + the string in case this attempt to match fails. */ | ||
12617 | + old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) | ||
12618 | + ? REG_UNSET (regstart[*p]) ? d : regstart[*p] | ||
12619 | + : regstart[*p]; | ||
12620 | + DEBUG_PRINT2 (" old_regstart: %d\n", | ||
12621 | + POINTER_TO_OFFSET (old_regstart[*p])); | ||
12622 | + | ||
12623 | + regstart[*p] = d; | ||
12624 | + DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); | ||
12625 | + | ||
12626 | + IS_ACTIVE (reg_info[*p]) = 1; | ||
12627 | + MATCHED_SOMETHING (reg_info[*p]) = 0; | ||
12628 | + | ||
12629 | + /* Clear this whenever we change the register activity status. */ | ||
12630 | + set_regs_matched_done = 0; | ||
12631 | + | ||
12632 | + /* This is the new highest active register. */ | ||
12633 | + highest_active_reg = *p; | ||
12634 | + | ||
12635 | + /* If nothing was active before, this is the new lowest active | ||
12636 | + register. */ | ||
12637 | + if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) | ||
12638 | + lowest_active_reg = *p; | ||
12639 | + | ||
12640 | + /* Move past the register number and inner group count. */ | ||
12641 | + p += 2; | ||
12642 | + just_past_start_mem = p; | ||
12643 | + | ||
12644 | + break; | ||
12645 | + | ||
12646 | + | ||
12647 | + /* The stop_memory opcode represents the end of a group. Its | ||
12648 | + arguments are the same as start_memory's: the register | ||
12649 | + number, and the number of inner groups. */ | ||
12650 | + case stop_memory: | ||
12651 | + DEBUG_PRINT3 ("EXECUTING stop_memory %ld (%ld):\n", | ||
12652 | + (long int) *p, (long int) p[1]); | ||
12653 | + | ||
12654 | + /* We need to save the string position the last time we were at | ||
12655 | + this close-group operator in case the group is operated | ||
12656 | + upon by a repetition operator, e.g., with `((a*)*(b*)*)*' | ||
12657 | + against `aba'; then we want to ignore where we are now in | ||
12658 | + the string in case this attempt to match fails. */ | ||
12659 | + old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) | ||
12660 | + ? REG_UNSET (regend[*p]) ? d : regend[*p] | ||
12661 | + : regend[*p]; | ||
12662 | + DEBUG_PRINT2 (" old_regend: %d\n", | ||
12663 | + POINTER_TO_OFFSET (old_regend[*p])); | ||
12664 | + | ||
12665 | + regend[*p] = d; | ||
12666 | + DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); | ||
12667 | + | ||
12668 | + /* This register isn't active anymore. */ | ||
12669 | + IS_ACTIVE (reg_info[*p]) = 0; | ||
12670 | + | ||
12671 | + /* Clear this whenever we change the register activity status. */ | ||
12672 | + set_regs_matched_done = 0; | ||
12673 | + | ||
12674 | + /* If this was the only register active, nothing is active | ||
12675 | + anymore. */ | ||
12676 | + if (lowest_active_reg == highest_active_reg) | ||
12677 | + { | ||
12678 | + lowest_active_reg = NO_LOWEST_ACTIVE_REG; | ||
12679 | + highest_active_reg = NO_HIGHEST_ACTIVE_REG; | ||
12680 | + } | ||
12681 | + else | ||
12682 | + { /* We must scan for the new highest active register, since | ||
12683 | + it isn't necessarily one less than now: consider | ||
12684 | + (a(b)c(d(e)f)g). When group 3 ends, after the f), the | ||
12685 | + new highest active register is 1. */ | ||
12686 | + UCHAR_T r = *p - 1; | ||
12687 | + while (r > 0 && !IS_ACTIVE (reg_info[r])) | ||
12688 | + r--; | ||
12689 | + | ||
12690 | + /* If we end up at register zero, that means that we saved | ||
12691 | + the registers as the result of an `on_failure_jump', not | ||
12692 | + a `start_memory', and we jumped to past the innermost | ||
12693 | + `stop_memory'. For example, in ((.)*) we save | ||
12694 | + registers 1 and 2 as a result of the *, but when we pop | ||
12695 | + back to the second ), we are at the stop_memory 1. | ||
12696 | + Thus, nothing is active. */ | ||
12697 | + if (r == 0) | ||
12698 | + { | ||
12699 | + lowest_active_reg = NO_LOWEST_ACTIVE_REG; | ||
12700 | + highest_active_reg = NO_HIGHEST_ACTIVE_REG; | ||
12701 | + } | ||
12702 | + else | ||
12703 | + highest_active_reg = r; | ||
12704 | + } | ||
12705 | + | ||
12706 | + /* If just failed to match something this time around with a | ||
12707 | + group that's operated on by a repetition operator, try to | ||
12708 | + force exit from the ``loop'', and restore the register | ||
12709 | + information for this group that we had before trying this | ||
12710 | + last match. */ | ||
12711 | + if ((!MATCHED_SOMETHING (reg_info[*p]) | ||
12712 | + || just_past_start_mem == p - 1) | ||
12713 | + && (p + 2) < pend) | ||
12714 | + { | ||
12715 | + boolean is_a_jump_n = false; | ||
12716 | + | ||
12717 | + p1 = p + 2; | ||
12718 | + mcnt = 0; | ||
12719 | + switch ((re_opcode_t) *p1++) | ||
12720 | + { | ||
12721 | + case jump_n: | ||
12722 | + is_a_jump_n = true; | ||
12723 | + case pop_failure_jump: | ||
12724 | + case maybe_pop_jump: | ||
12725 | + case jump: | ||
12726 | + case dummy_failure_jump: | ||
12727 | + EXTRACT_NUMBER_AND_INCR (mcnt, p1); | ||
12728 | + if (is_a_jump_n) | ||
12729 | + p1 += OFFSET_ADDRESS_SIZE; | ||
12730 | + break; | ||
12731 | + | ||
12732 | + default: | ||
12733 | + /* do nothing */ ; | ||
12734 | + } | ||
12735 | + p1 += mcnt; | ||
12736 | + | ||
12737 | + /* If the next operation is a jump backwards in the pattern | ||
12738 | + to an on_failure_jump right before the start_memory | ||
12739 | + corresponding to this stop_memory, exit from the loop | ||
12740 | + by forcing a failure after pushing on the stack the | ||
12741 | + on_failure_jump's jump in the pattern, and d. */ | ||
12742 | + if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump | ||
12743 | + && (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == start_memory | ||
12744 | + && p1[2+OFFSET_ADDRESS_SIZE] == *p) | ||
12745 | + { | ||
12746 | + /* If this group ever matched anything, then restore | ||
12747 | + what its registers were before trying this last | ||
12748 | + failed match, e.g., with `(a*)*b' against `ab' for | ||
12749 | + regstart[1], and, e.g., with `((a*)*(b*)*)*' | ||
12750 | + against `aba' for regend[3]. | ||
12751 | + | ||
12752 | + Also restore the registers for inner groups for, | ||
12753 | + e.g., `((a*)(b*))*' against `aba' (register 3 would | ||
12754 | + otherwise get trashed). */ | ||
12755 | + | ||
12756 | + if (EVER_MATCHED_SOMETHING (reg_info[*p])) | ||
12757 | + { | ||
12758 | + unsigned r; | ||
12759 | + | ||
12760 | + EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; | ||
12761 | + | ||
12762 | + /* Restore this and inner groups' (if any) registers. */ | ||
12763 | + for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1); | ||
12764 | + r++) | ||
12765 | + { | ||
12766 | + regstart[r] = old_regstart[r]; | ||
12767 | + | ||
12768 | + /* xx why this test? */ | ||
12769 | + if (old_regend[r] >= regstart[r]) | ||
12770 | + regend[r] = old_regend[r]; | ||
12771 | + } | ||
12772 | + } | ||
12773 | + p1++; | ||
12774 | + EXTRACT_NUMBER_AND_INCR (mcnt, p1); | ||
12775 | + PUSH_FAILURE_POINT (p1 + mcnt, d, -2); | ||
12776 | + | ||
12777 | + goto fail; | ||
12778 | + } | ||
12779 | + } | ||
12780 | + | ||
12781 | + /* Move past the register number and the inner group count. */ | ||
12782 | + p += 2; | ||
12783 | + break; | ||
12784 | + | ||
12785 | + | ||
12786 | + /* \<digit> has been turned into a `duplicate' command which is | ||
12787 | + followed by the numeric value of <digit> as the register number. */ | ||
12788 | + case duplicate: | ||
12789 | + { | ||
12790 | + register const CHAR_T *d2, *dend2; | ||
12791 | + int regno = *p++; /* Get which register to match against. */ | ||
12792 | + DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); | ||
12793 | + | ||
12794 | + /* Can't back reference a group which we've never matched. */ | ||
12795 | + if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) | ||
12796 | + goto fail; | ||
12797 | + | ||
12798 | + /* Where in input to try to start matching. */ | ||
12799 | + d2 = regstart[regno]; | ||
12800 | + | ||
12801 | + /* Where to stop matching; if both the place to start and | ||
12802 | + the place to stop matching are in the same string, then | ||
12803 | + set to the place to stop, otherwise, for now have to use | ||
12804 | + the end of the first string. */ | ||
12805 | + | ||
12806 | + dend2 = ((FIRST_STRING_P (regstart[regno]) | ||
12807 | + == FIRST_STRING_P (regend[regno])) | ||
12808 | + ? regend[regno] : end_match_1); | ||
12809 | + for (;;) | ||
12810 | + { | ||
12811 | + /* If necessary, advance to next segment in register | ||
12812 | + contents. */ | ||
12813 | + while (d2 == dend2) | ||
12814 | + { | ||
12815 | + if (dend2 == end_match_2) break; | ||
12816 | + if (dend2 == regend[regno]) break; | ||
12817 | + | ||
12818 | + /* End of string1 => advance to string2. */ | ||
12819 | + d2 = string2; | ||
12820 | + dend2 = regend[regno]; | ||
12821 | + } | ||
12822 | + /* At end of register contents => success */ | ||
12823 | + if (d2 == dend2) break; | ||
12824 | + | ||
12825 | + /* If necessary, advance to next segment in data. */ | ||
12826 | + PREFETCH (); | ||
12827 | + | ||
12828 | + /* How many characters left in this segment to match. */ | ||
12829 | + mcnt = dend - d; | ||
12830 | + | ||
12831 | + /* Want how many consecutive characters we can match in | ||
12832 | + one shot, so, if necessary, adjust the count. */ | ||
12833 | + if (mcnt > dend2 - d2) | ||
12834 | + mcnt = dend2 - d2; | ||
12835 | + | ||
12836 | + /* Compare that many; failure if mismatch, else move | ||
12837 | + past them. */ | ||
12838 | + if (translate | ||
12839 | + ? PREFIX(bcmp_translate) (d, d2, mcnt, translate) | ||
12840 | + : memcmp (d, d2, mcnt*sizeof(UCHAR_T))) | ||
12841 | + goto fail; | ||
12842 | + d += mcnt, d2 += mcnt; | ||
12843 | + | ||
12844 | + /* Do this because we've match some characters. */ | ||
12845 | + SET_REGS_MATCHED (); | ||
12846 | + } | ||
12847 | + } | ||
12848 | + break; | ||
12849 | + | ||
12850 | + | ||
12851 | + /* begline matches the empty string at the beginning of the string | ||
12852 | + (unless `not_bol' is set in `bufp'), and, if | ||
12853 | + `newline_anchor' is set, after newlines. */ | ||
12854 | + case begline: | ||
12855 | + DEBUG_PRINT1 ("EXECUTING begline.\n"); | ||
12856 | + | ||
12857 | + if (AT_STRINGS_BEG (d)) | ||
12858 | + { | ||
12859 | + if (!bufp->not_bol) break; | ||
12860 | + } | ||
12861 | + else if (d[-1] == '\n' && bufp->newline_anchor) | ||
12862 | + { | ||
12863 | + break; | ||
12864 | + } | ||
12865 | + /* In all other cases, we fail. */ | ||
12866 | + goto fail; | ||
12867 | + | ||
12868 | + | ||
12869 | + /* endline is the dual of begline. */ | ||
12870 | + case endline: | ||
12871 | + DEBUG_PRINT1 ("EXECUTING endline.\n"); | ||
12872 | + | ||
12873 | + if (AT_STRINGS_END (d)) | ||
12874 | + { | ||
12875 | + if (!bufp->not_eol) break; | ||
12876 | + } | ||
12877 | + | ||
12878 | + /* We have to ``prefetch'' the next character. */ | ||
12879 | + else if ((d == end1 ? *string2 : *d) == '\n' | ||
12880 | + && bufp->newline_anchor) | ||
12881 | + { | ||
12882 | + break; | ||
12883 | + } | ||
12884 | + goto fail; | ||
12885 | + | ||
12886 | + | ||
12887 | + /* Match at the very beginning of the data. */ | ||
12888 | + case begbuf: | ||
12889 | + DEBUG_PRINT1 ("EXECUTING begbuf.\n"); | ||
12890 | + if (AT_STRINGS_BEG (d)) | ||
12891 | + break; | ||
12892 | + goto fail; | ||
12893 | + | ||
12894 | + | ||
12895 | + /* Match at the very end of the data. */ | ||
12896 | + case endbuf: | ||
12897 | + DEBUG_PRINT1 ("EXECUTING endbuf.\n"); | ||
12898 | + if (AT_STRINGS_END (d)) | ||
12899 | + break; | ||
12900 | + goto fail; | ||
12901 | + | ||
12902 | + | ||
12903 | + /* on_failure_keep_string_jump is used to optimize `.*\n'. It | ||
12904 | + pushes NULL as the value for the string on the stack. Then | ||
12905 | + `pop_failure_point' will keep the current value for the | ||
12906 | + string, instead of restoring it. To see why, consider | ||
12907 | + matching `foo\nbar' against `.*\n'. The .* matches the foo; | ||
12908 | + then the . fails against the \n. But the next thing we want | ||
12909 | + to do is match the \n against the \n; if we restored the | ||
12910 | + string value, we would be back at the foo. | ||
12911 | + | ||
12912 | + Because this is used only in specific cases, we don't need to | ||
12913 | + check all the things that `on_failure_jump' does, to make | ||
12914 | + sure the right things get saved on the stack. Hence we don't | ||
12915 | + share its code. The only reason to push anything on the | ||
12916 | + stack at all is that otherwise we would have to change | ||
12917 | + `anychar's code to do something besides goto fail in this | ||
12918 | + case; that seems worse than this. */ | ||
12919 | + case on_failure_keep_string_jump: | ||
12920 | + DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); | ||
12921 | + | ||
12922 | + EXTRACT_NUMBER_AND_INCR (mcnt, p); | ||
12923 | +#ifdef _LIBC | ||
12924 | + DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt); | ||
12925 | +#else | ||
12926 | + DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt); | ||
12927 | +#endif | ||
12928 | + | ||
12929 | + PUSH_FAILURE_POINT (p + mcnt, NULL, -2); | ||
12930 | + break; | ||
12931 | + | ||
12932 | + | ||
12933 | + /* Uses of on_failure_jump: | ||
12934 | + | ||
12935 | + Each alternative starts with an on_failure_jump that points | ||
12936 | + to the beginning of the next alternative. Each alternative | ||
12937 | + except the last ends with a jump that in effect jumps past | ||
12938 | + the rest of the alternatives. (They really jump to the | ||
12939 | + ending jump of the following alternative, because tensioning | ||
12940 | + these jumps is a hassle.) | ||
12941 | + | ||
12942 | + Repeats start with an on_failure_jump that points past both | ||
12943 | + the repetition text and either the following jump or | ||
12944 | + pop_failure_jump back to this on_failure_jump. */ | ||
12945 | + case on_failure_jump: | ||
12946 | + on_failure: | ||
12947 | + DEBUG_PRINT1 ("EXECUTING on_failure_jump"); | ||
12948 | + | ||
12949 | + EXTRACT_NUMBER_AND_INCR (mcnt, p); | ||
12950 | +#ifdef _LIBC | ||
12951 | + DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt); | ||
12952 | +#else | ||
12953 | + DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); | ||
12954 | +#endif | ||
12955 | + | ||
12956 | + /* If this on_failure_jump comes right before a group (i.e., | ||
12957 | + the original * applied to a group), save the information | ||
12958 | + for that group and all inner ones, so that if we fail back | ||
12959 | + to this point, the group's information will be correct. | ||
12960 | + For example, in \(a*\)*\1, we need the preceding group, | ||
12961 | + and in \(zz\(a*\)b*\)\2, we need the inner group. */ | ||
12962 | + | ||
12963 | + /* We can't use `p' to check ahead because we push | ||
12964 | + a failure point to `p + mcnt' after we do this. */ | ||
12965 | + p1 = p; | ||
12966 | + | ||
12967 | + /* We need to skip no_op's before we look for the | ||
12968 | + start_memory in case this on_failure_jump is happening as | ||
12969 | + the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 | ||
12970 | + against aba. */ | ||
12971 | + while (p1 < pend && (re_opcode_t) *p1 == no_op) | ||
12972 | + p1++; | ||
12973 | + | ||
12974 | + if (p1 < pend && (re_opcode_t) *p1 == start_memory) | ||
12975 | + { | ||
12976 | + /* We have a new highest active register now. This will | ||
12977 | + get reset at the start_memory we are about to get to, | ||
12978 | + but we will have saved all the registers relevant to | ||
12979 | + this repetition op, as described above. */ | ||
12980 | + highest_active_reg = *(p1 + 1) + *(p1 + 2); | ||
12981 | + if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) | ||
12982 | + lowest_active_reg = *(p1 + 1); | ||
12983 | + } | ||
12984 | + | ||
12985 | + DEBUG_PRINT1 (":\n"); | ||
12986 | + PUSH_FAILURE_POINT (p + mcnt, d, -2); | ||
12987 | + break; | ||
12988 | + | ||
12989 | + | ||
12990 | + /* A smart repeat ends with `maybe_pop_jump'. | ||
12991 | + We change it to either `pop_failure_jump' or `jump'. */ | ||
12992 | + case maybe_pop_jump: | ||
12993 | + EXTRACT_NUMBER_AND_INCR (mcnt, p); | ||
12994 | + DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); | ||
12995 | + { | ||
12996 | + register UCHAR_T *p2 = p; | ||
12997 | + | ||
12998 | + /* Compare the beginning of the repeat with what in the | ||
12999 | + pattern follows its end. If we can establish that there | ||
13000 | + is nothing that they would both match, i.e., that we | ||
13001 | + would have to backtrack because of (as in, e.g., `a*a') | ||
13002 | + then we can change to pop_failure_jump, because we'll | ||
13003 | + never have to backtrack. | ||
13004 | + | ||
13005 | + This is not true in the case of alternatives: in | ||
13006 | + `(a|ab)*' we do need to backtrack to the `ab' alternative | ||
13007 | + (e.g., if the string was `ab'). But instead of trying to | ||
13008 | + detect that here, the alternative has put on a dummy | ||
13009 | + failure point which is what we will end up popping. */ | ||
13010 | + | ||
13011 | + /* Skip over open/close-group commands. | ||
13012 | + If what follows this loop is a ...+ construct, | ||
13013 | + look at what begins its body, since we will have to | ||
13014 | + match at least one of that. */ | ||
13015 | + while (1) | ||
13016 | + { | ||
13017 | + if (p2 + 2 < pend | ||
13018 | + && ((re_opcode_t) *p2 == stop_memory | ||
13019 | + || (re_opcode_t) *p2 == start_memory)) | ||
13020 | + p2 += 3; | ||
13021 | + else if (p2 + 2 + 2 * OFFSET_ADDRESS_SIZE < pend | ||
13022 | + && (re_opcode_t) *p2 == dummy_failure_jump) | ||
13023 | + p2 += 2 + 2 * OFFSET_ADDRESS_SIZE; | ||
13024 | + else | ||
13025 | + break; | ||
13026 | + } | ||
13027 | + | ||
13028 | + p1 = p + mcnt; | ||
13029 | + /* p1[0] ... p1[2] are the `on_failure_jump' corresponding | ||
13030 | + to the `maybe_finalize_jump' of this case. Examine what | ||
13031 | + follows. */ | ||
13032 | + | ||
13033 | + /* If we're at the end of the pattern, we can change. */ | ||
13034 | + if (p2 == pend) | ||
13035 | + { | ||
13036 | + /* Consider what happens when matching ":\(.*\)" | ||
13037 | + against ":/". I don't really understand this code | ||
13038 | + yet. */ | ||
13039 | + p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T) | ||
13040 | + pop_failure_jump; | ||
13041 | + DEBUG_PRINT1 | ||
13042 | + (" End of pattern: change to `pop_failure_jump'.\n"); | ||
13043 | + } | ||
13044 | + | ||
13045 | + else if ((re_opcode_t) *p2 == exactn | ||
13046 | +#ifdef MBS_SUPPORT | ||
13047 | + || (re_opcode_t) *p2 == exactn_bin | ||
13048 | +#endif | ||
13049 | + || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) | ||
13050 | + { | ||
13051 | + register UCHAR_T c | ||
13052 | + = *p2 == (UCHAR_T) endline ? '\n' : p2[2]; | ||
13053 | + | ||
13054 | + if (((re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn | ||
13055 | +#ifdef MBS_SUPPORT | ||
13056 | + || (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn_bin | ||
13057 | +#endif | ||
13058 | + ) && p1[3+OFFSET_ADDRESS_SIZE] != c) | ||
13059 | + { | ||
13060 | + p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T) | ||
13061 | + pop_failure_jump; | ||
13062 | +#ifdef WCHAR | ||
13063 | + DEBUG_PRINT3 (" %C != %C => pop_failure_jump.\n", | ||
13064 | + (wint_t) c, | ||
13065 | + (wint_t) p1[3+OFFSET_ADDRESS_SIZE]); | ||
13066 | +#else | ||
13067 | + DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", | ||
13068 | + (char) c, | ||
13069 | + (char) p1[3+OFFSET_ADDRESS_SIZE]); | ||
13070 | +#endif | ||
13071 | + } | ||
13072 | + | ||
13073 | +#ifndef WCHAR | ||
13074 | + else if ((re_opcode_t) p1[3] == charset | ||
13075 | + || (re_opcode_t) p1[3] == charset_not) | ||
13076 | + { | ||
13077 | + int negate = (re_opcode_t) p1[3] == charset_not; | ||
13078 | + | ||
13079 | + if (c < (unsigned) (p1[4] * BYTEWIDTH) | ||
13080 | + && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) | ||
13081 | + negate = !negate; | ||
13082 | + | ||
13083 | + /* `negate' is equal to 1 if c would match, which means | ||
13084 | + that we can't change to pop_failure_jump. */ | ||
13085 | + if (!negate) | ||
13086 | + { | ||
13087 | + p[-3] = (unsigned char) pop_failure_jump; | ||
13088 | + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); | ||
13089 | + } | ||
13090 | + } | ||
13091 | +#endif /* not WCHAR */ | ||
13092 | + } | ||
13093 | +#ifndef WCHAR | ||
13094 | + else if ((re_opcode_t) *p2 == charset) | ||
13095 | + { | ||
13096 | + /* We win if the first character of the loop is not part | ||
13097 | + of the charset. */ | ||
13098 | + if ((re_opcode_t) p1[3] == exactn | ||
13099 | + && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5] | ||
13100 | + && (p2[2 + p1[5] / BYTEWIDTH] | ||
13101 | + & (1 << (p1[5] % BYTEWIDTH))))) | ||
13102 | + { | ||
13103 | + p[-3] = (unsigned char) pop_failure_jump; | ||
13104 | + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); | ||
13105 | + } | ||
13106 | + | ||
13107 | + else if ((re_opcode_t) p1[3] == charset_not) | ||
13108 | + { | ||
13109 | + int idx; | ||
13110 | + /* We win if the charset_not inside the loop | ||
13111 | + lists every character listed in the charset after. */ | ||
13112 | + for (idx = 0; idx < (int) p2[1]; idx++) | ||
13113 | + if (! (p2[2 + idx] == 0 | ||
13114 | + || (idx < (int) p1[4] | ||
13115 | + && ((p2[2 + idx] & ~ p1[5 + idx]) == 0)))) | ||
13116 | + break; | ||
13117 | + | ||
13118 | + if (idx == p2[1]) | ||
13119 | + { | ||
13120 | + p[-3] = (unsigned char) pop_failure_jump; | ||
13121 | + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); | ||
13122 | + } | ||
13123 | + } | ||
13124 | + else if ((re_opcode_t) p1[3] == charset) | ||
13125 | + { | ||
13126 | + int idx; | ||
13127 | + /* We win if the charset inside the loop | ||
13128 | + has no overlap with the one after the loop. */ | ||
13129 | + for (idx = 0; | ||
13130 | + idx < (int) p2[1] && idx < (int) p1[4]; | ||
13131 | + idx++) | ||
13132 | + if ((p2[2 + idx] & p1[5 + idx]) != 0) | ||
13133 | + break; | ||
13134 | + | ||
13135 | + if (idx == p2[1] || idx == p1[4]) | ||
13136 | + { | ||
13137 | + p[-3] = (unsigned char) pop_failure_jump; | ||
13138 | + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); | ||
13139 | + } | ||
13140 | + } | ||
13141 | + } | ||
13142 | +#endif /* not WCHAR */ | ||
13143 | + } | ||
13144 | + p -= OFFSET_ADDRESS_SIZE; /* Point at relative address again. */ | ||
13145 | + if ((re_opcode_t) p[-1] != pop_failure_jump) | ||
13146 | + { | ||
13147 | + p[-1] = (UCHAR_T) jump; | ||
13148 | + DEBUG_PRINT1 (" Match => jump.\n"); | ||
13149 | + goto unconditional_jump; | ||
13150 | + } | ||
13151 | + /* Note fall through. */ | ||
13152 | + | ||
13153 | + | ||
13154 | + /* The end of a simple repeat has a pop_failure_jump back to | ||
13155 | + its matching on_failure_jump, where the latter will push a | ||
13156 | + failure point. The pop_failure_jump takes off failure | ||
13157 | + points put on by this pop_failure_jump's matching | ||
13158 | + on_failure_jump; we got through the pattern to here from the | ||
13159 | + matching on_failure_jump, so didn't fail. */ | ||
13160 | + case pop_failure_jump: | ||
13161 | + { | ||
13162 | + /* We need to pass separate storage for the lowest and | ||
13163 | + highest registers, even though we don't care about the | ||
13164 | + actual values. Otherwise, we will restore only one | ||
13165 | + register from the stack, since lowest will == highest in | ||
13166 | + `pop_failure_point'. */ | ||
13167 | + active_reg_t dummy_low_reg, dummy_high_reg; | ||
13168 | + UCHAR_T *pdummy = NULL; | ||
13169 | + const CHAR_T *sdummy = NULL; | ||
13170 | + | ||
13171 | + DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); | ||
13172 | + POP_FAILURE_POINT (sdummy, pdummy, | ||
13173 | + dummy_low_reg, dummy_high_reg, | ||
13174 | + reg_dummy, reg_dummy, reg_info_dummy); | ||
13175 | + } | ||
13176 | + /* Note fall through. */ | ||
13177 | + | ||
13178 | + unconditional_jump: | ||
13179 | +#ifdef _LIBC | ||
13180 | + DEBUG_PRINT2 ("\n%p: ", p); | ||
13181 | +#else | ||
13182 | + DEBUG_PRINT2 ("\n0x%x: ", p); | ||
13183 | +#endif | ||
13184 | + /* Note fall through. */ | ||
13185 | + | ||
13186 | + /* Unconditionally jump (without popping any failure points). */ | ||
13187 | + case jump: | ||
13188 | + EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ | ||
13189 | + DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); | ||
13190 | + p += mcnt; /* Do the jump. */ | ||
13191 | +#ifdef _LIBC | ||
13192 | + DEBUG_PRINT2 ("(to %p).\n", p); | ||
13193 | +#else | ||
13194 | + DEBUG_PRINT2 ("(to 0x%x).\n", p); | ||
13195 | +#endif | ||
13196 | + break; | ||
13197 | + | ||
13198 | + | ||
13199 | + /* We need this opcode so we can detect where alternatives end | ||
13200 | + in `group_match_null_string_p' et al. */ | ||
13201 | + case jump_past_alt: | ||
13202 | + DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); | ||
13203 | + goto unconditional_jump; | ||
13204 | + | ||
13205 | + | ||
13206 | + /* Normally, the on_failure_jump pushes a failure point, which | ||
13207 | + then gets popped at pop_failure_jump. We will end up at | ||
13208 | + pop_failure_jump, also, and with a pattern of, say, `a+', we | ||
13209 | + are skipping over the on_failure_jump, so we have to push | ||
13210 | + something meaningless for pop_failure_jump to pop. */ | ||
13211 | + case dummy_failure_jump: | ||
13212 | + DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); | ||
13213 | + /* It doesn't matter what we push for the string here. What | ||
13214 | + the code at `fail' tests is the value for the pattern. */ | ||
13215 | + PUSH_FAILURE_POINT (NULL, NULL, -2); | ||
13216 | + goto unconditional_jump; | ||
13217 | + | ||
13218 | + | ||
13219 | + /* At the end of an alternative, we need to push a dummy failure | ||
13220 | + point in case we are followed by a `pop_failure_jump', because | ||
13221 | + we don't want the failure point for the alternative to be | ||
13222 | + popped. For example, matching `(a|ab)*' against `aab' | ||
13223 | + requires that we match the `ab' alternative. */ | ||
13224 | + case push_dummy_failure: | ||
13225 | + DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); | ||
13226 | + /* See comments just above at `dummy_failure_jump' about the | ||
13227 | + two zeroes. */ | ||
13228 | + PUSH_FAILURE_POINT (NULL, NULL, -2); | ||
13229 | + break; | ||
13230 | + | ||
13231 | + /* Have to succeed matching what follows at least n times. | ||
13232 | + After that, handle like `on_failure_jump'. */ | ||
13233 | + case succeed_n: | ||
13234 | + EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE); | ||
13235 | + DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); | ||
13236 | + | ||
13237 | + assert (mcnt >= 0); | ||
13238 | + /* Originally, this is how many times we HAVE to succeed. */ | ||
13239 | + if (mcnt > 0) | ||
13240 | + { | ||
13241 | + mcnt--; | ||
13242 | + p += OFFSET_ADDRESS_SIZE; | ||
13243 | + STORE_NUMBER_AND_INCR (p, mcnt); | ||
13244 | +#ifdef _LIBC | ||
13245 | + DEBUG_PRINT3 (" Setting %p to %d.\n", p - OFFSET_ADDRESS_SIZE | ||
13246 | + , mcnt); | ||
13247 | +#else | ||
13248 | + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - OFFSET_ADDRESS_SIZE | ||
13249 | + , mcnt); | ||
13250 | +#endif | ||
13251 | + } | ||
13252 | + else if (mcnt == 0) | ||
13253 | + { | ||
13254 | +#ifdef _LIBC | ||
13255 | + DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", | ||
13256 | + p + OFFSET_ADDRESS_SIZE); | ||
13257 | +#else | ||
13258 | + DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", | ||
13259 | + p + OFFSET_ADDRESS_SIZE); | ||
13260 | +#endif /* _LIBC */ | ||
13261 | + | ||
13262 | +#ifdef WCHAR | ||
13263 | + p[1] = (UCHAR_T) no_op; | ||
13264 | +#else | ||
13265 | + p[2] = (UCHAR_T) no_op; | ||
13266 | + p[3] = (UCHAR_T) no_op; | ||
13267 | +#endif /* WCHAR */ | ||
13268 | + goto on_failure; | ||
13269 | + } | ||
13270 | + break; | ||
13271 | + | ||
13272 | + case jump_n: | ||
13273 | + EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE); | ||
13274 | + DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); | ||
13275 | + | ||
13276 | + /* Originally, this is how many times we CAN jump. */ | ||
13277 | + if (mcnt) | ||
13278 | + { | ||
13279 | + mcnt--; | ||
13280 | + STORE_NUMBER (p + OFFSET_ADDRESS_SIZE, mcnt); | ||
13281 | + | ||
13282 | +#ifdef _LIBC | ||
13283 | + DEBUG_PRINT3 (" Setting %p to %d.\n", p + OFFSET_ADDRESS_SIZE, | ||
13284 | + mcnt); | ||
13285 | +#else | ||
13286 | + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + OFFSET_ADDRESS_SIZE, | ||
13287 | + mcnt); | ||
13288 | +#endif /* _LIBC */ | ||
13289 | + goto unconditional_jump; | ||
13290 | + } | ||
13291 | + /* If don't have to jump any more, skip over the rest of command. */ | ||
13292 | + else | ||
13293 | + p += 2 * OFFSET_ADDRESS_SIZE; | ||
13294 | + break; | ||
13295 | + | ||
13296 | + case set_number_at: | ||
13297 | + { | ||
13298 | + DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); | ||
13299 | + | ||
13300 | + EXTRACT_NUMBER_AND_INCR (mcnt, p); | ||
13301 | + p1 = p + mcnt; | ||
13302 | + EXTRACT_NUMBER_AND_INCR (mcnt, p); | ||
13303 | +#ifdef _LIBC | ||
13304 | + DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt); | ||
13305 | +#else | ||
13306 | + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt); | ||
13307 | +#endif | ||
13308 | + STORE_NUMBER (p1, mcnt); | ||
13309 | + break; | ||
13310 | + } | ||
13311 | + | ||
13312 | +#if 0 | ||
13313 | + /* The DEC Alpha C compiler 3.x generates incorrect code for the | ||
13314 | + test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of | ||
13315 | + AT_WORD_BOUNDARY, so this code is disabled. Expanding the | ||
13316 | + macro and introducing temporary variables works around the bug. */ | ||
13317 | + | ||
13318 | + case wordbound: | ||
13319 | + DEBUG_PRINT1 ("EXECUTING wordbound.\n"); | ||
13320 | + if (AT_WORD_BOUNDARY (d)) | ||
13321 | + break; | ||
13322 | + goto fail; | ||
13323 | + | ||
13324 | + case notwordbound: | ||
13325 | + DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); | ||
13326 | + if (AT_WORD_BOUNDARY (d)) | ||
13327 | + goto fail; | ||
13328 | + break; | ||
13329 | +#else | ||
13330 | + case wordbound: | ||
13331 | + { | ||
13332 | + boolean prevchar, thischar; | ||
13333 | + | ||
13334 | + DEBUG_PRINT1 ("EXECUTING wordbound.\n"); | ||
13335 | + if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) | ||
13336 | + break; | ||
13337 | + | ||
13338 | + prevchar = WORDCHAR_P (d - 1); | ||
13339 | + thischar = WORDCHAR_P (d); | ||
13340 | + if (prevchar != thischar) | ||
13341 | + break; | ||
13342 | + goto fail; | ||
13343 | + } | ||
13344 | + | ||
13345 | + case notwordbound: | ||
13346 | + { | ||
13347 | + boolean prevchar, thischar; | ||
13348 | + | ||
13349 | + DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); | ||
13350 | + if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) | ||
13351 | + goto fail; | ||
13352 | + | ||
13353 | + prevchar = WORDCHAR_P (d - 1); | ||
13354 | + thischar = WORDCHAR_P (d); | ||
13355 | + if (prevchar != thischar) | ||
13356 | + goto fail; | ||
13357 | + break; | ||
13358 | + } | ||
13359 | +#endif | ||
13360 | + | ||
13361 | + case wordbeg: | ||
13362 | + DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); | ||
13363 | + if (!AT_STRINGS_END (d) && WORDCHAR_P (d) | ||
13364 | + && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1))) | ||
13365 | + break; | ||
13366 | + goto fail; | ||
13367 | + | ||
13368 | + case wordend: | ||
13369 | + DEBUG_PRINT1 ("EXECUTING wordend.\n"); | ||
13370 | + if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1) | ||
13371 | + && (AT_STRINGS_END (d) || !WORDCHAR_P (d))) | ||
13372 | + break; | ||
13373 | + goto fail; | ||
13374 | + | ||
13375 | +#ifdef emacs | ||
13376 | + case before_dot: | ||
13377 | + DEBUG_PRINT1 ("EXECUTING before_dot.\n"); | ||
13378 | + if (PTR_CHAR_POS ((unsigned char *) d) >= point) | ||
13379 | + goto fail; | ||
13380 | + break; | ||
13381 | + | ||
13382 | + case at_dot: | ||
13383 | + DEBUG_PRINT1 ("EXECUTING at_dot.\n"); | ||
13384 | + if (PTR_CHAR_POS ((unsigned char *) d) != point) | ||
13385 | + goto fail; | ||
13386 | + break; | ||
13387 | + | ||
13388 | + case after_dot: | ||
13389 | + DEBUG_PRINT1 ("EXECUTING after_dot.\n"); | ||
13390 | + if (PTR_CHAR_POS ((unsigned char *) d) <= point) | ||
13391 | + goto fail; | ||
13392 | + break; | ||
13393 | + | ||
13394 | + case syntaxspec: | ||
13395 | + DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); | ||
13396 | + mcnt = *p++; | ||
13397 | + goto matchsyntax; | ||
13398 | + | ||
13399 | + case wordchar: | ||
13400 | + DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); | ||
13401 | + mcnt = (int) Sword; | ||
13402 | + matchsyntax: | ||
13403 | + PREFETCH (); | ||
13404 | + /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ | ||
13405 | + d++; | ||
13406 | + if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt) | ||
13407 | + goto fail; | ||
13408 | + SET_REGS_MATCHED (); | ||
13409 | + break; | ||
13410 | + | ||
13411 | + case notsyntaxspec: | ||
13412 | + DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); | ||
13413 | + mcnt = *p++; | ||
13414 | + goto matchnotsyntax; | ||
13415 | + | ||
13416 | + case notwordchar: | ||
13417 | + DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); | ||
13418 | + mcnt = (int) Sword; | ||
13419 | + matchnotsyntax: | ||
13420 | + PREFETCH (); | ||
13421 | + /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ | ||
13422 | + d++; | ||
13423 | + if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt) | ||
13424 | + goto fail; | ||
13425 | + SET_REGS_MATCHED (); | ||
13426 | + break; | ||
13427 | + | ||
13428 | +#else /* not emacs */ | ||
13429 | + case wordchar: | ||
13430 | + DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); | ||
13431 | + PREFETCH (); | ||
13432 | + if (!WORDCHAR_P (d)) | ||
13433 | + goto fail; | ||
13434 | + SET_REGS_MATCHED (); | ||
13435 | + d++; | ||
13436 | + break; | ||
13437 | + | ||
13438 | + case notwordchar: | ||
13439 | + DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); | ||
13440 | + PREFETCH (); | ||
13441 | + if (WORDCHAR_P (d)) | ||
13442 | + goto fail; | ||
13443 | + SET_REGS_MATCHED (); | ||
13444 | + d++; | ||
13445 | + break; | ||
13446 | +#endif /* not emacs */ | ||
13447 | + | ||
13448 | + default: | ||
13449 | + abort (); | ||
13450 | + } | ||
13451 | + continue; /* Successfully executed one pattern command; keep going. */ | ||
13452 | + | ||
13453 | + | ||
13454 | + /* We goto here if a matching operation fails. */ | ||
13455 | + fail: | ||
13456 | + if (!FAIL_STACK_EMPTY ()) | ||
13457 | + { /* A restart point is known. Restore to that state. */ | ||
13458 | + DEBUG_PRINT1 ("\nFAIL:\n"); | ||
13459 | + POP_FAILURE_POINT (d, p, | ||
13460 | + lowest_active_reg, highest_active_reg, | ||
13461 | + regstart, regend, reg_info); | ||
13462 | + | ||
13463 | + /* If this failure point is a dummy, try the next one. */ | ||
13464 | + if (!p) | ||
13465 | + goto fail; | ||
13466 | + | ||
13467 | + /* If we failed to the end of the pattern, don't examine *p. */ | ||
13468 | + assert (p <= pend); | ||
13469 | + if (p < pend) | ||
13470 | + { | ||
13471 | + boolean is_a_jump_n = false; | ||
13472 | + | ||
13473 | + /* If failed to a backwards jump that's part of a repetition | ||
13474 | + loop, need to pop this failure point and use the next one. */ | ||
13475 | + switch ((re_opcode_t) *p) | ||
13476 | + { | ||
13477 | + case jump_n: | ||
13478 | + is_a_jump_n = true; | ||
13479 | + case maybe_pop_jump: | ||
13480 | + case pop_failure_jump: | ||
13481 | + case jump: | ||
13482 | + p1 = p + 1; | ||
13483 | + EXTRACT_NUMBER_AND_INCR (mcnt, p1); | ||
13484 | + p1 += mcnt; | ||
13485 | + | ||
13486 | + if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) | ||
13487 | + || (!is_a_jump_n | ||
13488 | + && (re_opcode_t) *p1 == on_failure_jump)) | ||
13489 | + goto fail; | ||
13490 | + break; | ||
13491 | + default: | ||
13492 | + /* do nothing */ ; | ||
13493 | + } | ||
13494 | + } | ||
13495 | + | ||
13496 | + if (d >= string1 && d <= end1) | ||
13497 | + dend = end_match_1; | ||
13498 | + } | ||
13499 | + else | ||
13500 | + break; /* Matching at this starting point really fails. */ | ||
13501 | + } /* for (;;) */ | ||
13502 | + | ||
13503 | + if (best_regs_set) | ||
13504 | + goto restore_best_regs; | ||
13505 | + | ||
13506 | + FREE_VARIABLES (); | ||
13507 | + | ||
13508 | + return -1; /* Failure to match. */ | ||
13509 | +} /* re_match_2 */ | ||
13510 | + | ||
13511 | +/* Subroutine definitions for re_match_2. */ | ||
13512 | + | ||
13513 | + | ||
13514 | +/* We are passed P pointing to a register number after a start_memory. | ||
13515 | + | ||
13516 | + Return true if the pattern up to the corresponding stop_memory can | ||
13517 | + match the empty string, and false otherwise. | ||
13518 | + | ||
13519 | + If we find the matching stop_memory, sets P to point to one past its number. | ||
13520 | + Otherwise, sets P to an undefined byte less than or equal to END. | ||
13521 | + | ||
13522 | + We don't handle duplicates properly (yet). */ | ||
13523 | + | ||
13524 | +static boolean | ||
13525 | +PREFIX(group_match_null_string_p) (UCHAR_T **p, UCHAR_T *end, | ||
13526 | + PREFIX(register_info_type) *reg_info) | ||
13527 | +{ | ||
13528 | + int mcnt; | ||
13529 | + /* Point to after the args to the start_memory. */ | ||
13530 | + UCHAR_T *p1 = *p + 2; | ||
13531 | + | ||
13532 | + while (p1 < end) | ||
13533 | + { | ||
13534 | + /* Skip over opcodes that can match nothing, and return true or | ||
13535 | + false, as appropriate, when we get to one that can't, or to the | ||
13536 | + matching stop_memory. */ | ||
13537 | + | ||
13538 | + switch ((re_opcode_t) *p1) | ||
13539 | + { | ||
13540 | + /* Could be either a loop or a series of alternatives. */ | ||
13541 | + case on_failure_jump: | ||
13542 | + p1++; | ||
13543 | + EXTRACT_NUMBER_AND_INCR (mcnt, p1); | ||
13544 | + | ||
13545 | + /* If the next operation is not a jump backwards in the | ||
13546 | + pattern. */ | ||
13547 | + | ||
13548 | + if (mcnt >= 0) | ||
13549 | + { | ||
13550 | + /* Go through the on_failure_jumps of the alternatives, | ||
13551 | + seeing if any of the alternatives cannot match nothing. | ||
13552 | + The last alternative starts with only a jump, | ||
13553 | + whereas the rest start with on_failure_jump and end | ||
13554 | + with a jump, e.g., here is the pattern for `a|b|c': | ||
13555 | + | ||
13556 | + /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 | ||
13557 | + /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 | ||
13558 | + /exactn/1/c | ||
13559 | + | ||
13560 | + So, we have to first go through the first (n-1) | ||
13561 | + alternatives and then deal with the last one separately. */ | ||
13562 | + | ||
13563 | + | ||
13564 | + /* Deal with the first (n-1) alternatives, which start | ||
13565 | + with an on_failure_jump (see above) that jumps to right | ||
13566 | + past a jump_past_alt. */ | ||
13567 | + | ||
13568 | + while ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] == | ||
13569 | + jump_past_alt) | ||
13570 | + { | ||
13571 | + /* `mcnt' holds how many bytes long the alternative | ||
13572 | + is, including the ending `jump_past_alt' and | ||
13573 | + its number. */ | ||
13574 | + | ||
13575 | + if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt - | ||
13576 | + (1 + OFFSET_ADDRESS_SIZE), | ||
13577 | + reg_info)) | ||
13578 | + return false; | ||
13579 | + | ||
13580 | + /* Move to right after this alternative, including the | ||
13581 | + jump_past_alt. */ | ||
13582 | + p1 += mcnt; | ||
13583 | + | ||
13584 | + /* Break if it's the beginning of an n-th alternative | ||
13585 | + that doesn't begin with an on_failure_jump. */ | ||
13586 | + if ((re_opcode_t) *p1 != on_failure_jump) | ||
13587 | + break; | ||
13588 | + | ||
13589 | + /* Still have to check that it's not an n-th | ||
13590 | + alternative that starts with an on_failure_jump. */ | ||
13591 | + p1++; | ||
13592 | + EXTRACT_NUMBER_AND_INCR (mcnt, p1); | ||
13593 | + if ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] != | ||
13594 | + jump_past_alt) | ||
13595 | + { | ||
13596 | + /* Get to the beginning of the n-th alternative. */ | ||
13597 | + p1 -= 1 + OFFSET_ADDRESS_SIZE; | ||
13598 | + break; | ||
13599 | + } | ||
13600 | + } | ||
13601 | + | ||
13602 | + /* Deal with the last alternative: go back and get number | ||
13603 | + of the `jump_past_alt' just before it. `mcnt' contains | ||
13604 | + the length of the alternative. */ | ||
13605 | + EXTRACT_NUMBER (mcnt, p1 - OFFSET_ADDRESS_SIZE); | ||
13606 | + | ||
13607 | + if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt, reg_info)) | ||
13608 | + return false; | ||
13609 | + | ||
13610 | + p1 += mcnt; /* Get past the n-th alternative. */ | ||
13611 | + } /* if mcnt > 0 */ | ||
13612 | + break; | ||
13613 | + | ||
13614 | + | ||
13615 | + case stop_memory: | ||
13616 | + assert (p1[1] == **p); | ||
13617 | + *p = p1 + 2; | ||
13618 | + return true; | ||
13619 | + | ||
13620 | + | ||
13621 | + default: | ||
13622 | + if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info)) | ||
13623 | + return false; | ||
13624 | + } | ||
13625 | + } /* while p1 < end */ | ||
13626 | + | ||
13627 | + return false; | ||
13628 | +} /* group_match_null_string_p */ | ||
13629 | + | ||
13630 | + | ||
13631 | +/* Similar to group_match_null_string_p, but doesn't deal with alternatives: | ||
13632 | + It expects P to be the first byte of a single alternative and END one | ||
13633 | + byte past the last. The alternative can contain groups. */ | ||
13634 | + | ||
13635 | +static boolean | ||
13636 | +PREFIX(alt_match_null_string_p) (UCHAR_T *p, UCHAR_T *end, | ||
13637 | + PREFIX(register_info_type) *reg_info) | ||
13638 | +{ | ||
13639 | + int mcnt; | ||
13640 | + UCHAR_T *p1 = p; | ||
13641 | + | ||
13642 | + while (p1 < end) | ||
13643 | + { | ||
13644 | + /* Skip over opcodes that can match nothing, and break when we get | ||
13645 | + to one that can't. */ | ||
13646 | + | ||
13647 | + switch ((re_opcode_t) *p1) | ||
13648 | + { | ||
13649 | + /* It's a loop. */ | ||
13650 | + case on_failure_jump: | ||
13651 | + p1++; | ||
13652 | + EXTRACT_NUMBER_AND_INCR (mcnt, p1); | ||
13653 | + p1 += mcnt; | ||
13654 | + break; | ||
13655 | + | ||
13656 | + default: | ||
13657 | + if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info)) | ||
13658 | + return false; | ||
13659 | + } | ||
13660 | + } /* while p1 < end */ | ||
13661 | + | ||
13662 | + return true; | ||
13663 | +} /* alt_match_null_string_p */ | ||
13664 | + | ||
13665 | + | ||
13666 | +/* Deals with the ops common to group_match_null_string_p and | ||
13667 | + alt_match_null_string_p. | ||
13668 | + | ||
13669 | + Sets P to one after the op and its arguments, if any. */ | ||
13670 | + | ||
13671 | +static boolean | ||
13672 | +PREFIX(common_op_match_null_string_p) (UCHAR_T **p, UCHAR_T *end, | ||
13673 | + PREFIX(register_info_type) *reg_info) | ||
13674 | +{ | ||
13675 | + int mcnt; | ||
13676 | + boolean ret; | ||
13677 | + int reg_no; | ||
13678 | + UCHAR_T *p1 = *p; | ||
13679 | + | ||
13680 | + switch ((re_opcode_t) *p1++) | ||
13681 | + { | ||
13682 | + case no_op: | ||
13683 | + case begline: | ||
13684 | + case endline: | ||
13685 | + case begbuf: | ||
13686 | + case endbuf: | ||
13687 | + case wordbeg: | ||
13688 | + case wordend: | ||
13689 | + case wordbound: | ||
13690 | + case notwordbound: | ||
13691 | +#ifdef emacs | ||
13692 | + case before_dot: | ||
13693 | + case at_dot: | ||
13694 | + case after_dot: | ||
13695 | +#endif | ||
13696 | + break; | ||
13697 | + | ||
13698 | + case start_memory: | ||
13699 | + reg_no = *p1; | ||
13700 | + assert (reg_no > 0 && reg_no <= MAX_REGNUM); | ||
13701 | + ret = PREFIX(group_match_null_string_p) (&p1, end, reg_info); | ||
13702 | + | ||
13703 | + /* Have to set this here in case we're checking a group which | ||
13704 | + contains a group and a back reference to it. */ | ||
13705 | + | ||
13706 | + if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) | ||
13707 | + REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; | ||
13708 | + | ||
13709 | + if (!ret) | ||
13710 | + return false; | ||
13711 | + break; | ||
13712 | + | ||
13713 | + /* If this is an optimized succeed_n for zero times, make the jump. */ | ||
13714 | + case jump: | ||
13715 | + EXTRACT_NUMBER_AND_INCR (mcnt, p1); | ||
13716 | + if (mcnt >= 0) | ||
13717 | + p1 += mcnt; | ||
13718 | + else | ||
13719 | + return false; | ||
13720 | + break; | ||
13721 | + | ||
13722 | + case succeed_n: | ||
13723 | + /* Get to the number of times to succeed. */ | ||
13724 | + p1 += OFFSET_ADDRESS_SIZE; | ||
13725 | + EXTRACT_NUMBER_AND_INCR (mcnt, p1); | ||
13726 | + | ||
13727 | + if (mcnt == 0) | ||
13728 | + { | ||
13729 | + p1 -= 2 * OFFSET_ADDRESS_SIZE; | ||
13730 | + EXTRACT_NUMBER_AND_INCR (mcnt, p1); | ||
13731 | + p1 += mcnt; | ||
13732 | + } | ||
13733 | + else | ||
13734 | + return false; | ||
13735 | + break; | ||
13736 | + | ||
13737 | + case duplicate: | ||
13738 | + if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) | ||
13739 | + return false; | ||
13740 | + break; | ||
13741 | + | ||
13742 | + case set_number_at: | ||
13743 | + p1 += 2 * OFFSET_ADDRESS_SIZE; | ||
13744 | + | ||
13745 | + default: | ||
13746 | + /* All other opcodes mean we cannot match the empty string. */ | ||
13747 | + return false; | ||
13748 | + } | ||
13749 | + | ||
13750 | + *p = p1; | ||
13751 | + return true; | ||
13752 | +} /* common_op_match_null_string_p */ | ||
13753 | + | ||
13754 | + | ||
13755 | +/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN | ||
13756 | + bytes; nonzero otherwise. */ | ||
13757 | + | ||
13758 | +static int | ||
13759 | +PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, register int len, | ||
13760 | + RE_TRANSLATE_TYPE translate) | ||
13761 | +{ | ||
13762 | + register const UCHAR_T *p1 = (const UCHAR_T *) s1; | ||
13763 | + register const UCHAR_T *p2 = (const UCHAR_T *) s2; | ||
13764 | + while (len) | ||
13765 | + { | ||
13766 | +#ifdef WCHAR | ||
13767 | + if (((*p1<=0xff)?translate[*p1++]:*p1++) | ||
13768 | + != ((*p2<=0xff)?translate[*p2++]:*p2++)) | ||
13769 | + return 1; | ||
13770 | +#else /* BYTE */ | ||
13771 | + if (translate[*p1++] != translate[*p2++]) return 1; | ||
13772 | +#endif /* WCHAR */ | ||
13773 | + len--; | ||
13774 | + } | ||
13775 | + return 0; | ||
13776 | +} | ||
13777 | + | ||
13778 | + | ||
13779 | +#else /* not INSIDE_RECURSION */ | ||
13780 | + | ||
13781 | +/* Entry points for GNU code. */ | ||
13782 | + | ||
13783 | +/* re_compile_pattern is the GNU regular expression compiler: it | ||
13784 | + compiles PATTERN (of length SIZE) and puts the result in BUFP. | ||
13785 | + Returns 0 if the pattern was valid, otherwise an error string. | ||
13786 | + | ||
13787 | + Assumes the `allocated' (and perhaps `buffer') and `translate' fields | ||
13788 | + are set in BUFP on entry. | ||
13789 | + | ||
13790 | + We call regex_compile to do the actual compilation. */ | ||
13791 | + | ||
13792 | +const char * | ||
13793 | +re_compile_pattern (const char *pattern, size_t length, | ||
13794 | + struct re_pattern_buffer *bufp) | ||
13795 | +{ | ||
13796 | + reg_errcode_t ret; | ||
13797 | + | ||
13798 | + /* GNU code is written to assume at least RE_NREGS registers will be set | ||
13799 | + (and at least one extra will be -1). */ | ||
13800 | + bufp->regs_allocated = REGS_UNALLOCATED; | ||
13801 | + | ||
13802 | + /* And GNU code determines whether or not to get register information | ||
13803 | + by passing null for the REGS argument to re_match, etc., not by | ||
13804 | + setting no_sub. */ | ||
13805 | + bufp->no_sub = 0; | ||
13806 | + | ||
13807 | + /* Match anchors at newline. */ | ||
13808 | + bufp->newline_anchor = 1; | ||
13809 | + | ||
13810 | +# ifdef MBS_SUPPORT | ||
13811 | + if (MB_CUR_MAX != 1) | ||
13812 | + ret = wcs_regex_compile (pattern, length, re_syntax_options, bufp); | ||
13813 | + else | ||
13814 | +# endif | ||
13815 | + ret = byte_regex_compile (pattern, length, re_syntax_options, bufp); | ||
13816 | + | ||
13817 | + if (!ret) | ||
13818 | + return NULL; | ||
13819 | + return gettext (re_error_msgid[(int) ret]); | ||
13820 | +} | ||
13821 | +#ifdef _LIBC | ||
13822 | +weak_alias (__re_compile_pattern, re_compile_pattern) | ||
13823 | +#endif | ||
13824 | + | ||
13825 | +/* Entry points compatible with 4.2 BSD regex library. We don't define | ||
13826 | + them unless specifically requested. */ | ||
13827 | + | ||
13828 | +#if defined _REGEX_RE_COMP || defined _LIBC | ||
13829 | + | ||
13830 | +/* BSD has one and only one pattern buffer. */ | ||
13831 | +static struct re_pattern_buffer re_comp_buf; | ||
13832 | + | ||
13833 | +char * | ||
13834 | +#ifdef _LIBC | ||
13835 | +/* Make these definitions weak in libc, so POSIX programs can redefine | ||
13836 | + these names if they don't use our functions, and still use | ||
13837 | + regcomp/regexec below without link errors. */ | ||
13838 | +weak_function | ||
13839 | +#endif | ||
13840 | +re_comp (const char *s) | ||
13841 | +{ | ||
13842 | + reg_errcode_t ret; | ||
13843 | + | ||
13844 | + if (!s) | ||
13845 | + { | ||
13846 | + if (!re_comp_buf.buffer) | ||
13847 | + return (char *) gettext ("No previous regular expression"); | ||
13848 | + return 0; | ||
13849 | + } | ||
13850 | + | ||
13851 | + if (!re_comp_buf.buffer) | ||
13852 | + { | ||
13853 | + re_comp_buf.buffer = (unsigned char *) malloc (200); | ||
13854 | + if (re_comp_buf.buffer == NULL) | ||
13855 | + return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); | ||
13856 | + re_comp_buf.allocated = 200; | ||
13857 | + | ||
13858 | + re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); | ||
13859 | + if (re_comp_buf.fastmap == NULL) | ||
13860 | + return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); | ||
13861 | + } | ||
13862 | + | ||
13863 | + /* Since `re_exec' always passes NULL for the `regs' argument, we | ||
13864 | + don't need to initialize the pattern buffer fields which affect it. */ | ||
13865 | + | ||
13866 | + /* Match anchors at newlines. */ | ||
13867 | + re_comp_buf.newline_anchor = 1; | ||
13868 | + | ||
13869 | +# ifdef MBS_SUPPORT | ||
13870 | + if (MB_CUR_MAX != 1) | ||
13871 | + ret = wcs_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); | ||
13872 | + else | ||
13873 | +# endif | ||
13874 | + ret = byte_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); | ||
13875 | + | ||
13876 | + if (!ret) | ||
13877 | + return NULL; | ||
13878 | + | ||
13879 | + /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ | ||
13880 | + return (char *) gettext (re_error_msgid[(int) ret]); | ||
13881 | +} | ||
13882 | + | ||
13883 | + | ||
13884 | +int | ||
13885 | +#ifdef _LIBC | ||
13886 | +weak_function | ||
13887 | +#endif | ||
13888 | +re_exec (const char *s) | ||
13889 | +{ | ||
13890 | + const int len = strlen (s); | ||
13891 | + return | ||
13892 | + 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); | ||
13893 | +} | ||
13894 | + | ||
13895 | +#endif /* _REGEX_RE_COMP */ | ||
13896 | + | ||
13897 | +/* POSIX.2 functions. Don't define these for Emacs. */ | ||
13898 | + | ||
13899 | +#ifndef emacs | ||
13900 | + | ||
13901 | +/* regcomp takes a regular expression as a string and compiles it. | ||
13902 | + | ||
13903 | + PREG is a regex_t *. We do not expect any fields to be initialized, | ||
13904 | + since POSIX says we shouldn't. Thus, we set | ||
13905 | + | ||
13906 | + `buffer' to the compiled pattern; | ||
13907 | + `used' to the length of the compiled pattern; | ||
13908 | + `syntax' to RE_SYNTAX_POSIX_EXTENDED if the | ||
13909 | + REG_EXTENDED bit in CFLAGS is set; otherwise, to | ||
13910 | + RE_SYNTAX_POSIX_BASIC; | ||
13911 | + `newline_anchor' to REG_NEWLINE being set in CFLAGS; | ||
13912 | + `fastmap' to an allocated space for the fastmap; | ||
13913 | + `fastmap_accurate' to zero; | ||
13914 | + `re_nsub' to the number of subexpressions in PATTERN. | ||
13915 | + | ||
13916 | + PATTERN is the address of the pattern string. | ||
13917 | + | ||
13918 | + CFLAGS is a series of bits which affect compilation. | ||
13919 | + | ||
13920 | + If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we | ||
13921 | + use POSIX basic syntax. | ||
13922 | + | ||
13923 | + If REG_NEWLINE is set, then . and [^...] don't match newline. | ||
13924 | + Also, regexec will try a match beginning after every newline. | ||
13925 | + | ||
13926 | + If REG_ICASE is set, then we considers upper- and lowercase | ||
13927 | + versions of letters to be equivalent when matching. | ||
13928 | + | ||
13929 | + If REG_NOSUB is set, then when PREG is passed to regexec, that | ||
13930 | + routine will report only success or failure, and nothing about the | ||
13931 | + registers. | ||
13932 | + | ||
13933 | + It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for | ||
13934 | + the return codes and their meanings.) */ | ||
13935 | + | ||
13936 | +int | ||
13937 | +regcomp (regex_t *preg, const char *pattern, int cflags) | ||
13938 | +{ | ||
13939 | + reg_errcode_t ret; | ||
13940 | + reg_syntax_t syntax | ||
13941 | + = (cflags & REG_EXTENDED) ? | ||
13942 | + RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; | ||
13943 | + | ||
13944 | + /* regex_compile will allocate the space for the compiled pattern. */ | ||
13945 | + preg->buffer = 0; | ||
13946 | + preg->allocated = 0; | ||
13947 | + preg->used = 0; | ||
13948 | + | ||
13949 | + /* Try to allocate space for the fastmap. */ | ||
13950 | + preg->fastmap = (char *) malloc (1 << BYTEWIDTH); | ||
13951 | + | ||
13952 | + if (cflags & REG_ICASE) | ||
13953 | + { | ||
13954 | + int i; | ||
13955 | + | ||
13956 | + preg->translate | ||
13957 | + = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE | ||
13958 | + * sizeof (*(RE_TRANSLATE_TYPE)0)); | ||
13959 | + if (preg->translate == NULL) | ||
13960 | + return (int) REG_ESPACE; | ||
13961 | + | ||
13962 | + /* Map uppercase characters to corresponding lowercase ones. */ | ||
13963 | + for (i = 0; i < CHAR_SET_SIZE; i++) | ||
13964 | + preg->translate[i] = ISUPPER (i) ? TOLOWER (i) : i; | ||
13965 | + } | ||
13966 | + else | ||
13967 | + preg->translate = NULL; | ||
13968 | + | ||
13969 | + /* If REG_NEWLINE is set, newlines are treated differently. */ | ||
13970 | + if (cflags & REG_NEWLINE) | ||
13971 | + { /* REG_NEWLINE implies neither . nor [^...] match newline. */ | ||
13972 | + syntax &= ~RE_DOT_NEWLINE; | ||
13973 | + syntax |= RE_HAT_LISTS_NOT_NEWLINE; | ||
13974 | + /* It also changes the matching behavior. */ | ||
13975 | + preg->newline_anchor = 1; | ||
13976 | + } | ||
13977 | + else | ||
13978 | + preg->newline_anchor = 0; | ||
13979 | + | ||
13980 | + preg->no_sub = !!(cflags & REG_NOSUB); | ||
13981 | + | ||
13982 | + /* POSIX says a null character in the pattern terminates it, so we | ||
13983 | + can use strlen here in compiling the pattern. */ | ||
13984 | +# ifdef MBS_SUPPORT | ||
13985 | + if (MB_CUR_MAX != 1) | ||
13986 | + ret = wcs_regex_compile (pattern, strlen (pattern), syntax, preg); | ||
13987 | + else | ||
13988 | +# endif | ||
13989 | + ret = byte_regex_compile (pattern, strlen (pattern), syntax, preg); | ||
13990 | + | ||
13991 | + /* POSIX doesn't distinguish between an unmatched open-group and an | ||
13992 | + unmatched close-group: both are REG_EPAREN. */ | ||
13993 | + if (ret == REG_ERPAREN) ret = REG_EPAREN; | ||
13994 | + | ||
13995 | + if (ret == REG_NOERROR && preg->fastmap) | ||
13996 | + { | ||
13997 | + /* Compute the fastmap now, since regexec cannot modify the pattern | ||
13998 | + buffer. */ | ||
13999 | + if (re_compile_fastmap (preg) == -2) | ||
14000 | + { | ||
14001 | + /* Some error occurred while computing the fastmap, just forget | ||
14002 | + about it. */ | ||
14003 | + free (preg->fastmap); | ||
14004 | + preg->fastmap = NULL; | ||
14005 | + } | ||
14006 | + } | ||
14007 | + | ||
14008 | + return (int) ret; | ||
14009 | +} | ||
14010 | +#ifdef _LIBC | ||
14011 | +weak_alias (__regcomp, regcomp) | ||
14012 | +#endif | ||
14013 | + | ||
14014 | + | ||
14015 | +/* regexec searches for a given pattern, specified by PREG, in the | ||
14016 | + string STRING. | ||
14017 | + | ||
14018 | + If NMATCH is zero or REG_NOSUB was set in the cflags argument to | ||
14019 | + `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at | ||
14020 | + least NMATCH elements, and we set them to the offsets of the | ||
14021 | + corresponding matched substrings. | ||
14022 | + | ||
14023 | + EFLAGS specifies `execution flags' which affect matching: if | ||
14024 | + REG_NOTBOL is set, then ^ does not match at the beginning of the | ||
14025 | + string; if REG_NOTEOL is set, then $ does not match at the end. | ||
14026 | + | ||
14027 | + We return 0 if we find a match and REG_NOMATCH if not. */ | ||
14028 | + | ||
14029 | +int | ||
14030 | +regexec (const regex_t *preg, const char *string, size_t nmatch, | ||
14031 | + regmatch_t pmatch[], int eflags) | ||
14032 | +{ | ||
14033 | + int ret; | ||
14034 | + struct re_registers regs; | ||
14035 | + regex_t private_preg; | ||
14036 | + int len = strlen (string); | ||
14037 | + boolean want_reg_info = !preg->no_sub && nmatch > 0; | ||
14038 | + | ||
14039 | + private_preg = *preg; | ||
14040 | + | ||
14041 | + private_preg.not_bol = !!(eflags & REG_NOTBOL); | ||
14042 | + private_preg.not_eol = !!(eflags & REG_NOTEOL); | ||
14043 | + | ||
14044 | + /* The user has told us exactly how many registers to return | ||
14045 | + information about, via `nmatch'. We have to pass that on to the | ||
14046 | + matching routines. */ | ||
14047 | + private_preg.regs_allocated = REGS_FIXED; | ||
14048 | + | ||
14049 | + if (want_reg_info) | ||
14050 | + { | ||
14051 | + regs.num_regs = nmatch; | ||
14052 | + regs.start = TALLOC (nmatch * 2, regoff_t); | ||
14053 | + if (regs.start == NULL) | ||
14054 | + return (int) REG_NOMATCH; | ||
14055 | + regs.end = regs.start + nmatch; | ||
14056 | + } | ||
14057 | + | ||
14058 | + /* Perform the searching operation. */ | ||
14059 | + ret = re_search (&private_preg, string, len, | ||
14060 | + /* start: */ 0, /* range: */ len, | ||
14061 | + want_reg_info ? ®s : (struct re_registers *) 0); | ||
14062 | + | ||
14063 | + /* Copy the register information to the POSIX structure. */ | ||
14064 | + if (want_reg_info) | ||
14065 | + { | ||
14066 | + if (ret >= 0) | ||
14067 | + { | ||
14068 | + unsigned r; | ||
14069 | + | ||
14070 | + for (r = 0; r < nmatch; r++) | ||
14071 | + { | ||
14072 | + pmatch[r].rm_so = regs.start[r]; | ||
14073 | + pmatch[r].rm_eo = regs.end[r]; | ||
14074 | + } | ||
14075 | + } | ||
14076 | + | ||
14077 | + /* If we needed the temporary register info, free the space now. */ | ||
14078 | + free (regs.start); | ||
14079 | + } | ||
14080 | + | ||
14081 | + /* We want zero return to mean success, unlike `re_search'. */ | ||
14082 | + return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; | ||
14083 | +} | ||
14084 | +#ifdef _LIBC | ||
14085 | +/* EGLIBC: This is handled in regexec-compat.c. */ | ||
14086 | +/*weak_alias (__regexec, regexec)*/ | ||
14087 | +#include "regexec-compat.c" | ||
14088 | +#endif | ||
14089 | + | ||
14090 | + | ||
14091 | +/* Returns a message corresponding to an error code, ERRCODE, returned | ||
14092 | + from either regcomp or regexec. We don't use PREG here. */ | ||
14093 | + | ||
14094 | +size_t | ||
14095 | +regerror (int errcode, const regex_t *preg __attribute__ ((unused)), | ||
14096 | + char *errbuf, size_t errbuf_size) | ||
14097 | +{ | ||
14098 | + const char *msg; | ||
14099 | + size_t msg_size; | ||
14100 | + | ||
14101 | + if (errcode < 0 | ||
14102 | + || errcode >= (int) (sizeof (re_error_msgid) | ||
14103 | + / sizeof (re_error_msgid[0]))) | ||
14104 | + /* Only error codes returned by the rest of the code should be passed | ||
14105 | + to this routine. If we are given anything else, or if other regex | ||
14106 | + code generates an invalid error code, then the program has a bug. | ||
14107 | + Dump core so we can fix it. */ | ||
14108 | + abort (); | ||
14109 | + | ||
14110 | + msg = gettext (re_error_msgid[errcode]); | ||
14111 | + | ||
14112 | + msg_size = strlen (msg) + 1; /* Includes the null. */ | ||
14113 | + | ||
14114 | + if (errbuf_size != 0) | ||
14115 | + { | ||
14116 | + if (msg_size > errbuf_size) | ||
14117 | + { | ||
14118 | +#if defined HAVE_MEMPCPY || defined _LIBC | ||
14119 | + *((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0'; | ||
14120 | +#else | ||
14121 | + memcpy (errbuf, msg, errbuf_size - 1); | ||
14122 | + errbuf[errbuf_size - 1] = 0; | ||
14123 | +#endif | ||
14124 | + } | ||
14125 | + else | ||
14126 | + memcpy (errbuf, msg, msg_size); | ||
14127 | + } | ||
14128 | + | ||
14129 | + return msg_size; | ||
14130 | +} | ||
14131 | +#ifdef _LIBC | ||
14132 | +weak_alias (__regerror, regerror) | ||
14133 | +#endif | ||
14134 | + | ||
14135 | + | ||
14136 | +/* Free dynamically allocated space used by PREG. */ | ||
14137 | + | ||
14138 | +void | ||
14139 | +regfree (regex_t *preg) | ||
14140 | +{ | ||
14141 | + if (preg->buffer != NULL) | ||
14142 | + free (preg->buffer); | ||
14143 | + preg->buffer = NULL; | ||
14144 | + | ||
14145 | + preg->allocated = 0; | ||
14146 | + preg->used = 0; | ||
14147 | + | ||
14148 | + if (preg->fastmap != NULL) | ||
14149 | + free (preg->fastmap); | ||
14150 | + preg->fastmap = NULL; | ||
14151 | + preg->fastmap_accurate = 0; | ||
14152 | + | ||
14153 | + if (preg->translate != NULL) | ||
14154 | + free (preg->translate); | ||
14155 | + preg->translate = NULL; | ||
14156 | +} | ||
14157 | +#ifdef _LIBC | ||
14158 | +weak_alias (__regfree, regfree) | ||
14159 | +#endif | ||
14160 | + | ||
14161 | +#endif /* not emacs */ | ||
14162 | + | ||
14163 | +#endif /* not INSIDE_RECURSION */ | ||
14164 | + | ||
14165 | + | ||
14166 | +#undef STORE_NUMBER | ||
14167 | +#undef STORE_NUMBER_AND_INCR | ||
14168 | +#undef EXTRACT_NUMBER | ||
14169 | +#undef EXTRACT_NUMBER_AND_INCR | ||
14170 | + | ||
14171 | +#undef DEBUG_PRINT_COMPILED_PATTERN | ||
14172 | +#undef DEBUG_PRINT_DOUBLE_STRING | ||
14173 | + | ||
14174 | +#undef INIT_FAIL_STACK | ||
14175 | +#undef RESET_FAIL_STACK | ||
14176 | +#undef DOUBLE_FAIL_STACK | ||
14177 | +#undef PUSH_PATTERN_OP | ||
14178 | +#undef PUSH_FAILURE_POINTER | ||
14179 | +#undef PUSH_FAILURE_INT | ||
14180 | +#undef PUSH_FAILURE_ELT | ||
14181 | +#undef POP_FAILURE_POINTER | ||
14182 | +#undef POP_FAILURE_INT | ||
14183 | +#undef POP_FAILURE_ELT | ||
14184 | +#undef DEBUG_PUSH | ||
14185 | +#undef DEBUG_POP | ||
14186 | +#undef PUSH_FAILURE_POINT | ||
14187 | +#undef POP_FAILURE_POINT | ||
14188 | + | ||
14189 | +#undef REG_UNSET_VALUE | ||
14190 | +#undef REG_UNSET | ||
14191 | + | ||
14192 | +#undef PATFETCH | ||
14193 | +#undef PATFETCH_RAW | ||
14194 | +#undef PATUNFETCH | ||
14195 | +#undef TRANSLATE | ||
14196 | + | ||
14197 | +#undef INIT_BUF_SIZE | ||
14198 | +#undef GET_BUFFER_SPACE | ||
14199 | +#undef BUF_PUSH | ||
14200 | +#undef BUF_PUSH_2 | ||
14201 | +#undef BUF_PUSH_3 | ||
14202 | +#undef STORE_JUMP | ||
14203 | +#undef STORE_JUMP2 | ||
14204 | +#undef INSERT_JUMP | ||
14205 | +#undef INSERT_JUMP2 | ||
14206 | +#undef EXTEND_BUFFER | ||
14207 | +#undef GET_UNSIGNED_NUMBER | ||
14208 | +#undef FREE_STACK_RETURN | ||
14209 | + | ||
14210 | +# undef POINTER_TO_OFFSET | ||
14211 | +# undef MATCHING_IN_FRST_STRING | ||
14212 | +# undef PREFETCH | ||
14213 | +# undef AT_STRINGS_BEG | ||
14214 | +# undef AT_STRINGS_END | ||
14215 | +# undef WORDCHAR_P | ||
14216 | +# undef FREE_VAR | ||
14217 | +# undef FREE_VARIABLES | ||
14218 | +# undef NO_HIGHEST_ACTIVE_REG | ||
14219 | +# undef NO_LOWEST_ACTIVE_REG | ||
14220 | + | ||
14221 | +# undef CHAR_T | ||
14222 | +# undef UCHAR_T | ||
14223 | +# undef COMPILED_BUFFER_VAR | ||
14224 | +# undef OFFSET_ADDRESS_SIZE | ||
14225 | +# undef CHAR_CLASS_SIZE | ||
14226 | +# undef PREFIX | ||
14227 | +# undef ARG_PREFIX | ||
14228 | +# undef PUT_CHAR | ||
14229 | +# undef BYTE | ||
14230 | +# undef WCHAR | ||
14231 | + | ||
14232 | +# define DEFINED_ONCE | ||
14233 | Index: git/pwd/Makefile | ||
14234 | =================================================================== | ||
14235 | --- git.orig/pwd/Makefile 2014-08-29 20:00:53.316070587 -0700 | ||
14236 | +++ git/pwd/Makefile 2014-08-29 20:01:15.232070587 -0700 | ||
14237 | @@ -18,6 +18,8 @@ | ||
14238 | # | ||
14239 | # Sub-makefile for pwd portion of the library. | ||
14240 | # | ||
14241 | +include ../option-groups.mak | ||
14242 | + | ||
14243 | subdir := pwd | ||
14244 | |||
14245 | include ../Makeconfig | ||
14246 | Index: git/resolv/Makefile | ||
14247 | =================================================================== | ||
14248 | --- git.orig/resolv/Makefile 2014-08-29 20:00:53.320070587 -0700 | ||
14249 | +++ git/resolv/Makefile 2014-08-29 20:01:15.232070587 -0700 | ||
14250 | @@ -18,6 +18,8 @@ | ||
14251 | # | ||
14252 | # Sub-makefile for resolv portion of the library. | ||
14253 | # | ||
14254 | +include ../option-groups.mak | ||
14255 | + | ||
14256 | subdir := resolv | ||
14257 | |||
14258 | include ../Makeconfig | ||
14259 | @@ -27,20 +29,21 @@ | ||
14260 | arpa/nameser.h arpa/nameser_compat.h \ | ||
14261 | sys/bitypes.h | ||
14262 | |||
14263 | -routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ | ||
14264 | - res_hconf res_libc res-state | ||
14265 | +routines-$(OPTION_EGLIBC_INET) \ | ||
14266 | + += herror inet_addr inet_ntop inet_pton nsap_addr res_init \ | ||
14267 | + res_hconf res_libc res-state | ||
14268 | |||
14269 | -tests = tst-aton tst-leaks tst-inet_ntop | ||
14270 | -xtests = tst-leaks2 | ||
14271 | +tests-$(OPTION_EGLIBC_INET) += tst-aton tst-leaks tst-inet_ntop | ||
14272 | +xtests-$(OPTION_EGLIBC_INET) += tst-leaks2 | ||
14273 | |||
14274 | generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace | ||
14275 | |||
14276 | -extra-libs := libresolv libnss_dns | ||
14277 | +extra-libs-$(OPTION_EGLIBC_INET) += libresolv libnss_dns | ||
14278 | ifeq ($(have-thread-library),yes) | ||
14279 | -extra-libs += libanl | ||
14280 | -routines += gai_sigqueue | ||
14281 | +extra-libs-$(OPTION_EGLIBC_INET_ANL) += libanl | ||
14282 | +routines-$(OPTION_EGLIBC_INET) += gai_sigqueue | ||
14283 | endif | ||
14284 | -extra-libs-others = $(extra-libs) | ||
14285 | +extra-libs-others-y += $(extra-libs-y) | ||
14286 | libresolv-routines := gethnamaddr res_comp res_debug \ | ||
14287 | res_data res_mkquery res_query res_send \ | ||
14288 | inet_net_ntop inet_net_pton inet_neta base64 \ | ||
14289 | @@ -60,7 +63,7 @@ | ||
14290 | static-only-routines += $(libnss_dns-routines) $(libresolv-routines) | ||
14291 | endif | ||
14292 | |||
14293 | -ifeq (yesyes,$(build-shared)$(have-thread-library)) | ||
14294 | +ifeq (yesyesy,$(build-shared)$(have-thread-library)$(OPTION_EGLIBC_INET_ANL)) | ||
14295 | tests: $(objpfx)ga_test | ||
14296 | endif | ||
14297 | |||
14298 | Index: git/stdio-common/fxprintf.c | ||
14299 | =================================================================== | ||
14300 | --- git.orig/stdio-common/fxprintf.c 2014-08-29 20:00:53.544070587 -0700 | ||
14301 | +++ git/stdio-common/fxprintf.c 2014-08-29 20:01:15.232070587 -0700 | ||
14302 | @@ -23,6 +23,7 @@ | ||
14303 | #include <wchar.h> | ||
14304 | #include <string.h> | ||
14305 | #include <libioP.h> | ||
14306 | +#include <gnu/option-groups.h> | ||
14307 | |||
14308 | |||
14309 | int | ||
14310 | @@ -37,6 +38,7 @@ | ||
14311 | int res; | ||
14312 | if (_IO_fwide (fp, 0) > 0) | ||
14313 | { | ||
14314 | +#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
14315 | size_t len = strlen (fmt) + 1; | ||
14316 | wchar_t wfmt[len]; | ||
14317 | for (size_t i = 0; i < len; ++i) | ||
14318 | @@ -45,6 +47,9 @@ | ||
14319 | wfmt[i] = fmt[i]; | ||
14320 | } | ||
14321 | res = __vfwprintf (fp, wfmt, ap); | ||
14322 | +#else | ||
14323 | + abort(); | ||
14324 | +#endif | ||
14325 | } | ||
14326 | else | ||
14327 | res = _IO_vfprintf (fp, fmt, ap); | ||
14328 | Index: git/stdio-common/_i18n_number.h | ||
14329 | =================================================================== | ||
14330 | --- git.orig/stdio-common/_i18n_number.h 2014-08-29 20:00:53.500070587 -0700 | ||
14331 | +++ git/stdio-common/_i18n_number.h 2014-08-29 20:01:15.232070587 -0700 | ||
14332 | @@ -19,10 +19,13 @@ | ||
14333 | #include <stdbool.h> | ||
14334 | #include <wchar.h> | ||
14335 | #include <wctype.h> | ||
14336 | +#include <gnu/option-groups.h> | ||
14337 | |||
14338 | #include "../locale/outdigits.h" | ||
14339 | #include "../locale/outdigitswc.h" | ||
14340 | |||
14341 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
14342 | + | ||
14343 | static CHAR_T * | ||
14344 | _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end) | ||
14345 | { | ||
14346 | @@ -115,3 +118,13 @@ | ||
14347 | |||
14348 | return w; | ||
14349 | } | ||
14350 | + | ||
14351 | +#else | ||
14352 | + | ||
14353 | +static CHAR_T * | ||
14354 | +_i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end) | ||
14355 | +{ | ||
14356 | + return w; | ||
14357 | +} | ||
14358 | + | ||
14359 | +#endif | ||
14360 | Index: git/stdio-common/Makefile | ||
14361 | =================================================================== | ||
14362 | --- git.orig/stdio-common/Makefile 2014-08-29 20:00:53.500070587 -0700 | ||
14363 | +++ git/stdio-common/Makefile 2014-08-29 20:01:15.232070587 -0700 | ||
14364 | @@ -18,6 +18,8 @@ | ||
14365 | # | ||
14366 | # Specific makefile for stdio-common. | ||
14367 | # | ||
14368 | +include ../option-groups.mak | ||
14369 | + | ||
14370 | subdir := stdio-common | ||
14371 | |||
14372 | include ../Makeconfig | ||
14373 | @@ -30,7 +32,7 @@ | ||
14374 | vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex \ | ||
14375 | reg-modifier reg-type \ | ||
14376 | printf_size fprintf printf snprintf sprintf asprintf dprintf \ | ||
14377 | - vfwprintf vfscanf vfwscanf \ | ||
14378 | + vfscanf \ | ||
14379 | fscanf scanf sscanf \ | ||
14380 | perror psignal \ | ||
14381 | tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \ | ||
14382 | @@ -41,23 +43,37 @@ | ||
14383 | isoc99_vsscanf \ | ||
14384 | psiginfo | ||
14385 | |||
14386 | -aux := errlist siglist printf-parsemb printf-parsewc fxprintf | ||
14387 | +# Ideally, _itowa and itowa-digits would be in this option group as | ||
14388 | +# well, but it is used unconditionally by printf_fp and printf_fphex, | ||
14389 | +# and it didn't seem straightforward to disentangle it. | ||
14390 | +routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += \ | ||
14391 | + vfwprintf vfwscanf | ||
14392 | + | ||
14393 | +aux := errlist siglist printf-parsemb fxprintf | ||
14394 | +aux-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += printf-parsewc | ||
14395 | |||
14396 | tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ | ||
14397 | temptest tst-fileno test-fwrite tst-ungetc tst-ferror \ | ||
14398 | xbug errnobug \ | ||
14399 | bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \ | ||
14400 | - tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \ | ||
14401 | + tfformat tiformat tllformat tstdiomisc tst-printfsz \ | ||
14402 | scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \ | ||
14403 | - scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \ | ||
14404 | - tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \ | ||
14405 | - tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \ | ||
14406 | + scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \ | ||
14407 | + scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \ | ||
14408 | + tst-fseek tst-fmemopen tst-gets \ | ||
14409 | + tst-sprintf tst-rndseek tst-fdopen tst-fphex \ | ||
14410 | tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \ | ||
14411 | - tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \ | ||
14412 | - bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \ | ||
14413 | - scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \ | ||
14414 | - bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \ | ||
14415 | - bug25 tst-printf-round bug26 | ||
14416 | + tst-fwrite bug16 bug17 tst-sprintf2 bug18 \ | ||
14417 | + bug19 tst-popen2 scanf14 scanf15 bug21 bug22 scanf16 scanf17 \ | ||
14418 | + tst-setvbuf1 bug23 bug24 bug-vfprintf-nargs tst-sprintf3 bug25 \ | ||
14419 | + tst-printf-round bug26 | ||
14420 | + | ||
14421 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
14422 | + += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping | ||
14423 | +tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \ | ||
14424 | + += tst-perror bug19a bug20 tst-long-dbl-fphex tst-fphex-wide | ||
14425 | +tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ | ||
14426 | + += bug18a tst-swscanf tst-wc-printf | ||
14427 | |||
14428 | test-srcs = tst-unbputc tst-printf | ||
14429 | |||
14430 | Index: git/stdio-common/printf_fp.c | ||
14431 | =================================================================== | ||
14432 | --- git.orig/stdio-common/printf_fp.c 2014-08-29 20:00:53.548070587 -0700 | ||
14433 | +++ git/stdio-common/printf_fp.c 2014-08-29 20:01:15.232070587 -0700 | ||
14434 | @@ -39,6 +39,7 @@ | ||
14435 | #include <unistd.h> | ||
14436 | #include <stdlib.h> | ||
14437 | #include <wchar.h> | ||
14438 | +#include <gnu/option-groups.h> | ||
14439 | #include <stdbool.h> | ||
14440 | #include <rounding-mode.h> | ||
14441 | |||
14442 | @@ -148,6 +149,10 @@ | ||
14443 | wchar_t thousands_sep, int ngroups) | ||
14444 | internal_function; | ||
14445 | |||
14446 | +/* Ideally, when OPTION_EGLIBC_LOCALE_CODE is disabled, this should do | ||
14447 | + all its work in ordinary characters, rather than doing it in wide | ||
14448 | + characters and then converting at the end. But that is a challenge | ||
14449 | + for another day. */ | ||
14450 | |||
14451 | int | ||
14452 | ___printf_fp (FILE *fp, | ||
14453 | @@ -206,7 +211,14 @@ | ||
14454 | mp_limb_t cy; | ||
14455 | |||
14456 | /* Nonzero if this is output on a wide character stream. */ | ||
14457 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
14458 | int wide = info->wide; | ||
14459 | +#else | ||
14460 | + /* This should never be called on a wide-oriented stream when | ||
14461 | + OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't | ||
14462 | + be trusted to figure that out. */ | ||
14463 | + const int wide = 0; | ||
14464 | +#endif | ||
14465 | |||
14466 | /* Buffer in which we produce the output. */ | ||
14467 | wchar_t *wbuffer = NULL; | ||
14468 | @@ -258,6 +270,7 @@ | ||
14469 | |||
14470 | |||
14471 | /* Figure out the decimal point character. */ | ||
14472 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
14473 | if (info->extra == 0) | ||
14474 | { | ||
14475 | decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); | ||
14476 | @@ -277,7 +290,13 @@ | ||
14477 | /* The decimal point character must not be zero. */ | ||
14478 | assert (*decimal != '\0'); | ||
14479 | assert (decimalwc != L'\0'); | ||
14480 | +#else | ||
14481 | + /* Hard-code values from 'C' locale. */ | ||
14482 | + decimal = "."; | ||
14483 | + decimalwc = L'.'; | ||
14484 | +#endif | ||
14485 | |||
14486 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
14487 | if (info->group) | ||
14488 | { | ||
14489 | if (info->extra == 0) | ||
14490 | @@ -321,6 +340,9 @@ | ||
14491 | } | ||
14492 | else | ||
14493 | grouping = NULL; | ||
14494 | +#else | ||
14495 | + grouping = NULL; | ||
14496 | +#endif | ||
14497 | |||
14498 | /* Fetch the argument value. */ | ||
14499 | #ifndef __NO_LONG_DOUBLE_MATH | ||
14500 | Index: git/stdio-common/printf_fphex.c | ||
14501 | =================================================================== | ||
14502 | --- git.orig/stdio-common/printf_fphex.c 2014-08-29 20:00:53.548070587 -0700 | ||
14503 | +++ git/stdio-common/printf_fphex.c 2014-08-29 20:01:15.232070587 -0700 | ||
14504 | @@ -28,6 +28,7 @@ | ||
14505 | #include <_itoa.h> | ||
14506 | #include <_itowa.h> | ||
14507 | #include <locale/localeinfo.h> | ||
14508 | +#include <gnu/option-groups.h> | ||
14509 | #include <stdbool.h> | ||
14510 | #include <rounding-mode.h> | ||
14511 | |||
14512 | @@ -139,10 +140,18 @@ | ||
14513 | int done = 0; | ||
14514 | |||
14515 | /* Nonzero if this is output on a wide character stream. */ | ||
14516 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
14517 | int wide = info->wide; | ||
14518 | +#else | ||
14519 | + /* This should never be called on a wide-oriented stream when | ||
14520 | + OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't | ||
14521 | + be trusted to figure that out. */ | ||
14522 | + const int wide = 0; | ||
14523 | +#endif | ||
14524 | |||
14525 | |||
14526 | /* Figure out the decimal point character. */ | ||
14527 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
14528 | if (info->extra == 0) | ||
14529 | { | ||
14530 | decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); | ||
14531 | @@ -156,6 +165,10 @@ | ||
14532 | } | ||
14533 | /* The decimal point character must never be zero. */ | ||
14534 | assert (*decimal != '\0' && decimalwc != L'\0'); | ||
14535 | +#else | ||
14536 | + decimal = "."; | ||
14537 | + decimalwc = L'.'; | ||
14538 | +#endif | ||
14539 | |||
14540 | |||
14541 | /* Fetch the argument value. */ | ||
14542 | Index: git/stdio-common/printf_size.c | ||
14543 | =================================================================== | ||
14544 | --- git.orig/stdio-common/printf_size.c 2014-08-29 20:00:53.548070587 -0700 | ||
14545 | +++ git/stdio-common/printf_size.c 2014-08-29 20:01:15.232070587 -0700 | ||
14546 | @@ -23,6 +23,7 @@ | ||
14547 | #include <math.h> | ||
14548 | #include <printf.h> | ||
14549 | #include <libioP.h> | ||
14550 | +#include <gnu/option-groups.h> | ||
14551 | |||
14552 | |||
14553 | /* This defines make it possible to use the same code for GNU C library and | ||
14554 | @@ -116,7 +117,14 @@ | ||
14555 | |||
14556 | struct printf_info fp_info; | ||
14557 | int done = 0; | ||
14558 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
14559 | int wide = info->wide; | ||
14560 | +#else | ||
14561 | + /* This should never be called on a wide-oriented stream when | ||
14562 | + OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't | ||
14563 | + be trusted to figure that out. */ | ||
14564 | + const int wide = 0; | ||
14565 | +#endif | ||
14566 | int res; | ||
14567 | |||
14568 | /* Fetch the argument value. */ | ||
14569 | Index: git/stdio-common/scanf14.c | ||
14570 | =================================================================== | ||
14571 | --- git.orig/stdio-common/scanf14.c 2014-08-29 20:00:53.548070587 -0700 | ||
14572 | +++ git/stdio-common/scanf14.c 2014-08-29 20:01:15.232070587 -0700 | ||
14573 | @@ -2,6 +2,7 @@ | ||
14574 | #include <stdlib.h> | ||
14575 | #include <string.h> | ||
14576 | #include <wchar.h> | ||
14577 | +#include <gnu/option-groups.h> | ||
14578 | |||
14579 | #define FAIL() \ | ||
14580 | do { \ | ||
14581 | @@ -36,6 +37,7 @@ | ||
14582 | FAIL (); | ||
14583 | else if (d != 2.25 || memcmp (c, " x", 2) != 0) | ||
14584 | FAIL (); | ||
14585 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
14586 | if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) | ||
14587 | FAIL (); | ||
14588 | else | ||
14589 | @@ -45,6 +47,7 @@ | ||
14590 | memset (lsp, 'x', sizeof L"3.25"); | ||
14591 | free (lsp); | ||
14592 | } | ||
14593 | +#endif | ||
14594 | if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) | ||
14595 | FAIL (); | ||
14596 | else | ||
14597 | Index: git/stdio-common/tstdiomisc.c | ||
14598 | =================================================================== | ||
14599 | --- git.orig/stdio-common/tstdiomisc.c 2014-08-29 20:00:53.584070587 -0700 | ||
14600 | +++ git/stdio-common/tstdiomisc.c 2014-08-29 20:01:15.232070587 -0700 | ||
14601 | @@ -3,6 +3,7 @@ | ||
14602 | #include <stdio.h> | ||
14603 | #include <string.h> | ||
14604 | #include <wchar.h> | ||
14605 | +#include <gnu/option-groups.h> | ||
14606 | |||
14607 | static int | ||
14608 | t1 (void) | ||
14609 | @@ -125,6 +126,7 @@ | ||
14610 | printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n", | ||
14611 | buf); | ||
14612 | |||
14613 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
14614 | swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G", | ||
14615 | qnanval, qnanval, qnanval, qnanval, | ||
14616 | qnanval, qnanval, qnanval, qnanval); | ||
14617 | @@ -162,6 +164,7 @@ | ||
14618 | result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0; | ||
14619 | printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n", | ||
14620 | wbuf); | ||
14621 | +#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ | ||
14622 | |||
14623 | lqnanval = NAN; | ||
14624 | |||
14625 | @@ -206,6 +209,7 @@ | ||
14626 | printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n", | ||
14627 | buf); | ||
14628 | |||
14629 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
14630 | swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), | ||
14631 | L"%La %LA %Le %LE %Lf %LF %Lg %LG", | ||
14632 | lqnanval, lqnanval, lqnanval, lqnanval, | ||
14633 | @@ -250,6 +254,7 @@ | ||
14634 | result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0; | ||
14635 | printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n", | ||
14636 | wbuf); | ||
14637 | +#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ | ||
14638 | |||
14639 | return result; | ||
14640 | } | ||
14641 | Index: git/stdio-common/tst-popen.c | ||
14642 | =================================================================== | ||
14643 | --- git.orig/stdio-common/tst-popen.c 2014-08-29 20:00:53.576070587 -0700 | ||
14644 | +++ git/stdio-common/tst-popen.c 2014-08-29 20:01:15.232070587 -0700 | ||
14645 | @@ -19,6 +19,7 @@ | ||
14646 | #include <stdio.h> | ||
14647 | #include <string.h> | ||
14648 | #include <wchar.h> | ||
14649 | +#include <gnu/option-groups.h> | ||
14650 | |||
14651 | static int | ||
14652 | do_test (void) | ||
14653 | @@ -34,12 +35,14 @@ | ||
14654 | return 1; | ||
14655 | } | ||
14656 | |||
14657 | +#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
14658 | /* POSIX says that pipe streams are byte-oriented. */ | ||
14659 | if (fwide (f, 0) >= 0) | ||
14660 | { | ||
14661 | puts ("popen did not return byte-oriented stream"); | ||
14662 | result = 1; | ||
14663 | } | ||
14664 | +#endif | ||
14665 | |||
14666 | if (getline (&line, &len, f) != 5) | ||
14667 | { | ||
14668 | Index: git/stdio-common/tst-sprintf.c | ||
14669 | =================================================================== | ||
14670 | --- git.orig/stdio-common/tst-sprintf.c 2014-08-29 20:00:53.580070587 -0700 | ||
14671 | +++ git/stdio-common/tst-sprintf.c 2014-08-29 20:01:15.236070587 -0700 | ||
14672 | @@ -2,6 +2,7 @@ | ||
14673 | #include <stdlib.h> | ||
14674 | #include <locale.h> | ||
14675 | #include <string.h> | ||
14676 | +#include <gnu/option-groups.h> | ||
14677 | |||
14678 | |||
14679 | int | ||
14680 | @@ -10,12 +11,14 @@ | ||
14681 | char buf[100]; | ||
14682 | int result = 0; | ||
14683 | |||
14684 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
14685 | if (sprintf (buf, "%.0ls", L"foo") != 0 | ||
14686 | || strlen (buf) != 0) | ||
14687 | { | ||
14688 | puts ("sprintf (buf, \"%.0ls\", L\"foo\") produced some output"); | ||
14689 | result = 1; | ||
14690 | } | ||
14691 | +#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */ | ||
14692 | |||
14693 | #define SIZE (1024*70000) | ||
14694 | #define STR(x) #x | ||
14695 | Index: git/stdio-common/vfprintf.c | ||
14696 | =================================================================== | ||
14697 | --- git.orig/stdio-common/vfprintf.c 2014-08-29 20:00:53.588070587 -0700 | ||
14698 | +++ git/stdio-common/vfprintf.c 2014-08-29 20:01:15.236070587 -0700 | ||
14699 | @@ -29,6 +29,7 @@ | ||
14700 | #include <_itoa.h> | ||
14701 | #include <locale/localeinfo.h> | ||
14702 | #include <stdio.h> | ||
14703 | +#include <gnu/option-groups.h> | ||
14704 | |||
14705 | /* This code is shared between the standard stdio implementation found | ||
14706 | in GNU C library and the libio implementation originally found in | ||
14707 | @@ -138,6 +139,18 @@ | ||
14708 | # define EOF WEOF | ||
14709 | #endif | ||
14710 | |||
14711 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
14712 | +# define MULTIBYTE_SUPPORT (1) | ||
14713 | +#else | ||
14714 | +# define MULTIBYTE_SUPPORT (0) | ||
14715 | +#endif | ||
14716 | + | ||
14717 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
14718 | +# define LOCALE_SUPPORT (1) | ||
14719 | +#else | ||
14720 | +# define LOCALE_SUPPORT (0) | ||
14721 | +#endif | ||
14722 | + | ||
14723 | #include "_i18n_number.h" | ||
14724 | |||
14725 | /* Include the shared code for parsing the format string. */ | ||
14726 | @@ -1123,8 +1136,11 @@ | ||
14727 | # define process_string_arg(fspec) \ | ||
14728 | LABEL (form_character): \ | ||
14729 | /* Character. */ \ | ||
14730 | - if (is_long) \ | ||
14731 | - goto LABEL (form_wcharacter); \ | ||
14732 | + if (is_long) \ | ||
14733 | + { \ | ||
14734 | + assert (MULTIBYTE_SUPPORT); \ | ||
14735 | + goto LABEL (form_wcharacter); \ | ||
14736 | + } \ | ||
14737 | --width; /* Account for the character itself. */ \ | ||
14738 | if (!left) \ | ||
14739 | PAD (' '); \ | ||
14740 | @@ -1137,6 +1153,7 @@ | ||
14741 | break; \ | ||
14742 | \ | ||
14743 | LABEL (form_wcharacter): \ | ||
14744 | + assert (MULTIBYTE_SUPPORT); \ | ||
14745 | { \ | ||
14746 | /* Wide character. */ \ | ||
14747 | char buf[MB_CUR_MAX]; \ | ||
14748 | @@ -1203,6 +1220,7 @@ | ||
14749 | } \ | ||
14750 | else \ | ||
14751 | { \ | ||
14752 | + assert (MULTIBYTE_SUPPORT); \ | ||
14753 | const wchar_t *s2 = (const wchar_t *) string; \ | ||
14754 | mbstate_t mbstate; \ | ||
14755 | \ | ||
14756 | @@ -1403,7 +1421,9 @@ | ||
14757 | LABEL (flag_quote): | ||
14758 | group = 1; | ||
14759 | |||
14760 | - if (grouping == (const char *) -1) | ||
14761 | + if (! LOCALE_SUPPORT) | ||
14762 | + grouping = NULL; | ||
14763 | + else if (grouping == (const char *) -1) | ||
14764 | { | ||
14765 | #ifdef COMPILE_WPRINTF | ||
14766 | thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC, | ||
14767 | @@ -1702,7 +1722,9 @@ | ||
14768 | free (workstart); | ||
14769 | workstart = NULL; | ||
14770 | |||
14771 | - if (grouping == (const char *) -1) | ||
14772 | + if (! LOCALE_SUPPORT) | ||
14773 | + grouping = NULL; | ||
14774 | + else if (grouping == (const char *) -1) | ||
14775 | { | ||
14776 | #ifdef COMPILE_WPRINTF | ||
14777 | thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC, | ||
14778 | Index: git/stdio-common/vfscanf.c | ||
14779 | =================================================================== | ||
14780 | --- git.orig/stdio-common/vfscanf.c 2014-08-29 20:00:53.588070587 -0700 | ||
14781 | +++ git/stdio-common/vfscanf.c 2014-08-29 20:01:15.236070587 -0700 | ||
14782 | @@ -29,6 +29,7 @@ | ||
14783 | #include <wctype.h> | ||
14784 | #include <bits/libc-lock.h> | ||
14785 | #include <locale/localeinfo.h> | ||
14786 | +#include <gnu/option-groups.h> | ||
14787 | |||
14788 | #ifdef __GNUC__ | ||
14789 | # define HAVE_LONGLONG | ||
14790 | @@ -133,6 +134,12 @@ | ||
14791 | # define WINT_T int | ||
14792 | #endif | ||
14793 | |||
14794 | +#if __OPTION_POSIX_C_LANG_WIDE_CHAR | ||
14795 | +# define MULTIBYTE_SUPPORT (1) | ||
14796 | +#else | ||
14797 | +# define MULTIBYTE_SUPPORT (0) | ||
14798 | +#endif | ||
14799 | + | ||
14800 | #define encode_error() do { \ | ||
14801 | errval = 4; \ | ||
14802 | __set_errno (EILSEQ); \ | ||
14803 | @@ -316,24 +323,35 @@ | ||
14804 | ARGCHECK (s, format); | ||
14805 | |||
14806 | { | ||
14807 | -#ifndef COMPILE_WSCANF | ||
14808 | +#if __OPTION_EGLIBC_LOCALE_CODE && !defined (COMPILE_WSCANF) | ||
14809 | struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC]; | ||
14810 | #endif | ||
14811 | |||
14812 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
14813 | /* Figure out the decimal point character. */ | ||
14814 | -#ifdef COMPILE_WSCANF | ||
14815 | +# ifdef COMPILE_WSCANF | ||
14816 | decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC); | ||
14817 | -#else | ||
14818 | +# else | ||
14819 | decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string; | ||
14820 | -#endif | ||
14821 | +# endif | ||
14822 | /* Figure out the thousands separator character. */ | ||
14823 | -#ifdef COMPILE_WSCANF | ||
14824 | +# ifdef COMPILE_WSCANF | ||
14825 | thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC); | ||
14826 | -#else | ||
14827 | +# else | ||
14828 | thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string; | ||
14829 | if (*thousands == '\0') | ||
14830 | thousands = NULL; | ||
14831 | -#endif | ||
14832 | +# endif | ||
14833 | +#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */ | ||
14834 | + /* Hard-code values from the C locale. */ | ||
14835 | +# ifdef COMPILE_WSCANF | ||
14836 | + decimal = L'.'; | ||
14837 | + thousands = L'\0'; | ||
14838 | +# else | ||
14839 | + decimal = "."; | ||
14840 | + thousands = NULL; | ||
14841 | +# endif | ||
14842 | +#endif /* __OPTION_EGLIBC_LOCALE_CODE */ | ||
14843 | } | ||
14844 | |||
14845 | /* Lock the stream. */ | ||
14846 | @@ -385,6 +403,8 @@ | ||
14847 | #ifndef COMPILE_WSCANF | ||
14848 | if (!isascii ((unsigned char) *f)) | ||
14849 | { | ||
14850 | + assert (MULTIBYTE_SUPPORT); | ||
14851 | + | ||
14852 | /* Non-ASCII, may be a multibyte. */ | ||
14853 | int len = __mbrlen (f, strlen (f), &state); | ||
14854 | if (len > 0) | ||
14855 | @@ -830,6 +850,8 @@ | ||
14856 | } | ||
14857 | /* FALLTHROUGH */ | ||
14858 | case L_('C'): | ||
14859 | + assert (MULTIBYTE_SUPPORT); | ||
14860 | + | ||
14861 | if (width == -1) | ||
14862 | width = 1; | ||
14863 | |||
14864 | @@ -1172,6 +1194,8 @@ | ||
14865 | /* FALLTHROUGH */ | ||
14866 | |||
14867 | case L_('S'): | ||
14868 | + assert (MULTIBYTE_SUPPORT); | ||
14869 | + | ||
14870 | { | ||
14871 | #ifndef COMPILE_WSCANF | ||
14872 | mbstate_t cstate; | ||
14873 | @@ -1419,10 +1443,17 @@ | ||
14874 | const char *mbdigits[10]; | ||
14875 | const char *mbdigits_extended[10]; | ||
14876 | #endif | ||
14877 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
14878 | /* "to_inpunct" is a map from ASCII digits to their | ||
14879 | equivalent in locale. This is defined for locales | ||
14880 | which use an extra digits set. */ | ||
14881 | wctrans_t map = __wctrans ("to_inpunct"); | ||
14882 | +#else | ||
14883 | + /* This will always be the case when | ||
14884 | + OPTION_EGLIBC_LOCALE_CODE is disabled, but the | ||
14885 | + compiler can't figure that out. */ | ||
14886 | + wctrans_t map = NULL; | ||
14887 | +#endif | ||
14888 | int n; | ||
14889 | |||
14890 | from_level = 0; | ||
14891 | @@ -2088,6 +2119,7 @@ | ||
14892 | --width; | ||
14893 | } | ||
14894 | |||
14895 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
14896 | wctrans_t map; | ||
14897 | if (__builtin_expect ((flags & I18N) != 0, 0) | ||
14898 | /* Hexadecimal floats make no sense, fixing localized | ||
14899 | @@ -2304,6 +2336,7 @@ | ||
14900 | ; | ||
14901 | #endif | ||
14902 | } | ||
14903 | +#endif /* __OPTION_EGLIBC_LOCALE_CODE */ | ||
14904 | |||
14905 | /* Have we read any character? If we try to read a number | ||
14906 | in hexadecimal notation and we have read only the `0x' | ||
14907 | @@ -2343,7 +2376,10 @@ | ||
14908 | |||
14909 | case L_('['): /* Character class. */ | ||
14910 | if (flags & LONG) | ||
14911 | - STRING_ARG (wstr, wchar_t, 100); | ||
14912 | + { | ||
14913 | + assert (MULTIBYTE_SUPPORT); | ||
14914 | + STRING_ARG (wstr, wchar_t, 100); | ||
14915 | + } | ||
14916 | else | ||
14917 | STRING_ARG (str, char, 100); | ||
14918 | |||
14919 | @@ -2417,6 +2453,7 @@ | ||
14920 | if (flags & LONG) | ||
14921 | { | ||
14922 | size_t now = read_in; | ||
14923 | + assert (MULTIBYTE_SUPPORT); | ||
14924 | #ifdef COMPILE_WSCANF | ||
14925 | if (__glibc_unlikely (inchar () == WEOF)) | ||
14926 | input_error (); | ||
14927 | Index: git/stdlib/Makefile | ||
14928 | =================================================================== | ||
14929 | --- git.orig/stdlib/Makefile 2014-08-29 20:00:53.588070587 -0700 | ||
14930 | +++ git/stdlib/Makefile 2014-08-29 20:01:15.236070587 -0700 | ||
14931 | @@ -18,6 +18,8 @@ | ||
14932 | # | ||
14933 | # Makefile for stdlib routines | ||
14934 | # | ||
14935 | +include ../option-groups.mak | ||
14936 | + | ||
14937 | subdir := stdlib | ||
14938 | |||
14939 | include ../Makeconfig | ||
14940 | @@ -30,7 +32,7 @@ | ||
14941 | alloca.h fmtmsg.h \ | ||
14942 | bits/stdlib-bsearch.h | ||
14943 | |||
14944 | -routines := \ | ||
14945 | +routines-y := \ | ||
14946 | atof atoi atol atoll \ | ||
14947 | abort \ | ||
14948 | bsearch qsort msort \ | ||
14949 | @@ -39,7 +41,6 @@ | ||
14950 | quick_exit at_quick_exit cxa_at_quick_exit cxa_thread_atexit_impl \ | ||
14951 | abs labs llabs \ | ||
14952 | div ldiv lldiv \ | ||
14953 | - mblen mbstowcs mbtowc wcstombs wctomb \ | ||
14954 | random random_r rand rand_r \ | ||
14955 | drand48 erand48 lrand48 nrand48 mrand48 jrand48 \ | ||
14956 | srand48 seed48 lcong48 \ | ||
14957 | @@ -52,9 +53,18 @@ | ||
14958 | strtof_l strtod_l strtold_l \ | ||
14959 | system canonicalize \ | ||
14960 | a64l l64a \ | ||
14961 | - rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg \ | ||
14962 | - strtoimax strtoumax wcstoimax wcstoumax \ | ||
14963 | + getsubopt xpg_basename \ | ||
14964 | + strtoimax strtoumax \ | ||
14965 | getcontext setcontext makecontext swapcontext | ||
14966 | +routines-$(OPTION_EGLIBC_LOCALE_CODE) += \ | ||
14967 | + strfmon strfmon_l | ||
14968 | +routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += \ | ||
14969 | + mblen mbstowcs mbtowc wcstombs wctomb \ | ||
14970 | + wcstoimax wcstoumax | ||
14971 | +ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP)) | ||
14972 | +routines-y += rpmatch | ||
14973 | +endif | ||
14974 | +routines-$(OPTION_EGLIBC_FMTMSG) += fmtmsg | ||
14975 | aux = grouping groupingwc tens_in_limb | ||
14976 | |||
14977 | # These routines will be omitted from the libc shared object. | ||
14978 | @@ -62,20 +72,22 @@ | ||
14979 | # linked against when the shared library will be used. | ||
14980 | static-only-routines = atexit at_quick_exit | ||
14981 | |||
14982 | -test-srcs := tst-fmtmsg | ||
14983 | -tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ | ||
14984 | +test-srcs-$(OPTION_EGLIBC_FMTMSG) := tst-fmtmsg | ||
14985 | +tests := tst-strtol tst-strtod testrand testsort testdiv \ | ||
14986 | test-canon test-canon2 tst-strtoll tst-environ \ | ||
14987 | tst-xpg-basename tst-random tst-random2 tst-bsearch \ | ||
14988 | tst-limits tst-rand48 bug-strtod tst-setcontext \ | ||
14989 | - test-a64l tst-qsort tst-system testmb2 bug-strtod2 \ | ||
14990 | - tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \ | ||
14991 | - tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \ | ||
14992 | - tst-makecontext2 tst-strtod6 tst-unsetenv1 \ | ||
14993 | - tst-makecontext3 bug-getcontext bug-fmtmsg1 \ | ||
14994 | + test-a64l tst-qsort tst-system bug-strtod2 \ | ||
14995 | + tst-atof1 tst-atof2 tst-strtod2 tst-rand48-2 \ | ||
14996 | + tst-makecontext tst-qsort2 tst-makecontext2 tst-strtod6 \ | ||
14997 | + tst-unsetenv1 tst-makecontext3 bug-getcontext bug-fmtmsg1 \ | ||
14998 | tst-secure-getenv tst-strtod-overflow tst-strtod-round \ | ||
14999 | tst-tininess tst-strtod-underflow tst-tls-atexit | ||
15000 | tests-static := tst-secure-getenv | ||
15001 | - | ||
15002 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
15003 | + += tst-strtod3 tst-strtod4 tst-strtod5 testmb2 | ||
15004 | +tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ | ||
15005 | + += testmb | ||
15006 | modules-names = tst-tls-atexit-lib | ||
15007 | |||
15008 | ifeq ($(build-shared),yes) | ||
15009 | @@ -115,8 +127,10 @@ | ||
15010 | tests-special += $(objpfx)isomac.out | ||
15011 | |||
15012 | ifeq ($(run-built-tests),yes) | ||
15013 | +ifeq (y,$(OPTION_EGLIBC_FMTMSG)) | ||
15014 | tests-special += $(objpfx)tst-fmtmsg.out | ||
15015 | endif | ||
15016 | +endif | ||
15017 | |||
15018 | include ../Rules | ||
15019 | |||
15020 | Index: git/stdlib/strtod_l.c | ||
15021 | =================================================================== | ||
15022 | --- git.orig/stdlib/strtod_l.c 2014-08-29 20:00:53.648070587 -0700 | ||
15023 | +++ git/stdlib/strtod_l.c 2014-08-29 20:01:15.236070587 -0700 | ||
15024 | @@ -17,6 +17,7 @@ | ||
15025 | License along with the GNU C Library; if not, see | ||
15026 | <http://www.gnu.org/licenses/>. */ | ||
15027 | |||
15028 | +#include <gnu/option-groups.h> | ||
15029 | #include <xlocale.h> | ||
15030 | |||
15031 | extern double ____strtod_l_internal (const char *, char **, int, __locale_t); | ||
15032 | @@ -548,6 +549,7 @@ | ||
15033 | /* Used in several places. */ | ||
15034 | int cnt; | ||
15035 | |||
15036 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
15037 | struct __locale_data *current = loc->__locales[LC_NUMERIC]; | ||
15038 | |||
15039 | if (__glibc_unlikely (group)) | ||
15040 | @@ -586,6 +588,17 @@ | ||
15041 | decimal_len = strlen (decimal); | ||
15042 | assert (decimal_len > 0); | ||
15043 | #endif | ||
15044 | +#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */ | ||
15045 | + /* Hard-code values from the 'C' locale. */ | ||
15046 | + grouping = NULL; | ||
15047 | +#ifdef USE_WIDE_CHAR | ||
15048 | + decimal = L'.'; | ||
15049 | +# define decimal_len 1 | ||
15050 | +#else | ||
15051 | + decimal = "."; | ||
15052 | + decimal_len = 1; | ||
15053 | +#endif | ||
15054 | +#endif /* __OPTION_EGLIBC_LOCALE_CODE */ | ||
15055 | |||
15056 | /* Prepare number representation. */ | ||
15057 | exponent = 0; | ||
15058 | Index: git/stdlib/tst-strtod.c | ||
15059 | =================================================================== | ||
15060 | --- git.orig/stdlib/tst-strtod.c 2014-08-29 20:00:53.700070587 -0700 | ||
15061 | +++ git/stdlib/tst-strtod.c 2014-08-29 20:01:15.236070587 -0700 | ||
15062 | @@ -23,6 +23,7 @@ | ||
15063 | #include <errno.h> | ||
15064 | #include <string.h> | ||
15065 | #include <math.h> | ||
15066 | +#include <gnu/option-groups.h> | ||
15067 | |||
15068 | struct ltest | ||
15069 | { | ||
15070 | @@ -176,7 +177,9 @@ | ||
15071 | |||
15072 | status |= long_dbl (); | ||
15073 | |||
15074 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
15075 | status |= locale_test (); | ||
15076 | +#endif | ||
15077 | |||
15078 | return status ? EXIT_FAILURE : EXIT_SUCCESS; | ||
15079 | } | ||
15080 | @@ -219,6 +222,7 @@ | ||
15081 | return 0; | ||
15082 | } | ||
15083 | |||
15084 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
15085 | /* Perform a few tests in a locale with thousands separators. */ | ||
15086 | static int | ||
15087 | locale_test (void) | ||
15088 | @@ -276,3 +280,4 @@ | ||
15089 | |||
15090 | return result; | ||
15091 | } | ||
15092 | +#endif /* __OPTION_EGLIBC_LOCALE_CODE */ | ||
15093 | Index: git/streams/Makefile | ||
15094 | =================================================================== | ||
15095 | --- git.orig/streams/Makefile 2014-08-29 20:00:53.712070587 -0700 | ||
15096 | +++ git/streams/Makefile 2014-08-29 20:01:15.236070587 -0700 | ||
15097 | @@ -18,11 +18,14 @@ | ||
15098 | # | ||
15099 | # Makefile for streams. | ||
15100 | # | ||
15101 | +include ../option-groups.mak | ||
15102 | + | ||
15103 | subdir := streams | ||
15104 | |||
15105 | include ../Makeconfig | ||
15106 | |||
15107 | headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h | ||
15108 | -routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach | ||
15109 | +routines-$(OPTION_EGLIBC_STREAMS) \ | ||
15110 | + += isastream getmsg getpmsg putmsg putpmsg fattach fdetach | ||
15111 | |||
15112 | include ../Rules | ||
15113 | Index: git/string/Makefile | ||
15114 | =================================================================== | ||
15115 | --- git.orig/string/Makefile 2014-08-29 20:00:53.716070587 -0700 | ||
15116 | +++ git/string/Makefile 2014-08-29 20:01:15.236070587 -0700 | ||
15117 | @@ -18,6 +18,8 @@ | ||
15118 | # | ||
15119 | # Sub-makefile for string portion of library. | ||
15120 | # | ||
15121 | +include ../option-groups.mak | ||
15122 | + | ||
15123 | subdir := string | ||
15124 | |||
15125 | include ../Makeconfig | ||
15126 | @@ -39,10 +41,12 @@ | ||
15127 | $(addprefix argz-,append count create ctsep next \ | ||
15128 | delete extract insert stringify \ | ||
15129 | addsep replace) \ | ||
15130 | - envz basename \ | ||
15131 | + basename \ | ||
15132 | strcoll_l strxfrm_l string-inlines memrchr \ | ||
15133 | xpg-strerror strerror_l | ||
15134 | |||
15135 | +routines-$(OPTION_EGLIBC_ENVZ) += envz | ||
15136 | + | ||
15137 | strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \ | ||
15138 | stpcpy stpncpy strcat strchr strcmp strcpy strcspn \ | ||
15139 | strlen strncmp strncpy strpbrk strrchr strspn memmem \ | ||
15140 | @@ -51,10 +55,12 @@ | ||
15141 | tests := tester inl-tester noinl-tester testcopy test-ffs \ | ||
15142 | tst-strlen stratcliff tst-svc tst-inlcall \ | ||
15143 | bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \ | ||
15144 | - tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \ | ||
15145 | + tst-strtok tst-strfry \ | ||
15146 | bug-strtok1 $(addprefix test-,$(strop-tests)) \ | ||
15147 | - bug-envz1 tst-strxfrm2 tst-endian tst-svc2 \ | ||
15148 | - tst-strtok_r | ||
15149 | + tst-strxfrm2 tst-endian tst-svc2 tst-strtok_r | ||
15150 | +tests-$(OPTION_EGLIBC_ENVZ) += bug-envz1 | ||
15151 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
15152 | + += tst-strxfrm bug-strcoll1 | ||
15153 | |||
15154 | xtests = tst-strcoll-overflow | ||
15155 | |||
15156 | Index: git/string/strcoll_l.c | ||
15157 | =================================================================== | ||
15158 | --- git.orig/string/strcoll_l.c 2014-08-29 20:00:53.744070587 -0700 | ||
15159 | +++ git/string/strcoll_l.c 2014-08-29 20:01:15.240070587 -0700 | ||
15160 | @@ -25,6 +25,7 @@ | ||
15161 | #include <stdlib.h> | ||
15162 | #include <string.h> | ||
15163 | #include <sys/param.h> | ||
15164 | +#include <gnu/option-groups.h> | ||
15165 | |||
15166 | #ifndef STRING_TYPE | ||
15167 | # define STRING_TYPE char | ||
15168 | @@ -472,7 +473,11 @@ | ||
15169 | STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) | ||
15170 | { | ||
15171 | struct __locale_data *current = l->__locales[LC_COLLATE]; | ||
15172 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
15173 | uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word; | ||
15174 | +#else | ||
15175 | + const uint_fast32_t nrules = 0; | ||
15176 | +#endif | ||
15177 | /* We don't assign the following values right away since it might be | ||
15178 | unnecessary in case there are no rules. */ | ||
15179 | const unsigned char *rulesets; | ||
15180 | Index: git/string/strerror_l.c | ||
15181 | =================================================================== | ||
15182 | --- git.orig/string/strerror_l.c 2014-08-29 20:00:53.744070587 -0700 | ||
15183 | +++ git/string/strerror_l.c 2014-08-29 20:01:15.240070587 -0700 | ||
15184 | @@ -21,6 +21,7 @@ | ||
15185 | #include <stdlib.h> | ||
15186 | #include <string.h> | ||
15187 | #include <sys/param.h> | ||
15188 | +#include <gnu/option-groups.h> | ||
15189 | |||
15190 | |||
15191 | static __thread char *last_value; | ||
15192 | @@ -29,10 +30,14 @@ | ||
15193 | static const char * | ||
15194 | translate (const char *str, locale_t loc) | ||
15195 | { | ||
15196 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
15197 | locale_t oldloc = __uselocale (loc); | ||
15198 | const char *res = _(str); | ||
15199 | __uselocale (oldloc); | ||
15200 | return res; | ||
15201 | +#else | ||
15202 | + return str; | ||
15203 | +#endif | ||
15204 | } | ||
15205 | |||
15206 | |||
15207 | Index: git/string/strxfrm_l.c | ||
15208 | =================================================================== | ||
15209 | --- git.orig/string/strxfrm_l.c 2014-08-29 20:00:53.748070587 -0700 | ||
15210 | +++ git/string/strxfrm_l.c 2014-08-29 20:01:15.240070587 -0700 | ||
15211 | @@ -24,6 +24,7 @@ | ||
15212 | #include <stdlib.h> | ||
15213 | #include <string.h> | ||
15214 | #include <sys/param.h> | ||
15215 | +#include <gnu/option-groups.h> | ||
15216 | |||
15217 | #ifndef STRING_TYPE | ||
15218 | # define STRING_TYPE char | ||
15219 | @@ -85,7 +86,11 @@ | ||
15220 | STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l) | ||
15221 | { | ||
15222 | struct __locale_data *current = l->__locales[LC_COLLATE]; | ||
15223 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
15224 | uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word; | ||
15225 | +#else | ||
15226 | + const uint_fast32_t nrules = 0; | ||
15227 | +#endif | ||
15228 | /* We don't assign the following values right away since it might be | ||
15229 | unnecessary in case there are no rules. */ | ||
15230 | const unsigned char *rulesets; | ||
15231 | Index: git/string/test-strcmp.c | ||
15232 | =================================================================== | ||
15233 | --- git.orig/string/test-strcmp.c 2014-08-29 20:00:53.752070587 -0700 | ||
15234 | +++ git/string/test-strcmp.c 2014-08-29 20:01:15.240070587 -0700 | ||
15235 | @@ -329,34 +329,6 @@ | ||
15236 | FOR_EACH_IMPL (impl, 0) | ||
15237 | check_result (impl, s1 + i1, s2 + i2, exp_result); | ||
15238 | } | ||
15239 | - | ||
15240 | - /* Test cases where there are multiple zero bytes after the first. */ | ||
15241 | - | ||
15242 | - for (size_t i = 0; i < 16 + 1; i++) | ||
15243 | - { | ||
15244 | - s1[i] = 0x00; | ||
15245 | - s2[i] = 0x00; | ||
15246 | - } | ||
15247 | - | ||
15248 | - for (size_t i = 0; i < 16; i++) | ||
15249 | - { | ||
15250 | - int exp_result; | ||
15251 | - | ||
15252 | - for (int val = 0x01; val < 0x100; val++) | ||
15253 | - { | ||
15254 | - for (size_t j = 0; j < i; j++) | ||
15255 | - { | ||
15256 | - s1[j] = val; | ||
15257 | - s2[j] = val; | ||
15258 | - } | ||
15259 | - | ||
15260 | - s2[i] = val; | ||
15261 | - | ||
15262 | - exp_result = SIMPLE_STRCMP (s1, s2); | ||
15263 | - FOR_EACH_IMPL (impl, 0) | ||
15264 | - check_result (impl, s1, s2, exp_result); | ||
15265 | - } | ||
15266 | - } | ||
15267 | } | ||
15268 | |||
15269 | |||
15270 | Index: git/string/tst-strxfrm2.c | ||
15271 | =================================================================== | ||
15272 | --- git.orig/string/tst-strxfrm2.c 2014-08-29 20:00:53.756070587 -0700 | ||
15273 | +++ git/string/tst-strxfrm2.c 2014-08-29 20:01:15.240070587 -0700 | ||
15274 | @@ -1,6 +1,7 @@ | ||
15275 | #include <locale.h> | ||
15276 | #include <stdio.h> | ||
15277 | #include <string.h> | ||
15278 | +#include <gnu/option-groups.h> | ||
15279 | |||
15280 | static int | ||
15281 | do_test (void) | ||
15282 | @@ -38,6 +39,7 @@ | ||
15283 | res = 1; | ||
15284 | } | ||
15285 | |||
15286 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
15287 | if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) | ||
15288 | { | ||
15289 | puts ("setlocale failed"); | ||
15290 | @@ -75,6 +77,7 @@ | ||
15291 | res = 1; | ||
15292 | } | ||
15293 | } | ||
15294 | +#endif | ||
15295 | |||
15296 | return res; | ||
15297 | } | ||
15298 | Index: git/string/tst-strxfrm.c | ||
15299 | =================================================================== | ||
15300 | --- git.orig/string/tst-strxfrm.c 2014-08-29 20:00:53.756070587 -0700 | ||
15301 | +++ git/string/tst-strxfrm.c 2014-08-29 20:01:15.240070587 -0700 | ||
15302 | @@ -3,6 +3,7 @@ | ||
15303 | #include <stdio.h> | ||
15304 | #include <stdlib.h> | ||
15305 | #include <string.h> | ||
15306 | +#include <gnu/option-groups.h> | ||
15307 | |||
15308 | |||
15309 | char const string[] = ""; | ||
15310 | @@ -64,8 +65,10 @@ | ||
15311 | int result = 0; | ||
15312 | |||
15313 | result |= test ("C"); | ||
15314 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
15315 | result |= test ("en_US.ISO-8859-1"); | ||
15316 | result |= test ("de_DE.UTF-8"); | ||
15317 | +#endif | ||
15318 | |||
15319 | return result; | ||
15320 | } | ||
15321 | Index: git/sunrpc/Makefile | ||
15322 | =================================================================== | ||
15323 | --- git.orig/sunrpc/Makefile 2014-08-29 20:00:53.760070587 -0700 | ||
15324 | +++ git/sunrpc/Makefile 2014-08-29 20:01:15.240070587 -0700 | ||
15325 | @@ -18,6 +18,8 @@ | ||
15326 | # | ||
15327 | # Sub-makefile for sunrpc portion of the library. | ||
15328 | # | ||
15329 | +include ../option-groups.mak | ||
15330 | + | ||
15331 | subdir := sunrpc | ||
15332 | |||
15333 | include ../Makeconfig | ||
15334 | @@ -55,7 +57,6 @@ | ||
15335 | headers-not-in-tirpc = $(addprefix rpc/,key_prot.h rpc_des.h) \ | ||
15336 | $(rpcsvc:%=rpcsvc/%) rpcsvc/bootparam.h | ||
15337 | headers = rpc/netdb.h | ||
15338 | -install-others = $(inst_sysconfdir)/rpc | ||
15339 | generated += $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) $(rpcsvc:%.x=x%.stmp) \ | ||
15340 | $(rpcsvc:%.x=rpcsvc/%.stmp) rpcgen | ||
15341 | generated-dirs += rpcsvc | ||
15342 | @@ -65,18 +66,28 @@ | ||
15343 | endif | ||
15344 | |||
15345 | ifeq ($(build-shared),yes) | ||
15346 | -need-export-routines := auth_des auth_unix clnt_gen clnt_perr clnt_tcp \ | ||
15347 | +need-export-routines-$(OPTION_EGLIBC_SUNRPC) += \ | ||
15348 | + auth_des auth_unix clnt_gen clnt_perr clnt_tcp \ | ||
15349 | clnt_udp get_myaddr key_call netname pm_getport \ | ||
15350 | - rpc_thread svc svc_tcp svc_udp xcrypt xdr_array xdr \ | ||
15351 | + rpc_thread svc svc_tcp svc_udp xdr_array xdr \ | ||
15352 | xdr_intXX_t xdr_mem xdr_ref xdr_sizeof xdr_stdio \ | ||
15353 | svc_run | ||
15354 | |||
15355 | -routines := auth_none authuxprot bindrsvprt clnt_raw clnt_simp \ | ||
15356 | +need-export-routines-y += xcrypt | ||
15357 | + | ||
15358 | +need-export-routines := $(need-export-routines-y) | ||
15359 | + | ||
15360 | +routines-$(OPTION_EGLIBC_SUNRPC) \ | ||
15361 | + += auth_none authuxprot bindrsvprt clnt_raw clnt_simp \ | ||
15362 | rpc_dtable getrpcport pmap_clnt pm_getmaps pmap_prot pmap_prot2 \ | ||
15363 | pmap_rmt rpc_prot rpc_common rpc_cmsg svc_auth svc_authux svc_raw \ | ||
15364 | svc_simple xdr_float xdr_rec publickey authdes_prot \ | ||
15365 | - des_crypt des_impl des_soft key_prot openchild rtime svcauth_des \ | ||
15366 | - clnt_unix svc_unix create_xid $(need-export-routines) | ||
15367 | + key_prot openchild rtime svcauth_des \ | ||
15368 | + clnt_unix svc_unix create_xid | ||
15369 | + | ||
15370 | +# xdecrypt is also used by nss/nss_files/files-key.c. | ||
15371 | +routines-y += des_crypt des_impl des_soft $(need-export-routines) | ||
15372 | + | ||
15373 | ifneq ($(link-obsolete-rpc),yes) | ||
15374 | # We only add the RPC for compatibility to libc.so. | ||
15375 | shared-only-routines = $(routines) | ||
15376 | @@ -85,25 +96,28 @@ | ||
15377 | |||
15378 | # We do not build rpcinfo anymore. It is not needed for a bootstrap | ||
15379 | # and not wanted on complete systems. | ||
15380 | -# others := rpcinfo | ||
15381 | -# install-sbin := rpcinfo | ||
15382 | -install-bin := rpcgen | ||
15383 | +# others-$(OPTION_EGLIBC_SUNRPC) += rpcinfo | ||
15384 | +# install-sbin-$(OPTION_EGLIBC_SUNRPC) += rpcinfo | ||
15385 | +install-bin-$(OPTION_EGLIBC_SUNRPC) += rpcgen | ||
15386 | rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \ | ||
15387 | rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \ | ||
15388 | rpc_tblout.o rpc_sample.o | ||
15389 | -extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs)) | ||
15390 | -others += rpcgen | ||
15391 | +extra-objs-$(OPTION_EGLIBC_SUNRPC) = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs)) | ||
15392 | +others-$(OPTION_EGLIBC_SUNRPC) += rpcgen | ||
15393 | + | ||
15394 | +install-others-$(OPTION_EGLIBC_SUNRPC) += $(inst_sysconfdir)/rpc | ||
15395 | |||
15396 | -tests = tst-xdrmem tst-xdrmem2 | ||
15397 | -xtests := tst-getmyaddr | ||
15398 | +tests-$(OPTION_EGLIBC_SUNRPC) = tst-xdrmem tst-xdrmem2 | ||
15399 | +xtests-$(OPTION_EGLIBC_SUNRPC) := tst-getmyaddr | ||
15400 | |||
15401 | ifeq ($(have-thread-library),yes) | ||
15402 | -xtests += thrsvc | ||
15403 | +xtests-$(OPTION_EGLIBC_SUNRPC) += thrsvc | ||
15404 | endif | ||
15405 | |||
15406 | headers += $(rpcsvc:%.x=rpcsvc/%.h) | ||
15407 | -extra-libs := librpcsvc | ||
15408 | -extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass. | ||
15409 | +extra-libs-$(OPTION_EGLIBC_SUNRPC) += librpcsvc | ||
15410 | +# Make it in `others' pass, not `lib' pass. | ||
15411 | +extra-libs-others-y += $(extra-libs-y) | ||
15412 | librpcsvc-routines = $(rpcsvc:%.x=x%) | ||
15413 | librpcsvc-inhibit-o = .os # Build no shared rpcsvc library. | ||
15414 | omit-deps = $(librpcsvc-routines) | ||
15415 | Index: git/sysdeps/generic/ldsodefs.h | ||
15416 | =================================================================== | ||
15417 | --- git.orig/sysdeps/generic/ldsodefs.h 2014-08-29 20:00:53.904070587 -0700 | ||
15418 | +++ git/sysdeps/generic/ldsodefs.h 2014-08-29 20:01:15.240070587 -0700 | ||
15419 | @@ -425,6 +425,12 @@ | ||
15420 | # undef __rtld_global_attribute__ | ||
15421 | #endif | ||
15422 | |||
15423 | +#if __OPTION_EGLIBC_RTLD_DEBUG | ||
15424 | +# define GLRO_dl_debug_mask GLRO(dl_debug_mask) | ||
15425 | +#else | ||
15426 | +# define GLRO_dl_debug_mask 0 | ||
15427 | +#endif | ||
15428 | + | ||
15429 | #ifndef SHARED | ||
15430 | # define GLRO(name) _##name | ||
15431 | #else | ||
15432 | @@ -437,8 +443,10 @@ | ||
15433 | { | ||
15434 | #endif | ||
15435 | |||
15436 | +#if __OPTION_EGLIBC_RTLD_DEBUG | ||
15437 | /* If nonzero the appropriate debug information is printed. */ | ||
15438 | EXTERN int _dl_debug_mask; | ||
15439 | +#endif | ||
15440 | #define DL_DEBUG_LIBS (1 << 0) | ||
15441 | #define DL_DEBUG_IMPCALLS (1 << 1) | ||
15442 | #define DL_DEBUG_BINDINGS (1 << 2) | ||
15443 | Index: git/sysdeps/gnu/Makefile | ||
15444 | =================================================================== | ||
15445 | --- git.orig/sysdeps/gnu/Makefile 2014-08-29 20:00:53.924070587 -0700 | ||
15446 | +++ git/sysdeps/gnu/Makefile 2014-08-29 20:01:15.240070587 -0700 | ||
15447 | @@ -57,7 +57,8 @@ | ||
15448 | endif | ||
15449 | |||
15450 | ifeq ($(subdir),login) | ||
15451 | -sysdep_routines += setutxent getutxent endutxent getutxid getutxline \ | ||
15452 | +sysdep_routines-$(OPTION_EGLIBC_UTMPX) \ | ||
15453 | + += setutxent getutxent endutxent getutxid getutxline \ | ||
15454 | pututxline utmpxname updwtmpx getutmpx getutmp | ||
15455 | |||
15456 | sysdep_headers += utmpx.h bits/utmpx.h | ||
15457 | Index: git/sysdeps/ieee754/ldbl-opt/Makefile | ||
15458 | =================================================================== | ||
15459 | --- git.orig/sysdeps/ieee754/ldbl-opt/Makefile 2014-08-29 20:00:54.452070587 -0700 | ||
15460 | +++ git/sysdeps/ieee754/ldbl-opt/Makefile 2014-08-29 20:01:15.244070587 -0700 | ||
15461 | @@ -11,19 +11,18 @@ | ||
15462 | routines += math_ldbl_opt nldbl-compat | ||
15463 | |||
15464 | extra-libs += libnldbl | ||
15465 | -libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \ | ||
15466 | +libnldbl-calls = asprintf dprintf fprintf fscanf iovfscanf \ | ||
15467 | obstack_printf obstack_vprintf printf scanf snprintf \ | ||
15468 | - sprintf sscanf swprintf swscanf vasprintf vdprintf vfprintf \ | ||
15469 | - vfscanf vfwprintf vfwscanf vprintf vscanf vsnprintf \ | ||
15470 | - vsprintf vsscanf vswprintf vswscanf vwprintf vwscanf \ | ||
15471 | - wprintf wscanf printf_fp printf_size \ | ||
15472 | - fprintf_chk fwprintf_chk printf_chk snprintf_chk sprintf_chk \ | ||
15473 | - swprintf_chk vfprintf_chk vfwprintf_chk vprintf_chk \ | ||
15474 | - vsnprintf_chk vsprintf_chk vswprintf_chk vwprintf_chk \ | ||
15475 | - wprintf_chk asprintf_chk vasprintf_chk dprintf_chk \ | ||
15476 | + sprintf sscanf vasprintf vdprintf vfprintf \ | ||
15477 | + vfscanf vprintf vscanf vsnprintf \ | ||
15478 | + vsprintf vsscanf \ | ||
15479 | + printf_fp printf_size \ | ||
15480 | + fprintf_chk printf_chk snprintf_chk sprintf_chk \ | ||
15481 | + vfprintf_chk vprintf_chk \ | ||
15482 | + vsnprintf_chk vsprintf_chk \ | ||
15483 | + asprintf_chk vasprintf_chk dprintf_chk \ | ||
15484 | vdprintf_chk obstack_printf_chk obstack_vprintf_chk \ | ||
15485 | syslog syslog_chk vsyslog vsyslog_chk \ | ||
15486 | - strfmon strfmon_l \ | ||
15487 | strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \ | ||
15488 | qecvt qfcvt qgcvt qecvt_r qfcvt_r \ | ||
15489 | isinf isnan finite signbit scalb log2 lgamma_r ceil \ | ||
15490 | @@ -38,9 +37,15 @@ | ||
15491 | casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \ | ||
15492 | cabs carg cimag creal clog10 \ | ||
15493 | isoc99_scanf isoc99_fscanf isoc99_sscanf \ | ||
15494 | - isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \ | ||
15495 | + isoc99_vscanf isoc99_vfscanf isoc99_vsscanf | ||
15496 | +libnldbl-calls-$(OPTION_EGLIBC_LOCALE_CODE) += strfmon strfmon_l | ||
15497 | +libnldbl-calls-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += fwprintf fwscanf \ | ||
15498 | + swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf \ | ||
15499 | + vwprintf vwscanf wprintf wscanf fwprintf_chk swprintf_chk \ | ||
15500 | + vfwprintf_chk vswprintf_chk vwprintf_chk wprintf_chk \ | ||
15501 | isoc99_wscanf isoc99_fwscanf isoc99_swscanf \ | ||
15502 | isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf | ||
15503 | +libnldbl-calls += $(libnldbl-calls-y) | ||
15504 | libnldbl-routines = $(libnldbl-calls:%=nldbl-%) | ||
15505 | libnldbl-inhibit-o = $(object-suffixes) | ||
15506 | libnldbl-static-only-routines = $(libnldbl-routines) | ||
15507 | Index: git/sysdeps/ieee754/ldbl-opt/nldbl-compat.c | ||
15508 | =================================================================== | ||
15509 | --- git.orig/sysdeps/ieee754/ldbl-opt/nldbl-compat.c 2014-08-29 20:00:54.468070587 -0700 | ||
15510 | +++ git/sysdeps/ieee754/ldbl-opt/nldbl-compat.c 2014-08-29 20:01:15.244070587 -0700 | ||
15511 | @@ -26,6 +26,7 @@ | ||
15512 | #include <locale/localeinfo.h> | ||
15513 | #include <sys/syslog.h> | ||
15514 | #include <bits/libc-lock.h> | ||
15515 | +#include <gnu/option-groups.h> | ||
15516 | |||
15517 | #include "nldbl-compat.h" | ||
15518 | |||
15519 | @@ -33,20 +34,14 @@ | ||
15520 | libc_hidden_proto (__nldbl_vsscanf) | ||
15521 | libc_hidden_proto (__nldbl_vsprintf) | ||
15522 | libc_hidden_proto (__nldbl_vfscanf) | ||
15523 | -libc_hidden_proto (__nldbl_vfwscanf) | ||
15524 | libc_hidden_proto (__nldbl_vdprintf) | ||
15525 | -libc_hidden_proto (__nldbl_vswscanf) | ||
15526 | -libc_hidden_proto (__nldbl_vfwprintf) | ||
15527 | -libc_hidden_proto (__nldbl_vswprintf) | ||
15528 | libc_hidden_proto (__nldbl_vsnprintf) | ||
15529 | libc_hidden_proto (__nldbl_vasprintf) | ||
15530 | libc_hidden_proto (__nldbl_obstack_vprintf) | ||
15531 | -libc_hidden_proto (__nldbl___vfwprintf_chk) | ||
15532 | libc_hidden_proto (__nldbl___vsnprintf_chk) | ||
15533 | libc_hidden_proto (__nldbl___vfprintf_chk) | ||
15534 | libc_hidden_proto (__nldbl___vsyslog_chk) | ||
15535 | libc_hidden_proto (__nldbl___vsprintf_chk) | ||
15536 | -libc_hidden_proto (__nldbl___vswprintf_chk) | ||
15537 | libc_hidden_proto (__nldbl___vasprintf_chk) | ||
15538 | libc_hidden_proto (__nldbl___vdprintf_chk) | ||
15539 | libc_hidden_proto (__nldbl___obstack_vprintf_chk) | ||
15540 | @@ -54,8 +49,17 @@ | ||
15541 | libc_hidden_proto (__nldbl___vstrfmon_l) | ||
15542 | libc_hidden_proto (__nldbl___isoc99_vsscanf) | ||
15543 | libc_hidden_proto (__nldbl___isoc99_vfscanf) | ||
15544 | + | ||
15545 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15546 | +libc_hidden_proto (__nldbl_vfwscanf) | ||
15547 | +libc_hidden_proto (__nldbl_vswscanf) | ||
15548 | +libc_hidden_proto (__nldbl_vfwprintf) | ||
15549 | +libc_hidden_proto (__nldbl_vswprintf) | ||
15550 | +libc_hidden_proto (__nldbl___vfwprintf_chk) | ||
15551 | +libc_hidden_proto (__nldbl___vswprintf_chk) | ||
15552 | libc_hidden_proto (__nldbl___isoc99_vswscanf) | ||
15553 | libc_hidden_proto (__nldbl___isoc99_vfwscanf) | ||
15554 | +#endif | ||
15555 | |||
15556 | static void | ||
15557 | __nldbl_cleanup (void *arg) | ||
15558 | @@ -117,6 +121,7 @@ | ||
15559 | } | ||
15560 | weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf) | ||
15561 | |||
15562 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15563 | int | ||
15564 | attribute_compat_text_section weak_function | ||
15565 | __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...) | ||
15566 | @@ -130,6 +135,7 @@ | ||
15567 | |||
15568 | return done; | ||
15569 | } | ||
15570 | +#endif | ||
15571 | |||
15572 | int | ||
15573 | attribute_compat_text_section | ||
15574 | @@ -226,6 +232,7 @@ | ||
15575 | return done; | ||
15576 | } | ||
15577 | |||
15578 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15579 | int | ||
15580 | attribute_compat_text_section | ||
15581 | __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...) | ||
15582 | @@ -239,6 +246,7 @@ | ||
15583 | |||
15584 | return done; | ||
15585 | } | ||
15586 | +#endif | ||
15587 | |||
15588 | int | ||
15589 | attribute_compat_text_section weak_function | ||
15590 | @@ -264,6 +272,7 @@ | ||
15591 | } | ||
15592 | libc_hidden_def (__nldbl_vdprintf) | ||
15593 | |||
15594 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15595 | int | ||
15596 | attribute_compat_text_section weak_function | ||
15597 | __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap) | ||
15598 | @@ -275,6 +284,7 @@ | ||
15599 | return res; | ||
15600 | } | ||
15601 | libc_hidden_def (__nldbl_vfwprintf) | ||
15602 | +#endif | ||
15603 | |||
15604 | int | ||
15605 | attribute_compat_text_section | ||
15606 | @@ -297,6 +307,7 @@ | ||
15607 | libc_hidden_def (__nldbl_vsnprintf) | ||
15608 | weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf) | ||
15609 | |||
15610 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15611 | int | ||
15612 | attribute_compat_text_section weak_function | ||
15613 | __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt, | ||
15614 | @@ -330,6 +341,7 @@ | ||
15615 | |||
15616 | return done; | ||
15617 | } | ||
15618 | +#endif | ||
15619 | |||
15620 | int | ||
15621 | attribute_compat_text_section | ||
15622 | @@ -419,6 +431,7 @@ | ||
15623 | return done; | ||
15624 | } | ||
15625 | |||
15626 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15627 | int | ||
15628 | attribute_compat_text_section | ||
15629 | __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap) | ||
15630 | @@ -491,6 +504,7 @@ | ||
15631 | |||
15632 | return done; | ||
15633 | } | ||
15634 | +#endif | ||
15635 | |||
15636 | int | ||
15637 | attribute_compat_text_section | ||
15638 | @@ -506,6 +520,7 @@ | ||
15639 | return done; | ||
15640 | } | ||
15641 | |||
15642 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15643 | int | ||
15644 | attribute_compat_text_section | ||
15645 | __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...) | ||
15646 | @@ -519,6 +534,7 @@ | ||
15647 | |||
15648 | return done; | ||
15649 | } | ||
15650 | +#endif | ||
15651 | |||
15652 | int | ||
15653 | attribute_compat_text_section | ||
15654 | @@ -563,6 +579,7 @@ | ||
15655 | return done; | ||
15656 | } | ||
15657 | |||
15658 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15659 | int | ||
15660 | attribute_compat_text_section | ||
15661 | __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen, | ||
15662 | @@ -577,6 +594,7 @@ | ||
15663 | |||
15664 | return done; | ||
15665 | } | ||
15666 | +#endif | ||
15667 | |||
15668 | int | ||
15669 | attribute_compat_text_section | ||
15670 | @@ -590,6 +608,7 @@ | ||
15671 | } | ||
15672 | libc_hidden_def (__nldbl___vfprintf_chk) | ||
15673 | |||
15674 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15675 | int | ||
15676 | attribute_compat_text_section | ||
15677 | __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap) | ||
15678 | @@ -601,6 +620,7 @@ | ||
15679 | return res; | ||
15680 | } | ||
15681 | libc_hidden_def (__nldbl___vfwprintf_chk) | ||
15682 | +#endif | ||
15683 | |||
15684 | int | ||
15685 | attribute_compat_text_section | ||
15686 | @@ -635,6 +655,7 @@ | ||
15687 | } | ||
15688 | libc_hidden_def (__nldbl___vsprintf_chk) | ||
15689 | |||
15690 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15691 | int | ||
15692 | attribute_compat_text_section | ||
15693 | __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen, | ||
15694 | @@ -668,6 +689,7 @@ | ||
15695 | |||
15696 | return done; | ||
15697 | } | ||
15698 | +#endif | ||
15699 | |||
15700 | int | ||
15701 | attribute_compat_text_section | ||
15702 | @@ -775,6 +797,7 @@ | ||
15703 | return ___printf_fp (fp, &info_no_ldbl, args); | ||
15704 | } | ||
15705 | |||
15706 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
15707 | ssize_t | ||
15708 | attribute_compat_text_section | ||
15709 | __nldbl_strfmon (char *s, size_t maxsize, const char *format, ...) | ||
15710 | @@ -829,6 +852,7 @@ | ||
15711 | return res; | ||
15712 | } | ||
15713 | libc_hidden_def (__nldbl___vstrfmon_l) | ||
15714 | +#endif | ||
15715 | |||
15716 | void | ||
15717 | attribute_compat_text_section | ||
15718 | @@ -941,6 +965,7 @@ | ||
15719 | return done; | ||
15720 | } | ||
15721 | |||
15722 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15723 | int | ||
15724 | attribute_compat_text_section | ||
15725 | __nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap) | ||
15726 | @@ -1014,6 +1039,7 @@ | ||
15727 | |||
15728 | return done; | ||
15729 | } | ||
15730 | +#endif | ||
15731 | |||
15732 | #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) | ||
15733 | compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0); | ||
15734 | @@ -1057,6 +1083,7 @@ | ||
15735 | compat_symbol (libc, __nldbl___strfmon_l, __strfmon_l, GLIBC_2_1); | ||
15736 | #endif | ||
15737 | #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_2) | ||
15738 | +# ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15739 | compat_symbol (libc, __nldbl_swprintf, swprintf, GLIBC_2_2); | ||
15740 | compat_symbol (libc, __nldbl_vwprintf, vwprintf, GLIBC_2_2); | ||
15741 | compat_symbol (libc, __nldbl_wprintf, wprintf, GLIBC_2_2); | ||
15742 | @@ -1069,6 +1096,7 @@ | ||
15743 | compat_symbol (libc, __nldbl_vswscanf, vswscanf, GLIBC_2_2); | ||
15744 | compat_symbol (libc, __nldbl_vwscanf, vwscanf, GLIBC_2_2); | ||
15745 | compat_symbol (libc, __nldbl_wscanf, wscanf, GLIBC_2_2); | ||
15746 | +# endif | ||
15747 | #endif | ||
15748 | #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3) | ||
15749 | compat_symbol (libc, __nldbl_strfmon_l, strfmon_l, GLIBC_2_3); | ||
15750 | Index: git/sysdeps/ieee754/ldbl-opt/nldbl-compat.h | ||
15751 | =================================================================== | ||
15752 | --- git.orig/sysdeps/ieee754/ldbl-opt/nldbl-compat.h 2014-08-29 20:00:54.468070587 -0700 | ||
15753 | +++ git/sysdeps/ieee754/ldbl-opt/nldbl-compat.h 2014-08-29 20:01:15.244070587 -0700 | ||
15754 | @@ -30,6 +30,7 @@ | ||
15755 | #include <math.h> | ||
15756 | #include <monetary.h> | ||
15757 | #include <sys/syslog.h> | ||
15758 | +#include <gnu/option-groups.h> | ||
15759 | |||
15760 | |||
15761 | /* Declare the __nldbl_NAME function the wrappers call that's in libc.so. */ | ||
15762 | @@ -37,19 +38,15 @@ | ||
15763 | |||
15764 | NLDBL_DECL (_IO_vfscanf); | ||
15765 | NLDBL_DECL (vfscanf); | ||
15766 | -NLDBL_DECL (vfwscanf); | ||
15767 | NLDBL_DECL (obstack_vprintf); | ||
15768 | NLDBL_DECL (vasprintf); | ||
15769 | NLDBL_DECL (dprintf); | ||
15770 | NLDBL_DECL (vdprintf); | ||
15771 | NLDBL_DECL (fprintf); | ||
15772 | NLDBL_DECL (vfprintf); | ||
15773 | -NLDBL_DECL (vfwprintf); | ||
15774 | NLDBL_DECL (vsnprintf); | ||
15775 | NLDBL_DECL (vsprintf); | ||
15776 | NLDBL_DECL (vsscanf); | ||
15777 | -NLDBL_DECL (vswprintf); | ||
15778 | -NLDBL_DECL (vswscanf); | ||
15779 | NLDBL_DECL (__asprintf); | ||
15780 | NLDBL_DECL (asprintf); | ||
15781 | NLDBL_DECL (__printf_fp); | ||
15782 | @@ -66,12 +63,18 @@ | ||
15783 | NLDBL_DECL (__isoc99_vscanf); | ||
15784 | NLDBL_DECL (__isoc99_vfscanf); | ||
15785 | NLDBL_DECL (__isoc99_vsscanf); | ||
15786 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15787 | +NLDBL_DECL (vfwscanf); | ||
15788 | +NLDBL_DECL (vfwprintf); | ||
15789 | +NLDBL_DECL (vswprintf); | ||
15790 | +NLDBL_DECL (vswscanf); | ||
15791 | NLDBL_DECL (__isoc99_wscanf); | ||
15792 | NLDBL_DECL (__isoc99_fwscanf); | ||
15793 | NLDBL_DECL (__isoc99_swscanf); | ||
15794 | NLDBL_DECL (__isoc99_vwscanf); | ||
15795 | NLDBL_DECL (__isoc99_vfwscanf); | ||
15796 | NLDBL_DECL (__isoc99_vswscanf); | ||
15797 | +#endif | ||
15798 | |||
15799 | /* This one does not exist in the normal interface, only | ||
15800 | __nldbl___vstrfmon really exists. */ | ||
15801 | @@ -82,22 +85,23 @@ | ||
15802 | since we don't compile with _FORTIFY_SOURCE. */ | ||
15803 | extern int __nldbl___vfprintf_chk (FILE *__restrict, int, | ||
15804 | const char *__restrict, _G_va_list); | ||
15805 | -extern int __nldbl___vfwprintf_chk (FILE *__restrict, int, | ||
15806 | - const wchar_t *__restrict, __gnuc_va_list); | ||
15807 | extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t, | ||
15808 | const char *__restrict, _G_va_list) __THROW; | ||
15809 | extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t, | ||
15810 | const char *__restrict, _G_va_list) | ||
15811 | __THROW; | ||
15812 | -extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t, | ||
15813 | - const wchar_t *__restrict, __gnuc_va_list) | ||
15814 | - __THROW; | ||
15815 | extern int __nldbl___vasprintf_chk (char **, int, const char *, _G_va_list) | ||
15816 | __THROW; | ||
15817 | extern int __nldbl___vdprintf_chk (int, int, const char *, _G_va_list); | ||
15818 | extern int __nldbl___obstack_vprintf_chk (struct obstack *, int, const char *, | ||
15819 | _G_va_list) __THROW; | ||
15820 | extern void __nldbl___vsyslog_chk (int, int, const char *, va_list); | ||
15821 | - | ||
15822 | +#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO | ||
15823 | +extern int __nldbl___vfwprintf_chk (FILE *__restrict, int, | ||
15824 | + const wchar_t *__restrict, __gnuc_va_list); | ||
15825 | +extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t, | ||
15826 | + const wchar_t *__restrict, __gnuc_va_list) | ||
15827 | + __THROW; | ||
15828 | +#endif | ||
15829 | |||
15830 | #endif /* __NLDBL_COMPAT_H */ | ||
15831 | Index: git/sysdeps/unix/sysv/linux/gethostid.c | ||
15832 | =================================================================== | ||
15833 | --- git.orig/sysdeps/unix/sysv/linux/gethostid.c 2014-08-29 20:00:58.840070587 -0700 | ||
15834 | +++ git/sysdeps/unix/sysv/linux/gethostid.c 2014-08-29 20:01:15.244070587 -0700 | ||
15835 | @@ -21,6 +21,7 @@ | ||
15836 | #include <unistd.h> | ||
15837 | #include <netdb.h> | ||
15838 | #include <not-cancel.h> | ||
15839 | +#include <gnu/option-groups.h> | ||
15840 | |||
15841 | #define HOSTIDFILE "/etc/hostid" | ||
15842 | |||
15843 | @@ -89,6 +90,7 @@ | ||
15844 | return id; | ||
15845 | } | ||
15846 | |||
15847 | +#if __OPTION_EGLIBC_INET | ||
15848 | /* Getting from the file was not successful. An intelligent guess for | ||
15849 | a unique number of a host is its IP address. Return this. */ | ||
15850 | if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0') | ||
15851 | @@ -115,5 +117,9 @@ | ||
15852 | /* For the return value to be not exactly the IP address we do some | ||
15853 | bit fiddling. */ | ||
15854 | return (int32_t) (in.s_addr << 16 | in.s_addr >> 16); | ||
15855 | +#else | ||
15856 | + /* Return an arbitrary value. */ | ||
15857 | + return 0; | ||
15858 | +#endif | ||
15859 | } | ||
15860 | #endif | ||
15861 | Index: git/sysdeps/unix/sysv/linux/libc_fatal.c | ||
15862 | =================================================================== | ||
15863 | --- git.orig/sysdeps/unix/sysv/linux/libc_fatal.c 2014-08-29 20:00:58.980070587 -0700 | ||
15864 | +++ git/sysdeps/unix/sysv/linux/libc_fatal.c 2014-08-29 20:01:15.244070587 -0700 | ||
15865 | @@ -23,6 +23,7 @@ | ||
15866 | #include <string.h> | ||
15867 | #include <sys/mman.h> | ||
15868 | #include <sys/uio.h> | ||
15869 | +#include <gnu/option-groups.h> | ||
15870 | |||
15871 | static bool | ||
15872 | writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total) | ||
15873 | @@ -40,6 +41,7 @@ | ||
15874 | static void | ||
15875 | backtrace_and_maps (int do_abort, bool written, int fd) | ||
15876 | { | ||
15877 | +#if __OPTION_EGLIBC_BACKTRACE | ||
15878 | if (do_abort > 1 && written) | ||
15879 | { | ||
15880 | void *addrs[64]; | ||
15881 | @@ -62,6 +64,7 @@ | ||
15882 | close_not_cancel_no_status (fd2); | ||
15883 | } | ||
15884 | } | ||
15885 | +#endif /* __OPTION_EGLIBC_BACKTRACE */ | ||
15886 | } | ||
15887 | #define BEFORE_ABORT backtrace_and_maps | ||
15888 | |||
15889 | Index: git/time/Makefile | ||
15890 | =================================================================== | ||
15891 | --- git.orig/time/Makefile 2014-08-29 20:00:59.504070587 -0700 | ||
15892 | +++ git/time/Makefile 2014-08-29 20:01:15.244070587 -0700 | ||
15893 | @@ -18,6 +18,8 @@ | ||
15894 | # | ||
15895 | # Makefile for time routines | ||
15896 | # | ||
15897 | +include ../option-groups.mak | ||
15898 | + | ||
15899 | subdir := time | ||
15900 | |||
15901 | include ../Makeconfig | ||
15902 | @@ -30,14 +32,20 @@ | ||
15903 | tzfile getitimer setitimer \ | ||
15904 | stime dysize timegm ftime \ | ||
15905 | getdate strptime strptime_l \ | ||
15906 | - strftime wcsftime strftime_l wcsftime_l \ | ||
15907 | + strftime strftime_l \ | ||
15908 | timespec_get | ||
15909 | -aux := era alt_digit lc-time-cleanup | ||
15910 | +routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ | ||
15911 | + := wcsftime wcsftime_l | ||
15912 | +aux-$(OPTION_EGLIBC_LOCALE_CODE) += alt_digit era lc-time-cleanup | ||
15913 | |||
15914 | -tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ | ||
15915 | - tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \ | ||
15916 | +tests := test_time clocktest tst-posixtz \ | ||
15917 | + tst-getdate tst-mktime tst-mktime2 tst-strftime \ | ||
15918 | tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \ | ||
15919 | tst-strptime3 bug-getdate1 tst-strptime-whitespace | ||
15920 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
15921 | + += tst-strptime tst-ftime_l | ||
15922 | +tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \ | ||
15923 | + += tst_wcsftime | ||
15924 | |||
15925 | include ../Rules | ||
15926 | |||
15927 | Index: git/time/strftime_l.c | ||
15928 | =================================================================== | ||
15929 | --- git.orig/time/strftime_l.c 2014-08-29 20:00:59.528070587 -0700 | ||
15930 | +++ git/time/strftime_l.c 2014-08-29 20:01:15.244070587 -0700 | ||
15931 | @@ -35,6 +35,10 @@ | ||
15932 | # include "../locale/localeinfo.h" | ||
15933 | #endif | ||
15934 | |||
15935 | +#ifdef _LIBC | ||
15936 | +# include <gnu/option-groups.h> | ||
15937 | +#endif | ||
15938 | + | ||
15939 | #if defined emacs && !defined HAVE_BCOPY | ||
15940 | # define HAVE_MEMCPY 1 | ||
15941 | #endif | ||
15942 | @@ -882,7 +886,7 @@ | ||
15943 | case L_('C'): | ||
15944 | if (modifier == L_('E')) | ||
15945 | { | ||
15946 | -#if HAVE_STRUCT_ERA_ENTRY | ||
15947 | +#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY | ||
15948 | struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); | ||
15949 | if (era) | ||
15950 | { | ||
15951 | @@ -955,7 +959,7 @@ | ||
15952 | |||
15953 | if (modifier == L_('O') && 0 <= number_value) | ||
15954 | { | ||
15955 | -#ifdef _NL_CURRENT | ||
15956 | +#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT) | ||
15957 | /* Get the locale specific alternate representation of | ||
15958 | the number NUMBER_VALUE. If none exist NULL is returned. */ | ||
15959 | const CHAR_T *cp = nl_get_alt_digit (number_value | ||
15960 | @@ -1260,7 +1264,7 @@ | ||
15961 | case L_('Y'): | ||
15962 | if (modifier == 'E') | ||
15963 | { | ||
15964 | -#if HAVE_STRUCT_ERA_ENTRY | ||
15965 | +#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY | ||
15966 | struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); | ||
15967 | if (era) | ||
15968 | { | ||
15969 | @@ -1285,7 +1289,7 @@ | ||
15970 | case L_('y'): | ||
15971 | if (modifier == L_('E')) | ||
15972 | { | ||
15973 | -#if HAVE_STRUCT_ERA_ENTRY | ||
15974 | +#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY | ||
15975 | struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); | ||
15976 | if (era) | ||
15977 | { | ||
15978 | Index: git/time/strptime_l.c | ||
15979 | =================================================================== | ||
15980 | --- git.orig/time/strptime_l.c 2014-08-29 20:00:59.528070587 -0700 | ||
15981 | +++ git/time/strptime_l.c 2014-08-29 20:01:15.244070587 -0700 | ||
15982 | @@ -29,6 +29,7 @@ | ||
15983 | |||
15984 | #ifdef _LIBC | ||
15985 | # define HAVE_LOCALTIME_R 0 | ||
15986 | +# include <gnu/option-groups.h> | ||
15987 | # include "../locale/localeinfo.h" | ||
15988 | #endif | ||
15989 | |||
15990 | @@ -84,7 +85,7 @@ | ||
15991 | if (val < from || val > to) \ | ||
15992 | return NULL; \ | ||
15993 | } while (0) | ||
15994 | -#ifdef _NL_CURRENT | ||
15995 | +#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT) | ||
15996 | # define get_alt_number(from, to, n) \ | ||
15997 | ({ \ | ||
15998 | __label__ do_normal; \ | ||
15999 | @@ -820,6 +821,7 @@ | ||
16000 | s.want_xday = 1; | ||
16001 | break; | ||
16002 | case 'C': | ||
16003 | +#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE | ||
16004 | if (s.decided != raw) | ||
16005 | { | ||
16006 | if (s.era_cnt >= 0) | ||
16007 | @@ -856,10 +858,12 @@ | ||
16008 | |||
16009 | s.decided = raw; | ||
16010 | } | ||
16011 | +#endif | ||
16012 | /* The C locale has no era information, so use the | ||
16013 | normal representation. */ | ||
16014 | goto match_century; | ||
16015 | case 'y': | ||
16016 | +#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE | ||
16017 | if (s.decided != raw) | ||
16018 | { | ||
16019 | get_number(0, 9999, 4); | ||
16020 | @@ -918,9 +922,10 @@ | ||
16021 | |||
16022 | s.decided = raw; | ||
16023 | } | ||
16024 | - | ||
16025 | +#endif | ||
16026 | goto match_year_in_century; | ||
16027 | case 'Y': | ||
16028 | +#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE | ||
16029 | if (s.decided != raw) | ||
16030 | { | ||
16031 | num_eras = _NL_CURRENT_WORD (LC_TIME, | ||
16032 | @@ -948,6 +953,7 @@ | ||
16033 | |||
16034 | s.decided = raw; | ||
16035 | } | ||
16036 | +#endif | ||
16037 | get_number (0, 9999, 4); | ||
16038 | tm->tm_year = val - 1900; | ||
16039 | s.want_century = 0; | ||
16040 | @@ -1118,6 +1124,7 @@ | ||
16041 | tm->tm_year = (s.century - 19) * 100; | ||
16042 | } | ||
16043 | |||
16044 | +#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE | ||
16045 | if (s.era_cnt != -1) | ||
16046 | { | ||
16047 | era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG); | ||
16048 | @@ -1132,6 +1139,7 @@ | ||
16049 | tm->tm_year = era->start_date[0]; | ||
16050 | } | ||
16051 | else | ||
16052 | +#endif | ||
16053 | if (s.want_era) | ||
16054 | { | ||
16055 | /* No era found but we have seen an E modifier. Rectify some | ||
16056 | Index: git/timezone/Makefile | ||
16057 | =================================================================== | ||
16058 | --- git.orig/timezone/Makefile 2014-08-29 20:01:14.044070587 -0700 | ||
16059 | +++ git/timezone/Makefile 2014-08-29 20:01:15.244070587 -0700 | ||
16060 | @@ -115,7 +115,7 @@ | ||
16061 | |||
16062 | $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make | ||
16063 | sed -e 's|/bin/bash|/bin/sh|' \ | ||
16064 | - -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \ | ||
16065 | + -e '/TZDIR=/s|\$$(pwd)|$(zonedir)|' \ | ||
16066 | -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \ | ||
16067 | -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \ | ||
16068 | -e '/REPORT_BUGS_TO=/s|=.*|="$(REPORT_BUGS_TO)"|' \ | ||
16069 | Index: git/wcsmbs/Makefile | ||
16070 | =================================================================== | ||
16071 | --- git.orig/wcsmbs/Makefile 2014-08-29 20:00:59.548070587 -0700 | ||
16072 | +++ git/wcsmbs/Makefile 2014-08-29 20:01:15.244070587 -0700 | ||
16073 | @@ -18,15 +18,21 @@ | ||
16074 | # | ||
16075 | # Sub-makefile for wcsmbs portion of the library. | ||
16076 | # | ||
16077 | +include ../option-groups.mak | ||
16078 | + | ||
16079 | subdir := wcsmbs | ||
16080 | |||
16081 | include ../Makeconfig | ||
16082 | |||
16083 | headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h | ||
16084 | |||
16085 | -routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ | ||
16086 | +# These functions are used by printf_fp.c, even in the plain case; see | ||
16087 | +# comments there for OPTION_EGLIBC_LOCALE_CODE. | ||
16088 | +routines := wmemcpy wmemset | ||
16089 | +routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ | ||
16090 | + := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ | ||
16091 | wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \ | ||
16092 | - wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy wmempcpy \ | ||
16093 | + wmemcmp wmemmove wcpcpy wcpncpy wmempcpy \ | ||
16094 | btowc wctob mbsinit \ | ||
16095 | mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \ | ||
16096 | mbsnrtowcs wcsnrtombs wcsnlen wcschrnul \ | ||
16097 | @@ -38,14 +44,19 @@ | ||
16098 | wcscoll_l wcsxfrm_l \ | ||
16099 | wcscasecmp wcsncase wcscasecmp_l wcsncase_l \ | ||
16100 | wcsmbsload mbsrtowcs_l \ | ||
16101 | - isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \ | ||
16102 | isoc99_swscanf isoc99_vswscanf \ | ||
16103 | mbrtoc16 c16rtomb | ||
16104 | +routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \ | ||
16105 | + += isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf | ||
16106 | |||
16107 | strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy | ||
16108 | -tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ | ||
16109 | - tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ | ||
16110 | - tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) | ||
16111 | +tests := tst-wchar-h | ||
16112 | +tests-$(OPTION_EGLIBC_LOCALE_CODE) \ | ||
16113 | + += tst-btowc tst-mbrtowc tst-mbrtowc2 tst-wcrtomb tst-c16c32-1 | ||
16114 | +tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ | ||
16115 | + += tst-wcstof wcsmbs-tst1 tst-wcsnlen \ | ||
16116 | + tst-wcpncpy tst-mbsrtowcs \ | ||
16117 | + wcsatcliff $(addprefix test-,$(strop-tests)) | ||
16118 | tests-ifunc := $(strop-tests:%=test-%-ifunc) | ||
16119 | tests += $(tests-ifunc) | ||
16120 | |||
16121 | Index: git/wcsmbs/wcsmbsload.c | ||
16122 | =================================================================== | ||
16123 | --- git.orig/wcsmbs/wcsmbsload.c 2014-08-29 20:00:59.580070587 -0700 | ||
16124 | +++ git/wcsmbs/wcsmbsload.c 2014-08-29 20:01:15.248070587 -0700 | ||
16125 | @@ -21,6 +21,7 @@ | ||
16126 | #include <limits.h> | ||
16127 | #include <stdlib.h> | ||
16128 | #include <string.h> | ||
16129 | +#include <gnu/option-groups.h> | ||
16130 | |||
16131 | #include <locale/localeinfo.h> | ||
16132 | #include <wcsmbsload.h> | ||
16133 | @@ -143,6 +144,7 @@ | ||
16134 | }) | ||
16135 | |||
16136 | |||
16137 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
16138 | /* Some of the functions here must not be used while setlocale is called. */ | ||
16139 | __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden) | ||
16140 | |||
16141 | @@ -211,6 +213,17 @@ | ||
16142 | |||
16143 | __libc_rwlock_unlock (__libc_setlocale_lock); | ||
16144 | } | ||
16145 | +#else | ||
16146 | +void | ||
16147 | +internal_function | ||
16148 | +__wcsmbs_load_conv (struct __locale_data *new_category) | ||
16149 | +{ | ||
16150 | + /* When OPTION_EGLIBC_LOCALE_CODE is disabled, we should never reach | ||
16151 | + this point: there is no way to change locales, so every locale | ||
16152 | + passed to get_gconv_fcts should be _nl_C_LC_CTYPE. */ | ||
16153 | + abort (); | ||
16154 | +} | ||
16155 | +#endif | ||
16156 | |||
16157 | |||
16158 | /* Clone the current conversion function set. */ | ||
16159 | Index: git/wctype/Makefile | ||
16160 | =================================================================== | ||
16161 | --- git.orig/wctype/Makefile 2014-08-29 20:00:59.584070587 -0700 | ||
16162 | +++ git/wctype/Makefile 2014-08-29 20:01:15.248070587 -0700 | ||
16163 | @@ -18,14 +18,20 @@ | ||
16164 | # | ||
16165 | # Sub-makefile for wctype portion of the library. | ||
16166 | # | ||
16167 | +include ../option-groups.mak | ||
16168 | + | ||
16169 | subdir := wctype | ||
16170 | |||
16171 | include ../Makeconfig | ||
16172 | |||
16173 | headers := wctype.h | ||
16174 | -routines := wcfuncs wctype iswctype wctrans towctrans \ | ||
16175 | - wcfuncs_l wctype_l iswctype_l wctrans_l towctrans_l | ||
16176 | +routines := wctrans towctrans towctrans_l | ||
16177 | +routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ | ||
16178 | + := wcfuncs wctype iswctype \ | ||
16179 | + wcfuncs_l wctype_l iswctype_l wctrans_l | ||
16180 | |||
16181 | -tests := test_wctype test_wcfuncs bug-wctypeh | ||
16182 | +tests := | ||
16183 | +tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ | ||
16184 | + += test_wctype test_wcfuncs bug-wctypeh | ||
16185 | |||
16186 | include ../Rules | ||
16187 | Index: git/sysdeps/nptl/Makefile | ||
16188 | =================================================================== | ||
16189 | --- git.orig/sysdeps/nptl/Makefile 2014-08-29 20:00:58.036070587 -0700 | ||
16190 | +++ git/sysdeps/nptl/Makefile 2014-08-29 20:01:15.248070587 -0700 | ||
16191 | @@ -18,6 +18,9 @@ | ||
16192 | |||
16193 | ifeq ($(subdir),nptl) | ||
16194 | libpthread-sysdep_routines += errno-loc | ||
16195 | +ifeq ($(OPTION_EGLIBC_BIG_MACROS),n) | ||
16196 | +sysdep_routines += small-macros-fns | ||
16197 | +endif | ||
16198 | endif | ||
16199 | |||
16200 | ifeq ($(subdir),rt) | ||
16201 | Index: git/sysdeps/nptl/bits/libc-lock.h | ||
16202 | =================================================================== | ||
16203 | --- git.orig/sysdeps/nptl/bits/libc-lock.h 2014-08-29 20:00:58.036070587 -0700 | ||
16204 | +++ git/sysdeps/nptl/bits/libc-lock.h 2014-08-29 20:01:15.248070587 -0700 | ||
16205 | @@ -24,6 +24,14 @@ | ||
16206 | #include <stddef.h> | ||
16207 | |||
16208 | |||
16209 | +#ifdef _LIBC | ||
16210 | +# include <lowlevellock.h> | ||
16211 | +# include <tls.h> | ||
16212 | +# include <pthread-functions.h> | ||
16213 | +# include <errno.h> /* For EBUSY. */ | ||
16214 | +# include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */ | ||
16215 | +#endif | ||
16216 | + | ||
16217 | /* Mutex type. */ | ||
16218 | #if defined _LIBC || defined _IO_MTSAFE_IO | ||
16219 | # if (defined NOT_IN_libc && !defined IS_IN_libpthread) || !defined _LIBC | ||
16220 | @@ -87,6 +95,14 @@ | ||
16221 | |||
16222 | /* Lock the recursive named lock variable. */ | ||
16223 | #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) | ||
16224 | +# if __OPTION_EGLIBC_BIG_MACROS != 1 | ||
16225 | +/* EGLIBC: Declare wrapper function for a big macro if either | ||
16226 | + !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from | ||
16227 | + small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ | ||
16228 | +extern void __libc_lock_lock_recursive_fn (__libc_lock_recursive_t *); | ||
16229 | +libc_hidden_proto (__libc_lock_lock_recursive_fn); | ||
16230 | +# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ | ||
16231 | +# if __OPTION_EGLIBC_BIG_MACROS | ||
16232 | # define __libc_lock_lock_recursive(NAME) \ | ||
16233 | do { \ | ||
16234 | void *self = THREAD_SELF; \ | ||
16235 | @@ -97,6 +113,10 @@ | ||
16236 | } \ | ||
16237 | ++(NAME).cnt; \ | ||
16238 | } while (0) | ||
16239 | +# else | ||
16240 | +# define __libc_lock_lock_recursive(NAME) \ | ||
16241 | + __libc_lock_lock_recursive_fn (&(NAME)) | ||
16242 | +# endif /* __OPTION_EGLIBC_BIG_MACROS */ | ||
16243 | #else | ||
16244 | # define __libc_lock_lock_recursive(NAME) \ | ||
16245 | __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0) | ||
16246 | @@ -104,6 +124,14 @@ | ||
16247 | |||
16248 | /* Try to lock the recursive named lock variable. */ | ||
16249 | #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) | ||
16250 | +# if __OPTION_EGLIBC_BIG_MACROS != 1 | ||
16251 | +/* EGLIBC: Declare wrapper function for a big macro if either | ||
16252 | + !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from | ||
16253 | + small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ | ||
16254 | +extern int __libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *); | ||
16255 | +libc_hidden_proto (__libc_lock_trylock_recursive_fn); | ||
16256 | +# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ | ||
16257 | +# if __OPTION_EGLIBC_BIG_MACROS | ||
16258 | # define __libc_lock_trylock_recursive(NAME) \ | ||
16259 | ({ \ | ||
16260 | int result = 0; \ | ||
16261 | @@ -122,6 +150,10 @@ | ||
16262 | ++(NAME).cnt; \ | ||
16263 | result; \ | ||
16264 | }) | ||
16265 | +# else | ||
16266 | +# define __libc_lock_trylock_recursive(NAME) \ | ||
16267 | + __libc_lock_trylock_recursive_fn (&(NAME)) | ||
16268 | +# endif /* __OPTION_EGLIBC_BIG_MACROS */ | ||
16269 | #else | ||
16270 | # define __libc_lock_trylock_recursive(NAME) \ | ||
16271 | __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0) | ||
16272 | @@ -129,6 +161,14 @@ | ||
16273 | |||
16274 | /* Unlock the recursive named lock variable. */ | ||
16275 | #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) | ||
16276 | +# if __OPTION_EGLIBC_BIG_MACROS != 1 | ||
16277 | +/* EGLIBC: Declare wrapper function for a big macro if either | ||
16278 | + !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from | ||
16279 | + small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ | ||
16280 | +extern void __libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *); | ||
16281 | +libc_hidden_proto (__libc_lock_unlock_recursive_fn); | ||
16282 | +# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ | ||
16283 | +# if __OPTION_EGLIBC_BIG_MACROS | ||
16284 | /* We do no error checking here. */ | ||
16285 | # define __libc_lock_unlock_recursive(NAME) \ | ||
16286 | do { \ | ||
16287 | @@ -138,6 +178,10 @@ | ||
16288 | lll_unlock ((NAME).lock, LLL_PRIVATE); \ | ||
16289 | } \ | ||
16290 | } while (0) | ||
16291 | +# else | ||
16292 | +# define __libc_lock_unlock_recursive(NAME) \ | ||
16293 | + __libc_lock_unlock_recursive_fn (&(NAME)) | ||
16294 | +# endif /* __OPTION_EGLIBC_BIG_MACROS */ | ||
16295 | #else | ||
16296 | # define __libc_lock_unlock_recursive(NAME) \ | ||
16297 | __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0) | ||
16298 | Index: git/sysdeps/nptl/bits/libc-lockP.h | ||
16299 | =================================================================== | ||
16300 | --- git.orig/sysdeps/nptl/bits/libc-lockP.h 2014-08-29 20:00:58.044070587 -0700 | ||
16301 | +++ git/sysdeps/nptl/bits/libc-lockP.h 2014-08-29 20:01:15.248070587 -0700 | ||
16302 | @@ -33,6 +33,8 @@ | ||
16303 | #include <lowlevellock.h> | ||
16304 | #include <tls.h> | ||
16305 | #include <pthread-functions.h> | ||
16306 | +#include <errno.h> /* For EBUSY. */ | ||
16307 | +#include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */ | ||
16308 | |||
16309 | /* Mutex type. */ | ||
16310 | #if defined NOT_IN_libc && !defined IS_IN_libpthread | ||
16311 | @@ -159,10 +161,22 @@ | ||
16312 | |||
16313 | /* Lock the named lock variable. */ | ||
16314 | #if !defined NOT_IN_libc || defined IS_IN_libpthread | ||
16315 | -# ifndef __libc_lock_lock | ||
16316 | -# define __libc_lock_lock(NAME) \ | ||
16317 | +# if __OPTION_EGLIBC_BIG_MACROS != 1 | ||
16318 | +/* EGLIBC: Declare wrapper function for a big macro if either | ||
16319 | + !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from | ||
16320 | + small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ | ||
16321 | +extern void __libc_lock_lock_fn (__libc_lock_t *); | ||
16322 | +libc_hidden_proto (__libc_lock_lock_fn); | ||
16323 | +# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ | ||
16324 | +# if __OPTION_EGLIBC_BIG_MACROS | ||
16325 | +# ifndef __libc_lock_lock | ||
16326 | +# define __libc_lock_lock(NAME) \ | ||
16327 | ({ lll_lock (NAME, LLL_PRIVATE); 0; }) | ||
16328 | -# endif | ||
16329 | +# endif | ||
16330 | +# else | ||
16331 | +# define __libc_lock_lock(NAME) \ | ||
16332 | + __libc_lock_lock_fn (&(NAME)) | ||
16333 | +# endif /* __OPTION_EGLIBC_BIG_MACROS */ | ||
16334 | #else | ||
16335 | # undef __libc_lock_lock | ||
16336 | # define __libc_lock_lock(NAME) \ | ||
16337 | @@ -175,10 +189,22 @@ | ||
16338 | |||
16339 | /* Try to lock the named lock variable. */ | ||
16340 | #if !defined NOT_IN_libc || defined IS_IN_libpthread | ||
16341 | -# ifndef __libc_lock_trylock | ||
16342 | -# define __libc_lock_trylock(NAME) \ | ||
16343 | +# if __OPTION_EGLIBC_BIG_MACROS != 1 | ||
16344 | +/* EGLIBC: Declare wrapper function for a big macro if either | ||
16345 | + !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from | ||
16346 | + small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ | ||
16347 | +extern int __libc_lock_trylock_fn (__libc_lock_t *); | ||
16348 | +libc_hidden_proto (__libc_lock_trylock_fn); | ||
16349 | +# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ | ||
16350 | +# if __OPTION_EGLIBC_BIG_MACROS | ||
16351 | +# ifndef __libc_lock_trylock | ||
16352 | +# define __libc_lock_trylock(NAME) \ | ||
16353 | lll_trylock (NAME) | ||
16354 | -# endif | ||
16355 | +# endif | ||
16356 | +# else | ||
16357 | +# define __libc_lock_trylock(NAME) \ | ||
16358 | + __libc_lock_trylock_fn (&(NAME)) | ||
16359 | +# endif /* __OPTION_EGLIBC_BIG_MACROS */ | ||
16360 | #else | ||
16361 | # undef __libc_lock_trylock | ||
16362 | # define __libc_lock_trylock(NAME) \ | ||
16363 | @@ -194,8 +220,20 @@ | ||
16364 | |||
16365 | /* Unlock the named lock variable. */ | ||
16366 | #if !defined NOT_IN_libc || defined IS_IN_libpthread | ||
16367 | +# if __OPTION_EGLIBC_BIG_MACROS != 1 | ||
16368 | +/* EGLIBC: Declare wrapper function for a big macro if either | ||
16369 | + !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from | ||
16370 | + small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */ | ||
16371 | +extern void __libc_lock_unlock_fn (__libc_lock_t *); | ||
16372 | +libc_hidden_proto (__libc_lock_unlock_fn); | ||
16373 | +# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */ | ||
16374 | +# if __OPTION_EGLIBC_BIG_MACROS | ||
16375 | # define __libc_lock_unlock(NAME) \ | ||
16376 | lll_unlock (NAME, LLL_PRIVATE) | ||
16377 | +# else | ||
16378 | +# define __libc_lock_unlock(NAME) \ | ||
16379 | + __libc_lock_unlock_fn (&(NAME)) | ||
16380 | +# endif /* __OPTION_EGLIBC_BIG_MACROS */ | ||
16381 | #else | ||
16382 | # define __libc_lock_unlock(NAME) \ | ||
16383 | __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0) | ||
16384 | Index: git/sysdeps/nptl/small-macros-fns.c | ||
16385 | =================================================================== | ||
16386 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
16387 | +++ git/sysdeps/nptl/small-macros-fns.c 2014-08-29 20:01:15.248070587 -0700 | ||
16388 | @@ -0,0 +1,72 @@ | ||
16389 | +/* EGLIBC: function wrappers for big macros. | ||
16390 | + Copyright (C) 2009 Free Software Foundation, Inc. | ||
16391 | + This file is part of the GNU C Library. | ||
16392 | + | ||
16393 | + The GNU C Library is free software; you can redistribute it and/or | ||
16394 | + modify it under the terms of the GNU Lesser General Public License as | ||
16395 | + published by the Free Software Foundation; either version 2.1 of the | ||
16396 | + License, or (at your option) any later version. | ||
16397 | + | ||
16398 | + The GNU C Library is distributed in the hope that it will be useful, | ||
16399 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16400 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16401 | + Lesser General Public License for more details. | ||
16402 | + | ||
16403 | + You should have received a copy of the GNU Lesser General Public | ||
16404 | + License along with the GNU C Library; see the file COPYING.LIB. If not, | ||
16405 | + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
16406 | + Boston, MA 02111-1307, USA. */ | ||
16407 | + | ||
16408 | +#include <gnu/option-groups.h> | ||
16409 | + | ||
16410 | +/* Handle macros from ./bits/libc-lock.h. */ | ||
16411 | +#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) | ||
16412 | + | ||
16413 | +/* Get the macros for function bodies through a back door. */ | ||
16414 | +# undef __OPTION_EGLIBC_BIG_MACROS | ||
16415 | +# define __OPTION_EGLIBC_BIG_MACROS 2 | ||
16416 | +# include <bits/libc-lock.h> | ||
16417 | + | ||
16418 | +void | ||
16419 | +__libc_lock_lock_fn (__libc_lock_t *name) | ||
16420 | +{ | ||
16421 | + __libc_lock_lock (*name); | ||
16422 | +} | ||
16423 | +libc_hidden_def (__libc_lock_lock_fn); | ||
16424 | + | ||
16425 | +void | ||
16426 | +__libc_lock_lock_recursive_fn (__libc_lock_recursive_t *name) | ||
16427 | +{ | ||
16428 | + __libc_lock_lock_recursive (*name); | ||
16429 | +} | ||
16430 | +libc_hidden_def (__libc_lock_lock_recursive_fn); | ||
16431 | + | ||
16432 | +int | ||
16433 | +__libc_lock_trylock_fn (__libc_lock_t *name) | ||
16434 | +{ | ||
16435 | + return __libc_lock_trylock (*name); | ||
16436 | +} | ||
16437 | +libc_hidden_def (__libc_lock_trylock_fn); | ||
16438 | + | ||
16439 | +int | ||
16440 | +__libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *name) | ||
16441 | +{ | ||
16442 | + return __libc_lock_trylock_recursive (*name); | ||
16443 | +} | ||
16444 | +libc_hidden_def (__libc_lock_trylock_recursive_fn); | ||
16445 | + | ||
16446 | +void | ||
16447 | +__libc_lock_unlock_fn (__libc_lock_t *name) | ||
16448 | +{ | ||
16449 | + __libc_lock_unlock (*name); | ||
16450 | +} | ||
16451 | +libc_hidden_def (__libc_lock_unlock_fn); | ||
16452 | + | ||
16453 | +void | ||
16454 | +__libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *name) | ||
16455 | +{ | ||
16456 | + __libc_lock_unlock_recursive (*name); | ||
16457 | +} | ||
16458 | +libc_hidden_def (__libc_lock_unlock_recursive_fn); | ||
16459 | + | ||
16460 | +#endif /*defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)*/ | ||
16461 | Index: git/include/libc-symbols.h | ||
16462 | =================================================================== | ||
16463 | --- git.orig/include/libc-symbols.h 2014-08-29 20:00:47.144070587 -0700 | ||
16464 | +++ git/include/libc-symbols.h 2014-08-29 20:01:15.248070587 -0700 | ||
16465 | @@ -60,8 +60,11 @@ | ||
16466 | /* Define these macros for the benefit of portable GNU code that wants to check | ||
16467 | them. Of course, STDC_HEADERS is never false when building libc! */ | ||
16468 | #define STDC_HEADERS 1 | ||
16469 | -#define HAVE_MBSTATE_T 1 | ||
16470 | -#define HAVE_MBSRTOWCS 1 | ||
16471 | + | ||
16472 | +#if __OPTION_EGLIBC_LOCALE_CODE | ||
16473 | +# define HAVE_MBSTATE_T 1 | ||
16474 | +# define HAVE_MBSRTOWCS 1 | ||
16475 | +#endif | ||
16476 | #define HAVE_LIBINTL_H 1 | ||
16477 | #define HAVE_WCTYPE_H 1 | ||
16478 | #define HAVE_ISWCTYPE 1 | ||
16479 | Index: git/crypt/crypt_common.c | ||
16480 | =================================================================== | ||
16481 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
16482 | +++ git/crypt/crypt_common.c 2014-08-29 20:01:15.248070587 -0700 | ||
16483 | @@ -0,0 +1,42 @@ | ||
16484 | +/* | ||
16485 | + * crypt: crypt(3) implementation | ||
16486 | + * | ||
16487 | + * Copyright (C) 1991-2014 Free Software Foundation, Inc. | ||
16488 | + * | ||
16489 | + * This library is free software; you can redistribute it and/or | ||
16490 | + * modify it under the terms of the GNU Lesser General Public | ||
16491 | + * License as published by the Free Software Foundation; either | ||
16492 | + * version 2.1 of the License, or (at your option) any later version. | ||
16493 | + * | ||
16494 | + * This library is distributed in the hope that it will be useful, | ||
16495 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16496 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16497 | + * Lesser General Public License for more details. | ||
16498 | + * | ||
16499 | + * You should have received a copy of the GNU Lesser General Public | ||
16500 | + * License along with this library; see the file COPYING.LIB. If not, | ||
16501 | + * see <http://www.gnu.org/licenses/>. | ||
16502 | + * | ||
16503 | + * General Support routines | ||
16504 | + * | ||
16505 | + */ | ||
16506 | + | ||
16507 | +#include "crypt-private.h" | ||
16508 | + | ||
16509 | +/* Table with characters for base64 transformation. */ | ||
16510 | +static const char b64t[64] = | ||
16511 | +"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
16512 | + | ||
16513 | +void | ||
16514 | +__b64_from_24bit (char **cp, int *buflen, | ||
16515 | + unsigned int b2, unsigned int b1, unsigned int b0, | ||
16516 | + int n) | ||
16517 | +{ | ||
16518 | + unsigned int w = (b2 << 16) | (b1 << 8) | b0; | ||
16519 | + while (n-- > 0 && (*buflen) > 0) | ||
16520 | + { | ||
16521 | + *(*cp)++ = b64t[w & 0x3f]; | ||
16522 | + --(*buflen); | ||
16523 | + w >>= 6; | ||
16524 | + } | ||
16525 | +} | ||
16526 | Index: git/crypt/crypt_util.c | ||
16527 | =================================================================== | ||
16528 | --- git.orig/crypt/crypt_util.c 2014-08-29 20:00:43.028070587 -0700 | ||
16529 | +++ git/crypt/crypt_util.c 2014-08-29 20:01:15.248070587 -0700 | ||
16530 | @@ -242,10 +242,6 @@ | ||
16531 | */ | ||
16532 | static ufc_long efp[16][64][2]; | ||
16533 | |||
16534 | -/* Table with characters for base64 transformation. */ | ||
16535 | -static const char b64t[64] = | ||
16536 | -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
16537 | - | ||
16538 | /* | ||
16539 | * For use by the old, non-reentrant routines | ||
16540 | * (crypt/encrypt/setkey) | ||
16541 | @@ -949,17 +945,3 @@ | ||
16542 | { | ||
16543 | __setkey_r(__key, &_ufc_foobar); | ||
16544 | } | ||
16545 | - | ||
16546 | -void | ||
16547 | -__b64_from_24bit (char **cp, int *buflen, | ||
16548 | - unsigned int b2, unsigned int b1, unsigned int b0, | ||
16549 | - int n) | ||
16550 | -{ | ||
16551 | - unsigned int w = (b2 << 16) | (b1 << 8) | b0; | ||
16552 | - while (n-- > 0 && (*buflen) > 0) | ||
16553 | - { | ||
16554 | - *(*cp)++ = b64t[w & 0x3f]; | ||
16555 | - --(*buflen); | ||
16556 | - w >>= 6; | ||
16557 | - } | ||
16558 | -} | ||
16559 | Index: git/sysdeps/arm/Makefile | ||
16560 | =================================================================== | ||
16561 | --- git.orig/sysdeps/arm/Makefile 2014-08-29 20:29:37.000000000 -0700 | ||
16562 | +++ git/sysdeps/arm/Makefile 2014-08-29 20:31:09.904070587 -0700 | ||
16563 | @@ -37,10 +37,13 @@ | ||
16564 | # get offset to rtld_global._dl_hwcap | ||
16565 | gen-as-const-headers += rtld-global-offsets.sym tlsdesc.sym | ||
16566 | aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math | ||
16567 | -aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \ | ||
16568 | +aeabi_routines = aeabi_assert aeabi_errno_addr \ | ||
16569 | aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \ | ||
16570 | aeabi_memmove aeabi_memset \ | ||
16571 | aeabi_read_tp libc-aeabi_read_tp | ||
16572 | +ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE)) | ||
16573 | +aeabi_routines += aeabi_localeconv | ||
16574 | +endif | ||
16575 | |||
16576 | sysdep_routines += $(aeabi_constants) $(aeabi_routines) | ||
16577 | static-only-routines += $(aeabi_constants) aeabi_read_tp | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc.patch new file mode 100644 index 0000000..fdfabc3 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/eglibc.patch | |||
@@ -0,0 +1,602 @@ | |||
1 | Instruction documents from eglibc | ||
2 | |||
3 | Upstream-Status: Pending | ||
4 | |||
5 | Index: git/EGLIBC.cross-building | ||
6 | =================================================================== | ||
7 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
8 | +++ git/EGLIBC.cross-building 2014-08-27 07:27:25.580070587 +0000 | ||
9 | @@ -0,0 +1,383 @@ | ||
10 | + -*- mode: text -*- | ||
11 | + | ||
12 | + Cross-Compiling EGLIBC | ||
13 | + Jim Blandy <jimb@codesourcery.com> | ||
14 | + | ||
15 | + | ||
16 | +Introduction | ||
17 | + | ||
18 | +Most GNU tools have a simple build procedure: you run their | ||
19 | +'configure' script, and then you run 'make'. Unfortunately, the | ||
20 | +process of cross-compiling the GNU C library is quite a bit more | ||
21 | +involved: | ||
22 | + | ||
23 | +1) Build a cross-compiler, with certain facilities disabled. | ||
24 | + | ||
25 | +2) Configure the C library using the compiler you built in step 1). | ||
26 | + Build a few of the C run-time object files, but not the rest of the | ||
27 | + library. Install the library's header files and the run-time | ||
28 | + object files, and create a dummy libc.so. | ||
29 | + | ||
30 | +3) Build a second cross-compiler, using the header files and object | ||
31 | + files you installed in step 2. | ||
32 | + | ||
33 | +4) Configure, build, and install a fresh C library, using the compiler | ||
34 | + built in step 3. | ||
35 | + | ||
36 | +5) Build a third cross-compiler, based on the C library built in step 4. | ||
37 | + | ||
38 | +The reason for this complexity is that, although GCC and the GNU C | ||
39 | +library are distributed separately, they are not actually independent | ||
40 | +of each other: GCC requires the C library's headers and some object | ||
41 | +files to compile its own libraries, while the C library depends on | ||
42 | +GCC's libraries. EGLIBC includes features and bug fixes to the stock | ||
43 | +GNU C library that simplify this process, but the fundamental | ||
44 | +interdependency stands. | ||
45 | + | ||
46 | +In this document, we explain how to cross-compile an EGLIBC/GCC pair | ||
47 | +from source. Our intended audience is developers who are already | ||
48 | +familiar with the GNU toolchain and comfortable working with | ||
49 | +cross-development tools. While we do present a worked example to | ||
50 | +accompany the explanation, for clarity's sake we do not cover many of | ||
51 | +the options available to cross-toolchain users. | ||
52 | + | ||
53 | + | ||
54 | +Preparation | ||
55 | + | ||
56 | +EGLIBC requires recent versions of the GNU binutils, GCC, and the | ||
57 | +Linux kernel. The web page <http://www.eglibc.org/prerequisites> | ||
58 | +documents the current requirements, and lists patches needed for | ||
59 | +certain target architectures. As of this writing, these build | ||
60 | +instructions have been tested with binutils 2.22.51, GCC 4.6.2, | ||
61 | +and Linux 3.1. | ||
62 | + | ||
63 | +First, let's set some variables, to simplify later commands. We'll | ||
64 | +build EGLIBC and GCC for an ARM target, known to the Linux kernel | ||
65 | +as 'arm', and we'll do the build on an Intel x86_64 Linux box: | ||
66 | + | ||
67 | + $ build=x86_64-pc-linux-gnu | ||
68 | + $ host=$build | ||
69 | + $ target=arm-none-linux-gnueabi | ||
70 | + $ linux_arch=arm | ||
71 | + | ||
72 | +We're using the aforementioned versions of Binutils, GCC, and Linux: | ||
73 | + | ||
74 | + $ binutilsv=binutils-2.22.51 | ||
75 | + $ gccv=gcc-4.6.2 | ||
76 | + $ linuxv=linux-3.1 | ||
77 | + | ||
78 | +We're carrying out the entire process under '~/cross-build', which | ||
79 | +contains unpacked source trees for binutils, gcc, and linux kernel, | ||
80 | +along with EGLIBC svn trunk (which can be checked-out with | ||
81 | +'svn co http://www.eglibc.org/svn/trunk eglibc'): | ||
82 | + | ||
83 | + $ top=$HOME/cross-build/$target | ||
84 | + $ src=$HOME/cross-build/src | ||
85 | + $ ls $src | ||
86 | + binutils-2.22.51 eglibc gcc-4.6.2 linux-3.1 | ||
87 | + | ||
88 | +We're going to place our build directories in a subdirectory 'obj', | ||
89 | +we'll install the cross-development toolchain in 'tools', and we'll | ||
90 | +place our sysroot (containing files to be installed on the target | ||
91 | +system) in 'sysroot': | ||
92 | + | ||
93 | + $ obj=$top/obj | ||
94 | + $ tools=$top/tools | ||
95 | + $ sysroot=$top/sysroot | ||
96 | + | ||
97 | + | ||
98 | +Binutils | ||
99 | + | ||
100 | +Configuring and building binutils for the target is straightforward: | ||
101 | + | ||
102 | + $ mkdir -p $obj/binutils | ||
103 | + $ cd $obj/binutils | ||
104 | + $ $src/$binutilsv/configure \ | ||
105 | + > --target=$target \ | ||
106 | + > --prefix=$tools \ | ||
107 | + > --with-sysroot=$sysroot | ||
108 | + $ make | ||
109 | + $ make install | ||
110 | + | ||
111 | + | ||
112 | +The First GCC | ||
113 | + | ||
114 | +For our work, we need a cross-compiler targeting an ARM Linux | ||
115 | +system. However, that configuration includes the shared library | ||
116 | +'libgcc_s.so', which is compiled against the EGLIBC headers (which we | ||
117 | +haven't installed yet) and linked against 'libc.so' (which we haven't | ||
118 | +built yet). | ||
119 | + | ||
120 | +Fortunately, there are configuration options for GCC which tell it not | ||
121 | +to build 'libgcc_s.so'. The '--without-headers' option is supposed to | ||
122 | +take care of this, but its implementation is incomplete, so you must | ||
123 | +also configure with the '--with-newlib' option. While '--with-newlib' | ||
124 | +appears to mean "Use the Newlib C library", its effect is to tell the | ||
125 | +GCC build machinery, "Don't assume there is a C library available." | ||
126 | + | ||
127 | +We also need to disable some of the libraries that would normally be | ||
128 | +built along with GCC, and specify that only the compiler for the C | ||
129 | +language is needed. | ||
130 | + | ||
131 | +So, we create a build directory, configure, make, and install. | ||
132 | + | ||
133 | + $ mkdir -p $obj/gcc1 | ||
134 | + $ cd $obj/gcc1 | ||
135 | + $ $src/$gccv/configure \ | ||
136 | + > --target=$target \ | ||
137 | + > --prefix=$tools \ | ||
138 | + > --without-headers --with-newlib \ | ||
139 | + > --disable-shared --disable-threads --disable-libssp \ | ||
140 | + > --disable-libgomp --disable-libmudflap --disable-libquadmath \ | ||
141 | + > --disable-decimal-float --disable-libffi \ | ||
142 | + > --enable-languages=c | ||
143 | + $ PATH=$tools/bin:$PATH make | ||
144 | + $ PATH=$tools/bin:$PATH make install | ||
145 | + | ||
146 | + | ||
147 | +Linux Kernel Headers | ||
148 | + | ||
149 | +To configure EGLIBC, we also need Linux kernel headers in place. | ||
150 | +Fortunately, the Linux makefiles have a target that installs them for | ||
151 | +us. Since the process does modify the source tree a bit, we make a | ||
152 | +copy first: | ||
153 | + | ||
154 | + $ cp -r $src/$linuxv $obj/linux | ||
155 | + $ cd $obj/linux | ||
156 | + | ||
157 | +Now we're ready to install the headers into the sysroot: | ||
158 | + | ||
159 | + $ PATH=$tools/bin:$PATH \ | ||
160 | + > make headers_install \ | ||
161 | + > ARCH=$linux_arch CROSS_COMPILE=$target- \ | ||
162 | + > INSTALL_HDR_PATH=$sysroot/usr | ||
163 | + | ||
164 | + | ||
165 | +EGLIBC Headers and Preliminary Objects | ||
166 | + | ||
167 | +Using the cross-compiler we've just built, we can now configure EGLIBC | ||
168 | +well enough to install the headers and build the object files that the | ||
169 | +full cross-compiler will need: | ||
170 | + | ||
171 | + $ mkdir -p $obj/eglibc-headers | ||
172 | + $ cd $obj/eglibc-headers | ||
173 | + $ BUILD_CC=gcc \ | ||
174 | + > CC=$tools/bin/$target-gcc \ | ||
175 | + > CXX=$tools/bin/$target-g++ \ | ||
176 | + > AR=$tools/bin/$target-ar \ | ||
177 | + > RANLIB=$tools/bin/$target-ranlib \ | ||
178 | + > $src/eglibc/libc/configure \ | ||
179 | + > --prefix=/usr \ | ||
180 | + > --with-headers=$sysroot/usr/include \ | ||
181 | + > --build=$build \ | ||
182 | + > --host=$target \ | ||
183 | + > --disable-profile --without-gd --without-cvs \ | ||
184 | + > --enable-add-ons=nptl,libidn,../ports | ||
185 | + | ||
186 | +The option '--prefix=/usr' may look strange, but you should never | ||
187 | +configure EGLIBC with a prefix other than '/usr': in various places, | ||
188 | +EGLIBC's build system checks whether the prefix is '/usr', and does | ||
189 | +special handling only if that is the case. Unless you use this | ||
190 | +prefix, you will get a sysroot that does not use the standard Linux | ||
191 | +directory layouts and cannot be used as a basis for the root | ||
192 | +filesystem on your target system compatibly with normal GLIBC | ||
193 | +installations. | ||
194 | + | ||
195 | +The '--with-headers' option tells EGLIBC where the Linux headers have | ||
196 | +been installed. | ||
197 | + | ||
198 | +The '--enable-add-ons=nptl,libidn,../ports' option tells EGLIBC to look | ||
199 | +for the listed glibc add-ons. Most notably the ports add-on (located | ||
200 | +just above the libc sources in the EGLIBC svn tree) is required to | ||
201 | +support ARM targets. | ||
202 | + | ||
203 | +We can now use the 'install-headers' makefile target to install the | ||
204 | +headers: | ||
205 | + | ||
206 | + $ make install-headers install_root=$sysroot \ | ||
207 | + > install-bootstrap-headers=yes | ||
208 | + | ||
209 | +The 'install_root' variable indicates where the files should actually | ||
210 | +be installed; its value is treated as the parent of the '--prefix' | ||
211 | +directory we passed to the configure script, so the headers will go in | ||
212 | +'$sysroot/usr/include'. The 'install-bootstrap-headers' variable | ||
213 | +requests special handling for certain tricky header files. | ||
214 | + | ||
215 | +Next, there are a few object files needed to link shared libraries, | ||
216 | +which we build and install by hand: | ||
217 | + | ||
218 | + $ mkdir -p $sysroot/usr/lib | ||
219 | + $ make csu/subdir_lib | ||
220 | + $ cp csu/crt1.o csu/crti.o csu/crtn.o $sysroot/usr/lib | ||
221 | + | ||
222 | +Finally, 'libgcc_s.so' requires a 'libc.so' to link against. However, | ||
223 | +since we will never actually execute its code, it doesn't matter what | ||
224 | +it contains. So, treating '/dev/null' as a C source file, we produce | ||
225 | +a dummy 'libc.so' in one step: | ||
226 | + | ||
227 | + $ $tools/bin/$target-gcc -nostdlib -nostartfiles -shared -x c /dev/null \ | ||
228 | + > -o $sysroot/usr/lib/libc.so | ||
229 | + | ||
230 | + | ||
231 | +The Second GCC | ||
232 | + | ||
233 | +With the EGLIBC headers and selected object files installed, we can | ||
234 | +now build a GCC that is capable of compiling EGLIBC. We configure, | ||
235 | +build, and install the second GCC, again building only the C compiler, | ||
236 | +and avoiding libraries we won't use: | ||
237 | + | ||
238 | + $ mkdir -p $obj/gcc2 | ||
239 | + $ cd $obj/gcc2 | ||
240 | + $ $src/$gccv/configure \ | ||
241 | + > --target=$target \ | ||
242 | + > --prefix=$tools \ | ||
243 | + > --with-sysroot=$sysroot \ | ||
244 | + > --disable-libssp --disable-libgomp --disable-libmudflap \ | ||
245 | + > --disable-libffi --disable-libquadmath \ | ||
246 | + > --enable-languages=c | ||
247 | + $ PATH=$tools/bin:$PATH make | ||
248 | + $ PATH=$tools/bin:$PATH make install | ||
249 | + | ||
250 | + | ||
251 | +EGLIBC, Complete | ||
252 | + | ||
253 | +With the second compiler built and installed, we're now ready for the | ||
254 | +full EGLIBC build: | ||
255 | + | ||
256 | + $ mkdir -p $obj/eglibc | ||
257 | + $ cd $obj/eglibc | ||
258 | + $ BUILD_CC=gcc \ | ||
259 | + > CC=$tools/bin/$target-gcc \ | ||
260 | + > CXX=$tools/bin/$target-g++ \ | ||
261 | + > AR=$tools/bin/$target-ar \ | ||
262 | + > RANLIB=$tools/bin/$target-ranlib \ | ||
263 | + > $src/eglibc/libc/configure \ | ||
264 | + > --prefix=/usr \ | ||
265 | + > --with-headers=$sysroot/usr/include \ | ||
266 | + > --with-kconfig=$obj/linux/scripts/kconfig \ | ||
267 | + > --build=$build \ | ||
268 | + > --host=$target \ | ||
269 | + > --disable-profile --without-gd --without-cvs \ | ||
270 | + > --enable-add-ons=nptl,libidn,../ports | ||
271 | + | ||
272 | +Note the additional '--with-kconfig' option. This tells EGLIBC where to | ||
273 | +find the host config tools used by the kernel 'make config' and 'make | ||
274 | +menuconfig'. These tools can be re-used by EGLIBC for its own 'make | ||
275 | +*config' support, which will create 'option-groups.config' for you. | ||
276 | +But first make sure those tools have been built by running some | ||
277 | +dummy 'make *config' calls in the kernel directory: | ||
278 | + | ||
279 | + $ cd $obj/linux | ||
280 | + $ PATH=$tools/bin:$PATH make config \ | ||
281 | + > ARCH=$linux_arch CROSS_COMPILE=$target- \ | ||
282 | + $ PATH=$tools/bin:$PATH make menuconfig \ | ||
283 | + > ARCH=$linux_arch CROSS_COMPILE=$target- \ | ||
284 | + | ||
285 | +Now we can configure and build the full EGLIBC: | ||
286 | + | ||
287 | + $ cd $obj/eglibc | ||
288 | + $ PATH=$tools/bin:$PATH make defconfig | ||
289 | + $ PATH=$tools/bin:$PATH make menuconfig | ||
290 | + $ PATH=$tools/bin:$PATH make | ||
291 | + $ PATH=$tools/bin:$PATH make install install_root=$sysroot | ||
292 | + | ||
293 | +At this point, we have a complete EGLIBC installation in '$sysroot', | ||
294 | +with header files, library files, and most of the C runtime startup | ||
295 | +files in place. | ||
296 | + | ||
297 | + | ||
298 | +The Third GCC | ||
299 | + | ||
300 | +Finally, we recompile GCC against this full installation, enabling | ||
301 | +whatever languages and libraries we would like to use: | ||
302 | + | ||
303 | + $ mkdir -p $obj/gcc3 | ||
304 | + $ cd $obj/gcc3 | ||
305 | + $ $src/$gccv/configure \ | ||
306 | + > --target=$target \ | ||
307 | + > --prefix=$tools \ | ||
308 | + > --with-sysroot=$sysroot \ | ||
309 | + > --enable-__cxa_atexit \ | ||
310 | + > --disable-libssp --disable-libgomp --disable-libmudflap \ | ||
311 | + > --enable-languages=c,c++ | ||
312 | + $ PATH=$tools/bin:$PATH make | ||
313 | + $ PATH=$tools/bin:$PATH make install | ||
314 | + | ||
315 | +The '--enable-__cxa_atexit' option tells GCC what sort of C++ | ||
316 | +destructor support to expect from the C library; it's required with | ||
317 | +EGLIBC. | ||
318 | + | ||
319 | +And since GCC's installation process isn't designed to help construct | ||
320 | +sysroot trees, we must manually copy certain libraries into place in | ||
321 | +the sysroot. | ||
322 | + | ||
323 | + $ cp -d $tools/$target/lib/libgcc_s.so* $sysroot/lib | ||
324 | + $ cp -d $tools/$target/lib/libstdc++.so* $sysroot/usr/lib | ||
325 | + | ||
326 | + | ||
327 | +Trying Things Out | ||
328 | + | ||
329 | +At this point, '$tools' contains a cross toolchain ready to use | ||
330 | +the EGLIBC installation in '$sysroot': | ||
331 | + | ||
332 | + $ cat > hello.c <<EOF | ||
333 | + > #include <stdio.h> | ||
334 | + > int | ||
335 | + > main (int argc, char **argv) | ||
336 | + > { | ||
337 | + > puts ("Hello, world!"); | ||
338 | + > return 0; | ||
339 | + > } | ||
340 | + > EOF | ||
341 | + $ $tools/bin/$target-gcc -Wall hello.c -o hello | ||
342 | + $ cat > c++-hello.cc <<EOF | ||
343 | + > #include <iostream> | ||
344 | + > int | ||
345 | + > main (int argc, char **argv) | ||
346 | + > { | ||
347 | + > std::cout << "Hello, C++ world!" << std::endl; | ||
348 | + > return 0; | ||
349 | + > } | ||
350 | + > EOF | ||
351 | + $ $tools/bin/$target-g++ -Wall c++-hello.cc -o c++-hello | ||
352 | + | ||
353 | + | ||
354 | +We can use 'readelf' to verify that these are indeed executables for | ||
355 | +our target, using our dynamic linker: | ||
356 | + | ||
357 | + $ $tools/bin/$target-readelf -hl hello | ||
358 | + ELF Header: | ||
359 | + ... | ||
360 | + Type: EXEC (Executable file) | ||
361 | + Machine: ARM | ||
362 | + | ||
363 | + ... | ||
364 | + Program Headers: | ||
365 | + Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align | ||
366 | + PHDR 0x000034 0x10000034 0x10000034 0x00100 0x00100 R E 0x4 | ||
367 | + INTERP 0x000134 0x00008134 0x00008134 0x00013 0x00013 R 0x1 | ||
368 | + [Requesting program interpreter: /lib/ld-linux.so.3] | ||
369 | + LOAD 0x000000 0x00008000 0x00008000 0x0042c 0x0042c R E 0x8000 | ||
370 | + ... | ||
371 | + | ||
372 | +Looking at the dynamic section of the installed 'libgcc_s.so', we see | ||
373 | +that the 'NEEDED' entry for the C library does include the '.6' | ||
374 | +suffix, indicating that was linked against our fully build EGLIBC, and | ||
375 | +not our dummy 'libc.so': | ||
376 | + | ||
377 | + $ $tools/bin/$target-readelf -d $sysroot/lib/libgcc_s.so.1 | ||
378 | + Dynamic section at offset 0x1083c contains 24 entries: | ||
379 | + Tag Type Name/Value | ||
380 | + 0x00000001 (NEEDED) Shared library: [libc.so.6] | ||
381 | + 0x0000000e (SONAME) Library soname: [libgcc_s.so.1] | ||
382 | + ... | ||
383 | + | ||
384 | + | ||
385 | +And on the target machine, we can run our programs: | ||
386 | + | ||
387 | + $ $sysroot/lib/ld.so.1 --library-path $sysroot/lib:$sysroot/usr/lib \ | ||
388 | + > ./hello | ||
389 | + Hello, world! | ||
390 | + $ $sysroot/lib/ld.so.1 --library-path $sysroot/lib:$sysroot/usr/lib \ | ||
391 | + > ./c++-hello | ||
392 | + Hello, C++ world! | ||
393 | Index: git/EGLIBC.cross-testing | ||
394 | =================================================================== | ||
395 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
396 | +++ git/EGLIBC.cross-testing 2014-08-27 07:24:41.532070587 +0000 | ||
397 | @@ -0,0 +1,205 @@ | ||
398 | + -*- mode: text -*- | ||
399 | + | ||
400 | + Cross-Testing With EGLIBC | ||
401 | + Jim Blandy <jimb@codesourcery.com> | ||
402 | + | ||
403 | + | ||
404 | +Introduction | ||
405 | + | ||
406 | +Developers writing software for embedded systems often use a desktop | ||
407 | +or other similarly capable computer for development, but need to run | ||
408 | +tests on the embedded system, or perhaps on a simulator. When | ||
409 | +configured for cross-compilation, the stock GNU C library simply | ||
410 | +disables running tests altogether: the command 'make tests' builds | ||
411 | +test programs, but does not run them. EGLIBC, however, provides | ||
412 | +facilities for compiling tests and generating data files on the build | ||
413 | +system, but running the test programs themselves on a remote system or | ||
414 | +simulator. | ||
415 | + | ||
416 | + | ||
417 | +Test environment requirements | ||
418 | + | ||
419 | +The test environment must meet certain conditions for EGLIBC's | ||
420 | +cross-testing facilities to work: | ||
421 | + | ||
422 | +- Shared filesystems. The 'build' system, on which you configure and | ||
423 | + compile EGLIBC, and the 'host' system, on which you intend to run | ||
424 | + EGLIBC, must share a filesystem containing the EGLIBC build and | ||
425 | + source trees. Files must appear at the same paths on both systems. | ||
426 | + | ||
427 | +- Remote-shell like invocation. There must be a way to run a program | ||
428 | + on the host system from the build system, passing it properly quoted | ||
429 | + command-line arguments, setting environment variables, and | ||
430 | + inheriting the caller's standard input and output. | ||
431 | + | ||
432 | + | ||
433 | +Usage | ||
434 | + | ||
435 | +To use EGLIBC's cross-testing support, provide values for the | ||
436 | +following Make variables when you invoke 'make': | ||
437 | + | ||
438 | +- cross-test-wrapper | ||
439 | + | ||
440 | + This should be the name of the cross-testing wrapper command, along | ||
441 | + with any arguments. | ||
442 | + | ||
443 | +- cross-localedef | ||
444 | + | ||
445 | + This should be the name of a cross-capable localedef program, like | ||
446 | + that included in the EGLIBC 'localedef' module, along with any | ||
447 | + arguments needed. | ||
448 | + | ||
449 | +These are each explained in detail below. | ||
450 | + | ||
451 | + | ||
452 | +The Cross-Testing Wrapper | ||
453 | + | ||
454 | +To run test programs reliably, the stock GNU C library takes care to | ||
455 | +ensure that test programs use the newly compiled dynamic linker and | ||
456 | +shared libraries, and never the host system's installed libraries. To | ||
457 | +accomplish this, it runs the tests by explicitly invoking the dynamic | ||
458 | +linker from the build tree, passing it a list of build tree | ||
459 | +directories to search for shared libraries, followed by the name of | ||
460 | +the executable to run and its arguments. | ||
461 | + | ||
462 | +For example, where one might normally run a test program like this: | ||
463 | + | ||
464 | + $ ./tst-foo arg1 arg2 | ||
465 | + | ||
466 | +the GNU C library might run that program like this: | ||
467 | + | ||
468 | + $ $objdir/elf/ld-linux.so.3 --library-path $objdir \ | ||
469 | + ./tst-foo arg1 arg2 | ||
470 | + | ||
471 | +(where $objdir is the path to the top of the build tree, and the | ||
472 | +trailing backslash indicates a continuation of the command). In other | ||
473 | +words, each test program invocation is 'wrapped up' inside an explicit | ||
474 | +invocation of the dynamic linker, which must itself execute the test | ||
475 | +program, having loaded shared libraries from the appropriate | ||
476 | +directories. | ||
477 | + | ||
478 | +To support cross-testing, EGLIBC allows the developer to optionally | ||
479 | +set the 'cross-test-wrapper' Make variable to another wrapper command, | ||
480 | +to which it passes the entire dynamic linker invocation shown above as | ||
481 | +arguments. For example, if the developer supplies a wrapper of | ||
482 | +'my-wrapper hostname', then EGLIBC would run the test above as | ||
483 | +follows: | ||
484 | + | ||
485 | + $ my-wrapper hostname \ | ||
486 | + $objdir/elf/ld-linux.so.3 --library-path $objdir \ | ||
487 | + ./tst-foo arg1 arg2 | ||
488 | + | ||
489 | +The 'my-wrapper' command is responsible for executing the command | ||
490 | +given on the host system. | ||
491 | + | ||
492 | +Since tests are run in varying directories, the wrapper should either | ||
493 | +be in your command search path, or 'cross-test-wrapper' should give an | ||
494 | +absolute path for the wrapper. | ||
495 | + | ||
496 | +The wrapper must meet several requirements: | ||
497 | + | ||
498 | +- It must preserve the current directory. As explained above, the | ||
499 | + build directory tree must be visible on both the build and host | ||
500 | + systems, at the same path. The test wrapper must ensure that the | ||
501 | + current directory it inherits is also inherited by the dynamic | ||
502 | + linker (and thus the test program itself). | ||
503 | + | ||
504 | +- It must preserve environment variables' values. Many EGLIBC tests | ||
505 | + set environment variables for test runs; in native testing, it | ||
506 | + invokes programs like this: | ||
507 | + | ||
508 | + $ GCONV_PATH=$objdir/iconvdata \ | ||
509 | + $objdir/elf/ld-linux.so.3 --library-path $objdir \ | ||
510 | + ./tst-foo arg1 arg2 | ||
511 | + | ||
512 | + With the cross-testing wrapper, that invocation becomes: | ||
513 | + | ||
514 | + $ GCONV_PATH=$objdir/iconvdata \ | ||
515 | + my-wrapper hostname \ | ||
516 | + $objdir/elf/ld-linux.so.3 --library-path $objdir \ | ||
517 | + ./tst-foo arg1 arg2 | ||
518 | + | ||
519 | + Here, 'my-wrapper' must ensure that the value it sees for | ||
520 | + 'GCONV_PATH' will be seen by the dynamic linker, and thus 'tst-foo' | ||
521 | + itself. (The wrapper supplied with GLIBC simply preserves the | ||
522 | + values of *all* enviroment variables, with a fixed set of | ||
523 | + exceptions.) | ||
524 | + | ||
525 | + If your wrapper is a shell script, take care to correctly propagate | ||
526 | + environment variables whose values contain spaces and shell | ||
527 | + metacharacters. | ||
528 | + | ||
529 | +- It must pass the command's arguments, unmodified. The arguments | ||
530 | + seen by the test program should be exactly those seen by the wrapper | ||
531 | + (after whatever arguments are given to the wrapper itself). The | ||
532 | + EGLIBC test framework performs all needed shell word splitting and | ||
533 | + expansion (wildcard expansion, parameter substitution, and so on) | ||
534 | + before invoking the wrapper; further expansion may break the tests. | ||
535 | + | ||
536 | + | ||
537 | +The 'cross-test-ssh.sh' script | ||
538 | + | ||
539 | +If you want to use 'ssh' (or something sufficiently similar) to run | ||
540 | +test programs on your host system, EGLIBC includes a shell script, | ||
541 | +'scripts/cross-test-ssh.sh', which you can use as your wrapper | ||
542 | +command. This script takes care of setting the test command's current | ||
543 | +directory, propagating environment variable values, and carrying | ||
544 | +command-line arguments, all across an 'ssh' connection. You may even | ||
545 | +supply an alternative to 'ssh' on the command line, if needed. | ||
546 | + | ||
547 | +For more details, pass 'cross-test-ssh.sh' the '--help' option. | ||
548 | + | ||
549 | + | ||
550 | +The Cross-Compiling Locale Definition Command | ||
551 | + | ||
552 | +Some EGLIBC tests rely on locales generated especially for the test | ||
553 | +process. In a native configuration, these tests simply run the | ||
554 | +'localedef' command built by the normal EGLIBC build process, | ||
555 | +'locale/localedef', to process and install their locales. However, in | ||
556 | +a cross-compiling configuration, this 'localedef' is built for the | ||
557 | +host system, not the build system, and since it requires quite a bit | ||
558 | +of memory to run (we have seen it fail on systems with 64MiB of | ||
559 | +memory), it may not be practical to run it on the host system. | ||
560 | + | ||
561 | +If set, EGLIBC uses the 'cross-localedef' Make variable as the command | ||
562 | +to run on the build system to process and install locales. The | ||
563 | +localedef program built from the EGLIBC 'localedef' module is | ||
564 | +suitable. | ||
565 | + | ||
566 | +The value of 'cross-localedef' may also include command-line arguments | ||
567 | +to be passed to the program; if you are using EGLIBC's 'localedef', | ||
568 | +you may include endianness and 'uint32_t' alignment arguments here. | ||
569 | + | ||
570 | + | ||
571 | +Example | ||
572 | + | ||
573 | +In developing EGLIBC's cross-testing facility, we invoked 'make' with | ||
574 | +the following script: | ||
575 | + | ||
576 | + #!/bin/sh | ||
577 | + | ||
578 | + srcdir=... | ||
579 | + test_hostname=... | ||
580 | + localedefdir=... | ||
581 | + cross_gxx=...-g++ | ||
582 | + | ||
583 | + wrapper="$srcdir/scripts/cross-test-ssh.sh $test_hostname" | ||
584 | + localedef="$localedefdir/localedef --little-endian --uint32-align=4" | ||
585 | + | ||
586 | + make cross-test-wrapper="$wrapper" \ | ||
587 | + cross-localedef="$localedef" \ | ||
588 | + CXX="$cross_gxx" \ | ||
589 | + "$@" | ||
590 | + | ||
591 | + | ||
592 | +Other Cross-Testing Concerns | ||
593 | + | ||
594 | +Here are notes on some other issues which you may encounter in running | ||
595 | +the EGLIBC tests in a cross-compiling environment: | ||
596 | + | ||
597 | +- Some tests require a C++ cross-compiler; you should set the 'CXX' | ||
598 | + Make variable to the name of an appropriate cross-compiler. | ||
599 | + | ||
600 | +- Some tests require access to libstdc++.so.6 and libgcc_s.so.1; we | ||
601 | + simply place copies of these libraries in the top EGLIBC build | ||
602 | + directory. | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/etc/ld.so.conf b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/etc/ld.so.conf new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/etc/ld.so.conf | |||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/fix-tibetian-locales.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/fix-tibetian-locales.patch new file mode 100644 index 0000000..9ab9fdc --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/fix-tibetian-locales.patch | |||
@@ -0,0 +1,38 @@ | |||
1 | cross localedef fails to compile these locales because name_fmt field is empty | ||
2 | It is not acceptable for cross localedef and it errors out | ||
3 | |||
4 | LC_NAME: field `name_fmt' not defined | ||
5 | |||
6 | We therefore give a dummy string to the format, the real fix needs some native | ||
7 | tibetian person to define proper name_fmt | ||
8 | |||
9 | Upstream-Status: Pending | ||
10 | |||
11 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
12 | |||
13 | Index: git/localedata/locales/bo_CN | ||
14 | =================================================================== | ||
15 | --- git.orig/localedata/locales/bo_CN 2014-08-29 10:35:22.464070587 -0700 | ||
16 | +++ git/localedata/locales/bo_CN 2014-08-29 10:35:22.456070587 -0700 | ||
17 | @@ -146,7 +146,7 @@ | ||
18 | LC_NAME | ||
19 | % FIXME | ||
20 | |||
21 | -name_fmt "" | ||
22 | +name_fmt "FIXME" | ||
23 | % name_gen "FIXME" | ||
24 | % name_miss "FIXME" | ||
25 | % name_mr "FIXME" | ||
26 | Index: git/localedata/locales/bo_IN | ||
27 | =================================================================== | ||
28 | --- git.orig/localedata/locales/bo_IN 2014-08-29 10:35:22.464070587 -0700 | ||
29 | +++ git/localedata/locales/bo_IN 2014-08-29 10:35:22.456070587 -0700 | ||
30 | @@ -71,7 +71,7 @@ | ||
31 | |||
32 | LC_NAME | ||
33 | % FIXME | ||
34 | -name_fmt "" | ||
35 | +name_fmt "FIXME" | ||
36 | % name_gen "FIXME" | ||
37 | % name_miss "FIXME" | ||
38 | % name_mr "FIXME" | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/fix_am_rootsbindir.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/fix_am_rootsbindir.patch new file mode 100644 index 0000000..668e8bf --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/fix_am_rootsbindir.patch | |||
@@ -0,0 +1,29 @@ | |||
1 | sysdeps/gnu/configure.ac: handle correctly $libc_cv_rootsbindir | ||
2 | |||
3 | Upstream-Status:Pending | ||
4 | Signed-off-by: Matthieu Crapet <Matthieu.Crapet@ingenico.com> | ||
5 | |||
6 | Index: git/sysdeps/gnu/configure | ||
7 | =================================================================== | ||
8 | --- git.orig/sysdeps/gnu/configure 2014-08-27 07:24:38.572070587 +0000 | ||
9 | +++ git/sysdeps/gnu/configure 2014-08-27 07:24:41.308070587 +0000 | ||
10 | @@ -32,6 +32,6 @@ | ||
11 | else | ||
12 | libc_cv_localstatedir=$localstatedir | ||
13 | fi | ||
14 | - libc_cv_rootsbindir=/sbin | ||
15 | + test -n "$libc_cv_rootsbindir" || libc_cv_rootsbindir=/sbin | ||
16 | ;; | ||
17 | esac | ||
18 | Index: git/sysdeps/gnu/configure.ac | ||
19 | =================================================================== | ||
20 | --- git.orig/sysdeps/gnu/configure.ac 2014-08-27 07:24:38.572070587 +0000 | ||
21 | +++ git/sysdeps/gnu/configure.ac 2014-08-27 07:24:41.308070587 +0000 | ||
22 | @@ -21,6 +21,6 @@ | ||
23 | else | ||
24 | libc_cv_localstatedir=$localstatedir | ||
25 | fi | ||
26 | - libc_cv_rootsbindir=/sbin | ||
27 | + test -n "$libc_cv_rootsbindir" || libc_cv_rootsbindir=/sbin | ||
28 | ;; | ||
29 | esac | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/fsl-ppc-no-fsqrt.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/fsl-ppc-no-fsqrt.patch new file mode 100644 index 0000000..f88eaf4 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/fsl-ppc-no-fsqrt.patch | |||
@@ -0,0 +1,100 @@ | |||
1 | Create e5500 specific math_private.h and let it include when compiling for e5500/64bit core | ||
2 | We prefefine __CPU_HAS_FSQRT to 0 and then in general ppc64 math_private.h we check if its | ||
3 | already defined before redefining it. This way we can ensure that on e5500 builds it wont | ||
4 | emit fsqrt intructions | ||
5 | |||
6 | -Khem | ||
7 | |||
8 | Upstream-Status: Pending | ||
9 | |||
10 | Index: git/sysdeps/powerpc/fpu/math_private.h | ||
11 | =================================================================== | ||
12 | --- git.orig/sysdeps/powerpc/fpu/math_private.h 2014-08-29 10:31:30.224070587 -0700 | ||
13 | +++ git/sysdeps/powerpc/fpu/math_private.h 2014-08-29 10:31:30.212070587 -0700 | ||
14 | @@ -25,10 +25,12 @@ | ||
15 | #include <fenv_private.h> | ||
16 | #include_next <math_private.h> | ||
17 | |||
18 | -# if __WORDSIZE == 64 || defined _ARCH_PWR4 | ||
19 | -# define __CPU_HAS_FSQRT 1 | ||
20 | -# else | ||
21 | -# define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) | ||
22 | +# ifndef __CPU_HAS_FSQRT | ||
23 | +# if __WORDSIZE == 64 || defined _ARCH_PWR4 | ||
24 | +# define __CPU_HAS_FSQRT 1 | ||
25 | +# else | ||
26 | +# define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) | ||
27 | +# endif | ||
28 | # endif | ||
29 | |||
30 | extern double __slow_ieee754_sqrt (double); | ||
31 | Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/math_private.h | ||
32 | =================================================================== | ||
33 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
34 | +++ git/sysdeps/powerpc/powerpc64/e5500/fpu/math_private.h 2014-08-29 10:31:30.212070587 -0700 | ||
35 | @@ -0,0 +1,9 @@ | ||
36 | +#ifndef _E5500_MATH_PRIVATE_H_ | ||
37 | +#define _E5500_MATH_PRIVATE_H_ 1 | ||
38 | +/* E5500 core FPU does not implement | ||
39 | + fsqrt */ | ||
40 | + | ||
41 | +#define __CPU_HAS_FSQRT 0 | ||
42 | +#include_next <math_private.h> | ||
43 | + | ||
44 | +#endif /* _E5500_MATH_PRIVATE_H_ */ | ||
45 | Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/math_private.h | ||
46 | =================================================================== | ||
47 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
48 | +++ git/sysdeps/powerpc/powerpc64/e6500/fpu/math_private.h 2014-08-29 10:31:30.212070587 -0700 | ||
49 | @@ -0,0 +1,9 @@ | ||
50 | +#ifndef _E6500_MATH_PRIVATE_H_ | ||
51 | +#define _E6500_MATH_PRIVATE_H_ 1 | ||
52 | +/* E6500 core FPU does not implement | ||
53 | + fsqrt */ | ||
54 | + | ||
55 | +#define __CPU_HAS_FSQRT 0 | ||
56 | +#include_next <math_private.h> | ||
57 | + | ||
58 | +#endif /* _E6500_MATH_PRIVATE_H_ */ | ||
59 | Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/math_private.h | ||
60 | =================================================================== | ||
61 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
62 | +++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/math_private.h 2014-08-29 10:31:30.212070587 -0700 | ||
63 | @@ -0,0 +1,9 @@ | ||
64 | +#ifndef _E500MC_MATH_PRIVATE_H_ | ||
65 | +#define _E500MC_MATH_PRIVATE_H_ 1 | ||
66 | +/* E500MC core FPU does not implement | ||
67 | + fsqrt */ | ||
68 | + | ||
69 | +#define __CPU_HAS_FSQRT 0 | ||
70 | +#include_next <math_private.h> | ||
71 | + | ||
72 | +#endif /* _E500MC_MATH_PRIVATE_H_ */ | ||
73 | Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/math_private.h | ||
74 | =================================================================== | ||
75 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
76 | +++ git/sysdeps/powerpc/powerpc32/e5500/fpu/math_private.h 2014-08-29 10:31:30.216070587 -0700 | ||
77 | @@ -0,0 +1,9 @@ | ||
78 | +#ifndef _E5500_MATH_PRIVATE_H_ | ||
79 | +#define _E5500_MATH_PRIVATE_H_ 1 | ||
80 | +/* E5500 core FPU does not implement | ||
81 | + fsqrt */ | ||
82 | + | ||
83 | +#define __CPU_HAS_FSQRT 0 | ||
84 | +#include_next <math_private.h> | ||
85 | + | ||
86 | +#endif /* _E5500_MATH_PRIVATE_H_ */ | ||
87 | Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/math_private.h | ||
88 | =================================================================== | ||
89 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
90 | +++ git/sysdeps/powerpc/powerpc32/e6500/fpu/math_private.h 2014-08-29 10:31:30.216070587 -0700 | ||
91 | @@ -0,0 +1,9 @@ | ||
92 | +#ifndef _E6500_MATH_PRIVATE_H_ | ||
93 | +#define _E6500_MATH_PRIVATE_H_ 1 | ||
94 | +/* E6500 core FPU does not implement | ||
95 | + fsqrt */ | ||
96 | + | ||
97 | +#define __CPU_HAS_FSQRT 0 | ||
98 | +#include_next <math_private.h> | ||
99 | + | ||
100 | +#endif /* _E6500_MATH_PRIVATE_H_ */ | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/generate-supported.mk b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/generate-supported.mk new file mode 100644 index 0000000..d2a28c2 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/generate-supported.mk | |||
@@ -0,0 +1,11 @@ | |||
1 | #!/usr/bin/make | ||
2 | |||
3 | include $(IN) | ||
4 | |||
5 | all: | ||
6 | rm -f $(OUT) | ||
7 | touch $(OUT) | ||
8 | for locale in $(SUPPORTED-LOCALES); do \ | ||
9 | [ $$locale = true ] && continue; \ | ||
10 | echo $$locale | sed 's,/, ,' >> $(OUT); \ | ||
11 | done | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/glibc.fix_sqrt2.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/glibc.fix_sqrt2.patch new file mode 100644 index 0000000..f5ed1bf --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/glibc.fix_sqrt2.patch | |||
@@ -0,0 +1,1516 @@ | |||
1 | Signed-of-by: Edmar Wienskoski <edmar@freescale.com> | ||
2 | Upstream-Status: Pending | ||
3 | |||
4 | Index: git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c | ||
5 | =================================================================== | ||
6 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
7 | +++ git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 2014-08-29 10:34:07.768070587 -0700 | ||
8 | @@ -0,0 +1,134 @@ | ||
9 | +/* Double-precision floating point square root. | ||
10 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
11 | + This file is part of the GNU C Library. | ||
12 | + | ||
13 | + The GNU C Library is free software; you can redistribute it and/or | ||
14 | + modify it under the terms of the GNU Lesser General Public | ||
15 | + License as published by the Free Software Foundation; either | ||
16 | + version 2.1 of the License, or (at your option) any later version. | ||
17 | + | ||
18 | + The GNU C Library is distributed in the hope that it will be useful, | ||
19 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
21 | + Lesser General Public License for more details. | ||
22 | + | ||
23 | + You should have received a copy of the GNU Lesser General Public | ||
24 | + License along with the GNU C Library; if not, write to the Free | ||
25 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
26 | + 02111-1307 USA. */ | ||
27 | + | ||
28 | +#include <math.h> | ||
29 | +#include <math_private.h> | ||
30 | +#include <fenv_libc.h> | ||
31 | +#include <inttypes.h> | ||
32 | + | ||
33 | +#include <sysdep.h> | ||
34 | +#include <ldsodefs.h> | ||
35 | + | ||
36 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
37 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
38 | +static const float two108 = 3.245185536584267269e+32; | ||
39 | +static const float twom54 = 5.551115123125782702e-17; | ||
40 | +static const float half = 0.5; | ||
41 | + | ||
42 | +/* The method is based on the descriptions in: | ||
43 | + | ||
44 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
45 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
46 | + | ||
47 | + We find the actual square root and half of its reciprocal | ||
48 | + simultaneously. */ | ||
49 | + | ||
50 | +#ifdef __STDC__ | ||
51 | +double | ||
52 | +__ieee754_sqrt (double b) | ||
53 | +#else | ||
54 | +double | ||
55 | +__ieee754_sqrt (b) | ||
56 | + double b; | ||
57 | +#endif | ||
58 | +{ | ||
59 | + if (__builtin_expect (b > 0, 1)) | ||
60 | + { | ||
61 | + double y, g, h, d, r; | ||
62 | + ieee_double_shape_type u; | ||
63 | + | ||
64 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
65 | + { | ||
66 | + fenv_t fe; | ||
67 | + | ||
68 | + fe = fegetenv_register (); | ||
69 | + | ||
70 | + u.value = b; | ||
71 | + | ||
72 | + relax_fenv_state (); | ||
73 | + | ||
74 | + __asm__ ("frsqrte %[estimate], %[x]\n" | ||
75 | + : [estimate] "=f" (y) : [x] "f" (b)); | ||
76 | + | ||
77 | + /* Following Muller et al, page 168, equation 5.20. | ||
78 | + | ||
79 | + h goes to 1/(2*sqrt(b)) | ||
80 | + g goes to sqrt(b). | ||
81 | + | ||
82 | + We need three iterations to get within 1ulp. */ | ||
83 | + | ||
84 | + /* Indicate that these can be performed prior to the branch. GCC | ||
85 | + insists on sinking them below the branch, however; it seems like | ||
86 | + they'd be better before the branch so that we can cover any latency | ||
87 | + from storing the argument and loading its high word. Oh well. */ | ||
88 | + | ||
89 | + g = b * y; | ||
90 | + h = 0.5 * y; | ||
91 | + | ||
92 | + /* Handle small numbers by scaling. */ | ||
93 | + if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
94 | + return __ieee754_sqrt (b * two108) * twom54; | ||
95 | + | ||
96 | +#define FMADD(a_, c_, b_) \ | ||
97 | + ({ double __r; \ | ||
98 | + __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ | ||
99 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
100 | + __r;}) | ||
101 | +#define FNMSUB(a_, c_, b_) \ | ||
102 | + ({ double __r; \ | ||
103 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
104 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
105 | + __r;}) | ||
106 | + | ||
107 | + r = FNMSUB (g, h, half); | ||
108 | + g = FMADD (g, r, g); | ||
109 | + h = FMADD (h, r, h); | ||
110 | + | ||
111 | + r = FNMSUB (g, h, half); | ||
112 | + g = FMADD (g, r, g); | ||
113 | + h = FMADD (h, r, h); | ||
114 | + | ||
115 | + r = FNMSUB (g, h, half); | ||
116 | + g = FMADD (g, r, g); | ||
117 | + h = FMADD (h, r, h); | ||
118 | + | ||
119 | + /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ | ||
120 | + | ||
121 | + /* Final refinement. */ | ||
122 | + d = FNMSUB (g, g, b); | ||
123 | + | ||
124 | + fesetenv_register (fe); | ||
125 | + return FMADD (d, h, g); | ||
126 | + } | ||
127 | + } | ||
128 | + else if (b < 0) | ||
129 | + { | ||
130 | + /* For some reason, some PowerPC32 processors don't implement | ||
131 | + FE_INVALID_SQRT. */ | ||
132 | +#ifdef FE_INVALID_SQRT | ||
133 | + feraiseexcept (FE_INVALID_SQRT); | ||
134 | + | ||
135 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
136 | + if ((u.l & FE_INVALID) == 0) | ||
137 | +#endif | ||
138 | + feraiseexcept (FE_INVALID); | ||
139 | + b = a_nan.value; | ||
140 | + } | ||
141 | + return f_wash (b); | ||
142 | +} | ||
143 | Index: git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c | ||
144 | =================================================================== | ||
145 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
146 | +++ git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 2014-08-29 10:34:07.768070587 -0700 | ||
147 | @@ -0,0 +1,101 @@ | ||
148 | +/* Single-precision floating point square root. | ||
149 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
150 | + This file is part of the GNU C Library. | ||
151 | + | ||
152 | + The GNU C Library is free software; you can redistribute it and/or | ||
153 | + modify it under the terms of the GNU Lesser General Public | ||
154 | + License as published by the Free Software Foundation; either | ||
155 | + version 2.1 of the License, or (at your option) any later version. | ||
156 | + | ||
157 | + The GNU C Library is distributed in the hope that it will be useful, | ||
158 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
159 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
160 | + Lesser General Public License for more details. | ||
161 | + | ||
162 | + You should have received a copy of the GNU Lesser General Public | ||
163 | + License along with the GNU C Library; if not, write to the Free | ||
164 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
165 | + 02111-1307 USA. */ | ||
166 | + | ||
167 | +#include <math.h> | ||
168 | +#include <math_private.h> | ||
169 | +#include <fenv_libc.h> | ||
170 | +#include <inttypes.h> | ||
171 | + | ||
172 | +#include <sysdep.h> | ||
173 | +#include <ldsodefs.h> | ||
174 | + | ||
175 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
176 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
177 | +static const float threehalf = 1.5; | ||
178 | + | ||
179 | +/* The method is based on the descriptions in: | ||
180 | + | ||
181 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
182 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
183 | + | ||
184 | + We find the reciprocal square root and use that to compute the actual | ||
185 | + square root. */ | ||
186 | + | ||
187 | +#ifdef __STDC__ | ||
188 | +float | ||
189 | +__ieee754_sqrtf (float b) | ||
190 | +#else | ||
191 | +float | ||
192 | +__ieee754_sqrtf (b) | ||
193 | + float b; | ||
194 | +#endif | ||
195 | +{ | ||
196 | + if (__builtin_expect (b > 0, 1)) | ||
197 | + { | ||
198 | +#define FMSUB(a_, c_, b_) \ | ||
199 | + ({ double __r; \ | ||
200 | + __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ | ||
201 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
202 | + __r;}) | ||
203 | +#define FNMSUB(a_, c_, b_) \ | ||
204 | + ({ double __r; \ | ||
205 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
206 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
207 | + __r;}) | ||
208 | + | ||
209 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
210 | + { | ||
211 | + double y, x; | ||
212 | + fenv_t fe; | ||
213 | + | ||
214 | + fe = fegetenv_register (); | ||
215 | + | ||
216 | + relax_fenv_state (); | ||
217 | + | ||
218 | + /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ | ||
219 | + y = FMSUB (threehalf, b, b); | ||
220 | + | ||
221 | + /* Initial estimate. */ | ||
222 | + __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); | ||
223 | + | ||
224 | + /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ | ||
225 | + x = x * FNMSUB (y, x * x, threehalf); | ||
226 | + x = x * FNMSUB (y, x * x, threehalf); | ||
227 | + x = x * FNMSUB (y, x * x, threehalf); | ||
228 | + | ||
229 | + /* All done. */ | ||
230 | + fesetenv_register (fe); | ||
231 | + return x * b; | ||
232 | + } | ||
233 | + } | ||
234 | + else if (b < 0) | ||
235 | + { | ||
236 | + /* For some reason, some PowerPC32 processors don't implement | ||
237 | + FE_INVALID_SQRT. */ | ||
238 | +#ifdef FE_INVALID_SQRT | ||
239 | + feraiseexcept (FE_INVALID_SQRT); | ||
240 | + | ||
241 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
242 | + if ((u.l & FE_INVALID) == 0) | ||
243 | +#endif | ||
244 | + feraiseexcept (FE_INVALID); | ||
245 | + b = a_nan.value; | ||
246 | + } | ||
247 | + return f_washf (b); | ||
248 | +} | ||
249 | Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c | ||
250 | =================================================================== | ||
251 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
252 | +++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 2014-08-29 10:34:07.768070587 -0700 | ||
253 | @@ -0,0 +1,134 @@ | ||
254 | +/* Double-precision floating point square root. | ||
255 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
256 | + This file is part of the GNU C Library. | ||
257 | + | ||
258 | + The GNU C Library is free software; you can redistribute it and/or | ||
259 | + modify it under the terms of the GNU Lesser General Public | ||
260 | + License as published by the Free Software Foundation; either | ||
261 | + version 2.1 of the License, or (at your option) any later version. | ||
262 | + | ||
263 | + The GNU C Library is distributed in the hope that it will be useful, | ||
264 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
265 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
266 | + Lesser General Public License for more details. | ||
267 | + | ||
268 | + You should have received a copy of the GNU Lesser General Public | ||
269 | + License along with the GNU C Library; if not, write to the Free | ||
270 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
271 | + 02111-1307 USA. */ | ||
272 | + | ||
273 | +#include <math.h> | ||
274 | +#include <math_private.h> | ||
275 | +#include <fenv_libc.h> | ||
276 | +#include <inttypes.h> | ||
277 | + | ||
278 | +#include <sysdep.h> | ||
279 | +#include <ldsodefs.h> | ||
280 | + | ||
281 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
282 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
283 | +static const float two108 = 3.245185536584267269e+32; | ||
284 | +static const float twom54 = 5.551115123125782702e-17; | ||
285 | +static const float half = 0.5; | ||
286 | + | ||
287 | +/* The method is based on the descriptions in: | ||
288 | + | ||
289 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
290 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
291 | + | ||
292 | + We find the actual square root and half of its reciprocal | ||
293 | + simultaneously. */ | ||
294 | + | ||
295 | +#ifdef __STDC__ | ||
296 | +double | ||
297 | +__ieee754_sqrt (double b) | ||
298 | +#else | ||
299 | +double | ||
300 | +__ieee754_sqrt (b) | ||
301 | + double b; | ||
302 | +#endif | ||
303 | +{ | ||
304 | + if (__builtin_expect (b > 0, 1)) | ||
305 | + { | ||
306 | + double y, g, h, d, r; | ||
307 | + ieee_double_shape_type u; | ||
308 | + | ||
309 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
310 | + { | ||
311 | + fenv_t fe; | ||
312 | + | ||
313 | + fe = fegetenv_register (); | ||
314 | + | ||
315 | + u.value = b; | ||
316 | + | ||
317 | + relax_fenv_state (); | ||
318 | + | ||
319 | + __asm__ ("frsqrte %[estimate], %[x]\n" | ||
320 | + : [estimate] "=f" (y) : [x] "f" (b)); | ||
321 | + | ||
322 | + /* Following Muller et al, page 168, equation 5.20. | ||
323 | + | ||
324 | + h goes to 1/(2*sqrt(b)) | ||
325 | + g goes to sqrt(b). | ||
326 | + | ||
327 | + We need three iterations to get within 1ulp. */ | ||
328 | + | ||
329 | + /* Indicate that these can be performed prior to the branch. GCC | ||
330 | + insists on sinking them below the branch, however; it seems like | ||
331 | + they'd be better before the branch so that we can cover any latency | ||
332 | + from storing the argument and loading its high word. Oh well. */ | ||
333 | + | ||
334 | + g = b * y; | ||
335 | + h = 0.5 * y; | ||
336 | + | ||
337 | + /* Handle small numbers by scaling. */ | ||
338 | + if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
339 | + return __ieee754_sqrt (b * two108) * twom54; | ||
340 | + | ||
341 | +#define FMADD(a_, c_, b_) \ | ||
342 | + ({ double __r; \ | ||
343 | + __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ | ||
344 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
345 | + __r;}) | ||
346 | +#define FNMSUB(a_, c_, b_) \ | ||
347 | + ({ double __r; \ | ||
348 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
349 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
350 | + __r;}) | ||
351 | + | ||
352 | + r = FNMSUB (g, h, half); | ||
353 | + g = FMADD (g, r, g); | ||
354 | + h = FMADD (h, r, h); | ||
355 | + | ||
356 | + r = FNMSUB (g, h, half); | ||
357 | + g = FMADD (g, r, g); | ||
358 | + h = FMADD (h, r, h); | ||
359 | + | ||
360 | + r = FNMSUB (g, h, half); | ||
361 | + g = FMADD (g, r, g); | ||
362 | + h = FMADD (h, r, h); | ||
363 | + | ||
364 | + /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ | ||
365 | + | ||
366 | + /* Final refinement. */ | ||
367 | + d = FNMSUB (g, g, b); | ||
368 | + | ||
369 | + fesetenv_register (fe); | ||
370 | + return FMADD (d, h, g); | ||
371 | + } | ||
372 | + } | ||
373 | + else if (b < 0) | ||
374 | + { | ||
375 | + /* For some reason, some PowerPC32 processors don't implement | ||
376 | + FE_INVALID_SQRT. */ | ||
377 | +#ifdef FE_INVALID_SQRT | ||
378 | + feraiseexcept (FE_INVALID_SQRT); | ||
379 | + | ||
380 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
381 | + if ((u.l & FE_INVALID) == 0) | ||
382 | +#endif | ||
383 | + feraiseexcept (FE_INVALID); | ||
384 | + b = a_nan.value; | ||
385 | + } | ||
386 | + return f_wash (b); | ||
387 | +} | ||
388 | Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c | ||
389 | =================================================================== | ||
390 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
391 | +++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 2014-08-29 10:34:07.772070587 -0700 | ||
392 | @@ -0,0 +1,101 @@ | ||
393 | +/* Single-precision floating point square root. | ||
394 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
395 | + This file is part of the GNU C Library. | ||
396 | + | ||
397 | + The GNU C Library is free software; you can redistribute it and/or | ||
398 | + modify it under the terms of the GNU Lesser General Public | ||
399 | + License as published by the Free Software Foundation; either | ||
400 | + version 2.1 of the License, or (at your option) any later version. | ||
401 | + | ||
402 | + The GNU C Library is distributed in the hope that it will be useful, | ||
403 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
404 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
405 | + Lesser General Public License for more details. | ||
406 | + | ||
407 | + You should have received a copy of the GNU Lesser General Public | ||
408 | + License along with the GNU C Library; if not, write to the Free | ||
409 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
410 | + 02111-1307 USA. */ | ||
411 | + | ||
412 | +#include <math.h> | ||
413 | +#include <math_private.h> | ||
414 | +#include <fenv_libc.h> | ||
415 | +#include <inttypes.h> | ||
416 | + | ||
417 | +#include <sysdep.h> | ||
418 | +#include <ldsodefs.h> | ||
419 | + | ||
420 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
421 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
422 | +static const float threehalf = 1.5; | ||
423 | + | ||
424 | +/* The method is based on the descriptions in: | ||
425 | + | ||
426 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
427 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
428 | + | ||
429 | + We find the reciprocal square root and use that to compute the actual | ||
430 | + square root. */ | ||
431 | + | ||
432 | +#ifdef __STDC__ | ||
433 | +float | ||
434 | +__ieee754_sqrtf (float b) | ||
435 | +#else | ||
436 | +float | ||
437 | +__ieee754_sqrtf (b) | ||
438 | + float b; | ||
439 | +#endif | ||
440 | +{ | ||
441 | + if (__builtin_expect (b > 0, 1)) | ||
442 | + { | ||
443 | +#define FMSUB(a_, c_, b_) \ | ||
444 | + ({ double __r; \ | ||
445 | + __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ | ||
446 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
447 | + __r;}) | ||
448 | +#define FNMSUB(a_, c_, b_) \ | ||
449 | + ({ double __r; \ | ||
450 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
451 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
452 | + __r;}) | ||
453 | + | ||
454 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
455 | + { | ||
456 | + double y, x; | ||
457 | + fenv_t fe; | ||
458 | + | ||
459 | + fe = fegetenv_register (); | ||
460 | + | ||
461 | + relax_fenv_state (); | ||
462 | + | ||
463 | + /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ | ||
464 | + y = FMSUB (threehalf, b, b); | ||
465 | + | ||
466 | + /* Initial estimate. */ | ||
467 | + __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); | ||
468 | + | ||
469 | + /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ | ||
470 | + x = x * FNMSUB (y, x * x, threehalf); | ||
471 | + x = x * FNMSUB (y, x * x, threehalf); | ||
472 | + x = x * FNMSUB (y, x * x, threehalf); | ||
473 | + | ||
474 | + /* All done. */ | ||
475 | + fesetenv_register (fe); | ||
476 | + return x * b; | ||
477 | + } | ||
478 | + } | ||
479 | + else if (b < 0) | ||
480 | + { | ||
481 | + /* For some reason, some PowerPC32 processors don't implement | ||
482 | + FE_INVALID_SQRT. */ | ||
483 | +#ifdef FE_INVALID_SQRT | ||
484 | + feraiseexcept (FE_INVALID_SQRT); | ||
485 | + | ||
486 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
487 | + if ((u.l & FE_INVALID) == 0) | ||
488 | +#endif | ||
489 | + feraiseexcept (FE_INVALID); | ||
490 | + b = a_nan.value; | ||
491 | + } | ||
492 | + return f_washf (b); | ||
493 | +} | ||
494 | Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c | ||
495 | =================================================================== | ||
496 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
497 | +++ git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 2014-08-29 10:34:07.772070587 -0700 | ||
498 | @@ -0,0 +1,134 @@ | ||
499 | +/* Double-precision floating point square root. | ||
500 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
501 | + This file is part of the GNU C Library. | ||
502 | + | ||
503 | + The GNU C Library is free software; you can redistribute it and/or | ||
504 | + modify it under the terms of the GNU Lesser General Public | ||
505 | + License as published by the Free Software Foundation; either | ||
506 | + version 2.1 of the License, or (at your option) any later version. | ||
507 | + | ||
508 | + The GNU C Library is distributed in the hope that it will be useful, | ||
509 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
510 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
511 | + Lesser General Public License for more details. | ||
512 | + | ||
513 | + You should have received a copy of the GNU Lesser General Public | ||
514 | + License along with the GNU C Library; if not, write to the Free | ||
515 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
516 | + 02111-1307 USA. */ | ||
517 | + | ||
518 | +#include <math.h> | ||
519 | +#include <math_private.h> | ||
520 | +#include <fenv_libc.h> | ||
521 | +#include <inttypes.h> | ||
522 | + | ||
523 | +#include <sysdep.h> | ||
524 | +#include <ldsodefs.h> | ||
525 | + | ||
526 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
527 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
528 | +static const float two108 = 3.245185536584267269e+32; | ||
529 | +static const float twom54 = 5.551115123125782702e-17; | ||
530 | +static const float half = 0.5; | ||
531 | + | ||
532 | +/* The method is based on the descriptions in: | ||
533 | + | ||
534 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
535 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
536 | + | ||
537 | + We find the actual square root and half of its reciprocal | ||
538 | + simultaneously. */ | ||
539 | + | ||
540 | +#ifdef __STDC__ | ||
541 | +double | ||
542 | +__ieee754_sqrt (double b) | ||
543 | +#else | ||
544 | +double | ||
545 | +__ieee754_sqrt (b) | ||
546 | + double b; | ||
547 | +#endif | ||
548 | +{ | ||
549 | + if (__builtin_expect (b > 0, 1)) | ||
550 | + { | ||
551 | + double y, g, h, d, r; | ||
552 | + ieee_double_shape_type u; | ||
553 | + | ||
554 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
555 | + { | ||
556 | + fenv_t fe; | ||
557 | + | ||
558 | + fe = fegetenv_register (); | ||
559 | + | ||
560 | + u.value = b; | ||
561 | + | ||
562 | + relax_fenv_state (); | ||
563 | + | ||
564 | + __asm__ ("frsqrte %[estimate], %[x]\n" | ||
565 | + : [estimate] "=f" (y) : [x] "f" (b)); | ||
566 | + | ||
567 | + /* Following Muller et al, page 168, equation 5.20. | ||
568 | + | ||
569 | + h goes to 1/(2*sqrt(b)) | ||
570 | + g goes to sqrt(b). | ||
571 | + | ||
572 | + We need three iterations to get within 1ulp. */ | ||
573 | + | ||
574 | + /* Indicate that these can be performed prior to the branch. GCC | ||
575 | + insists on sinking them below the branch, however; it seems like | ||
576 | + they'd be better before the branch so that we can cover any latency | ||
577 | + from storing the argument and loading its high word. Oh well. */ | ||
578 | + | ||
579 | + g = b * y; | ||
580 | + h = 0.5 * y; | ||
581 | + | ||
582 | + /* Handle small numbers by scaling. */ | ||
583 | + if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
584 | + return __ieee754_sqrt (b * two108) * twom54; | ||
585 | + | ||
586 | +#define FMADD(a_, c_, b_) \ | ||
587 | + ({ double __r; \ | ||
588 | + __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ | ||
589 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
590 | + __r;}) | ||
591 | +#define FNMSUB(a_, c_, b_) \ | ||
592 | + ({ double __r; \ | ||
593 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
594 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
595 | + __r;}) | ||
596 | + | ||
597 | + r = FNMSUB (g, h, half); | ||
598 | + g = FMADD (g, r, g); | ||
599 | + h = FMADD (h, r, h); | ||
600 | + | ||
601 | + r = FNMSUB (g, h, half); | ||
602 | + g = FMADD (g, r, g); | ||
603 | + h = FMADD (h, r, h); | ||
604 | + | ||
605 | + r = FNMSUB (g, h, half); | ||
606 | + g = FMADD (g, r, g); | ||
607 | + h = FMADD (h, r, h); | ||
608 | + | ||
609 | + /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ | ||
610 | + | ||
611 | + /* Final refinement. */ | ||
612 | + d = FNMSUB (g, g, b); | ||
613 | + | ||
614 | + fesetenv_register (fe); | ||
615 | + return FMADD (d, h, g); | ||
616 | + } | ||
617 | + } | ||
618 | + else if (b < 0) | ||
619 | + { | ||
620 | + /* For some reason, some PowerPC32 processors don't implement | ||
621 | + FE_INVALID_SQRT. */ | ||
622 | +#ifdef FE_INVALID_SQRT | ||
623 | + feraiseexcept (FE_INVALID_SQRT); | ||
624 | + | ||
625 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
626 | + if ((u.l & FE_INVALID) == 0) | ||
627 | +#endif | ||
628 | + feraiseexcept (FE_INVALID); | ||
629 | + b = a_nan.value; | ||
630 | + } | ||
631 | + return f_wash (b); | ||
632 | +} | ||
633 | Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c | ||
634 | =================================================================== | ||
635 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
636 | +++ git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 2014-08-29 10:34:07.772070587 -0700 | ||
637 | @@ -0,0 +1,101 @@ | ||
638 | +/* Single-precision floating point square root. | ||
639 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
640 | + This file is part of the GNU C Library. | ||
641 | + | ||
642 | + The GNU C Library is free software; you can redistribute it and/or | ||
643 | + modify it under the terms of the GNU Lesser General Public | ||
644 | + License as published by the Free Software Foundation; either | ||
645 | + version 2.1 of the License, or (at your option) any later version. | ||
646 | + | ||
647 | + The GNU C Library is distributed in the hope that it will be useful, | ||
648 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
649 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
650 | + Lesser General Public License for more details. | ||
651 | + | ||
652 | + You should have received a copy of the GNU Lesser General Public | ||
653 | + License along with the GNU C Library; if not, write to the Free | ||
654 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
655 | + 02111-1307 USA. */ | ||
656 | + | ||
657 | +#include <math.h> | ||
658 | +#include <math_private.h> | ||
659 | +#include <fenv_libc.h> | ||
660 | +#include <inttypes.h> | ||
661 | + | ||
662 | +#include <sysdep.h> | ||
663 | +#include <ldsodefs.h> | ||
664 | + | ||
665 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
666 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
667 | +static const float threehalf = 1.5; | ||
668 | + | ||
669 | +/* The method is based on the descriptions in: | ||
670 | + | ||
671 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
672 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
673 | + | ||
674 | + We find the reciprocal square root and use that to compute the actual | ||
675 | + square root. */ | ||
676 | + | ||
677 | +#ifdef __STDC__ | ||
678 | +float | ||
679 | +__ieee754_sqrtf (float b) | ||
680 | +#else | ||
681 | +float | ||
682 | +__ieee754_sqrtf (b) | ||
683 | + float b; | ||
684 | +#endif | ||
685 | +{ | ||
686 | + if (__builtin_expect (b > 0, 1)) | ||
687 | + { | ||
688 | +#define FMSUB(a_, c_, b_) \ | ||
689 | + ({ double __r; \ | ||
690 | + __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ | ||
691 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
692 | + __r;}) | ||
693 | +#define FNMSUB(a_, c_, b_) \ | ||
694 | + ({ double __r; \ | ||
695 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
696 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
697 | + __r;}) | ||
698 | + | ||
699 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
700 | + { | ||
701 | + double y, x; | ||
702 | + fenv_t fe; | ||
703 | + | ||
704 | + fe = fegetenv_register (); | ||
705 | + | ||
706 | + relax_fenv_state (); | ||
707 | + | ||
708 | + /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ | ||
709 | + y = FMSUB (threehalf, b, b); | ||
710 | + | ||
711 | + /* Initial estimate. */ | ||
712 | + __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); | ||
713 | + | ||
714 | + /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ | ||
715 | + x = x * FNMSUB (y, x * x, threehalf); | ||
716 | + x = x * FNMSUB (y, x * x, threehalf); | ||
717 | + x = x * FNMSUB (y, x * x, threehalf); | ||
718 | + | ||
719 | + /* All done. */ | ||
720 | + fesetenv_register (fe); | ||
721 | + return x * b; | ||
722 | + } | ||
723 | + } | ||
724 | + else if (b < 0) | ||
725 | + { | ||
726 | + /* For some reason, some PowerPC32 processors don't implement | ||
727 | + FE_INVALID_SQRT. */ | ||
728 | +#ifdef FE_INVALID_SQRT | ||
729 | + feraiseexcept (FE_INVALID_SQRT); | ||
730 | + | ||
731 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
732 | + if ((u.l & FE_INVALID) == 0) | ||
733 | +#endif | ||
734 | + feraiseexcept (FE_INVALID); | ||
735 | + b = a_nan.value; | ||
736 | + } | ||
737 | + return f_washf (b); | ||
738 | +} | ||
739 | Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c | ||
740 | =================================================================== | ||
741 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
742 | +++ git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 2014-08-29 10:34:07.772070587 -0700 | ||
743 | @@ -0,0 +1,134 @@ | ||
744 | +/* Double-precision floating point square root. | ||
745 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
746 | + This file is part of the GNU C Library. | ||
747 | + | ||
748 | + The GNU C Library is free software; you can redistribute it and/or | ||
749 | + modify it under the terms of the GNU Lesser General Public | ||
750 | + License as published by the Free Software Foundation; either | ||
751 | + version 2.1 of the License, or (at your option) any later version. | ||
752 | + | ||
753 | + The GNU C Library is distributed in the hope that it will be useful, | ||
754 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
755 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
756 | + Lesser General Public License for more details. | ||
757 | + | ||
758 | + You should have received a copy of the GNU Lesser General Public | ||
759 | + License along with the GNU C Library; if not, write to the Free | ||
760 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
761 | + 02111-1307 USA. */ | ||
762 | + | ||
763 | +#include <math.h> | ||
764 | +#include <math_private.h> | ||
765 | +#include <fenv_libc.h> | ||
766 | +#include <inttypes.h> | ||
767 | + | ||
768 | +#include <sysdep.h> | ||
769 | +#include <ldsodefs.h> | ||
770 | + | ||
771 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
772 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
773 | +static const float two108 = 3.245185536584267269e+32; | ||
774 | +static const float twom54 = 5.551115123125782702e-17; | ||
775 | +static const float half = 0.5; | ||
776 | + | ||
777 | +/* The method is based on the descriptions in: | ||
778 | + | ||
779 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
780 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
781 | + | ||
782 | + We find the actual square root and half of its reciprocal | ||
783 | + simultaneously. */ | ||
784 | + | ||
785 | +#ifdef __STDC__ | ||
786 | +double | ||
787 | +__ieee754_sqrt (double b) | ||
788 | +#else | ||
789 | +double | ||
790 | +__ieee754_sqrt (b) | ||
791 | + double b; | ||
792 | +#endif | ||
793 | +{ | ||
794 | + if (__builtin_expect (b > 0, 1)) | ||
795 | + { | ||
796 | + double y, g, h, d, r; | ||
797 | + ieee_double_shape_type u; | ||
798 | + | ||
799 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
800 | + { | ||
801 | + fenv_t fe; | ||
802 | + | ||
803 | + fe = fegetenv_register (); | ||
804 | + | ||
805 | + u.value = b; | ||
806 | + | ||
807 | + relax_fenv_state (); | ||
808 | + | ||
809 | + __asm__ ("frsqrte %[estimate], %[x]\n" | ||
810 | + : [estimate] "=f" (y) : [x] "f" (b)); | ||
811 | + | ||
812 | + /* Following Muller et al, page 168, equation 5.20. | ||
813 | + | ||
814 | + h goes to 1/(2*sqrt(b)) | ||
815 | + g goes to sqrt(b). | ||
816 | + | ||
817 | + We need three iterations to get within 1ulp. */ | ||
818 | + | ||
819 | + /* Indicate that these can be performed prior to the branch. GCC | ||
820 | + insists on sinking them below the branch, however; it seems like | ||
821 | + they'd be better before the branch so that we can cover any latency | ||
822 | + from storing the argument and loading its high word. Oh well. */ | ||
823 | + | ||
824 | + g = b * y; | ||
825 | + h = 0.5 * y; | ||
826 | + | ||
827 | + /* Handle small numbers by scaling. */ | ||
828 | + if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
829 | + return __ieee754_sqrt (b * two108) * twom54; | ||
830 | + | ||
831 | +#define FMADD(a_, c_, b_) \ | ||
832 | + ({ double __r; \ | ||
833 | + __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ | ||
834 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
835 | + __r;}) | ||
836 | +#define FNMSUB(a_, c_, b_) \ | ||
837 | + ({ double __r; \ | ||
838 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
839 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
840 | + __r;}) | ||
841 | + | ||
842 | + r = FNMSUB (g, h, half); | ||
843 | + g = FMADD (g, r, g); | ||
844 | + h = FMADD (h, r, h); | ||
845 | + | ||
846 | + r = FNMSUB (g, h, half); | ||
847 | + g = FMADD (g, r, g); | ||
848 | + h = FMADD (h, r, h); | ||
849 | + | ||
850 | + r = FNMSUB (g, h, half); | ||
851 | + g = FMADD (g, r, g); | ||
852 | + h = FMADD (h, r, h); | ||
853 | + | ||
854 | + /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ | ||
855 | + | ||
856 | + /* Final refinement. */ | ||
857 | + d = FNMSUB (g, g, b); | ||
858 | + | ||
859 | + fesetenv_register (fe); | ||
860 | + return FMADD (d, h, g); | ||
861 | + } | ||
862 | + } | ||
863 | + else if (b < 0) | ||
864 | + { | ||
865 | + /* For some reason, some PowerPC32 processors don't implement | ||
866 | + FE_INVALID_SQRT. */ | ||
867 | +#ifdef FE_INVALID_SQRT | ||
868 | + feraiseexcept (FE_INVALID_SQRT); | ||
869 | + | ||
870 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
871 | + if ((u.l & FE_INVALID) == 0) | ||
872 | +#endif | ||
873 | + feraiseexcept (FE_INVALID); | ||
874 | + b = a_nan.value; | ||
875 | + } | ||
876 | + return f_wash (b); | ||
877 | +} | ||
878 | Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c | ||
879 | =================================================================== | ||
880 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
881 | +++ git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 2014-08-29 10:34:07.772070587 -0700 | ||
882 | @@ -0,0 +1,101 @@ | ||
883 | +/* Single-precision floating point square root. | ||
884 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
885 | + This file is part of the GNU C Library. | ||
886 | + | ||
887 | + The GNU C Library is free software; you can redistribute it and/or | ||
888 | + modify it under the terms of the GNU Lesser General Public | ||
889 | + License as published by the Free Software Foundation; either | ||
890 | + version 2.1 of the License, or (at your option) any later version. | ||
891 | + | ||
892 | + The GNU C Library is distributed in the hope that it will be useful, | ||
893 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
894 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
895 | + Lesser General Public License for more details. | ||
896 | + | ||
897 | + You should have received a copy of the GNU Lesser General Public | ||
898 | + License along with the GNU C Library; if not, write to the Free | ||
899 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
900 | + 02111-1307 USA. */ | ||
901 | + | ||
902 | +#include <math.h> | ||
903 | +#include <math_private.h> | ||
904 | +#include <fenv_libc.h> | ||
905 | +#include <inttypes.h> | ||
906 | + | ||
907 | +#include <sysdep.h> | ||
908 | +#include <ldsodefs.h> | ||
909 | + | ||
910 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
911 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
912 | +static const float threehalf = 1.5; | ||
913 | + | ||
914 | +/* The method is based on the descriptions in: | ||
915 | + | ||
916 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
917 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
918 | + | ||
919 | + We find the reciprocal square root and use that to compute the actual | ||
920 | + square root. */ | ||
921 | + | ||
922 | +#ifdef __STDC__ | ||
923 | +float | ||
924 | +__ieee754_sqrtf (float b) | ||
925 | +#else | ||
926 | +float | ||
927 | +__ieee754_sqrtf (b) | ||
928 | + float b; | ||
929 | +#endif | ||
930 | +{ | ||
931 | + if (__builtin_expect (b > 0, 1)) | ||
932 | + { | ||
933 | +#define FMSUB(a_, c_, b_) \ | ||
934 | + ({ double __r; \ | ||
935 | + __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ | ||
936 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
937 | + __r;}) | ||
938 | +#define FNMSUB(a_, c_, b_) \ | ||
939 | + ({ double __r; \ | ||
940 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
941 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
942 | + __r;}) | ||
943 | + | ||
944 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
945 | + { | ||
946 | + double y, x; | ||
947 | + fenv_t fe; | ||
948 | + | ||
949 | + fe = fegetenv_register (); | ||
950 | + | ||
951 | + relax_fenv_state (); | ||
952 | + | ||
953 | + /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ | ||
954 | + y = FMSUB (threehalf, b, b); | ||
955 | + | ||
956 | + /* Initial estimate. */ | ||
957 | + __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); | ||
958 | + | ||
959 | + /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ | ||
960 | + x = x * FNMSUB (y, x * x, threehalf); | ||
961 | + x = x * FNMSUB (y, x * x, threehalf); | ||
962 | + x = x * FNMSUB (y, x * x, threehalf); | ||
963 | + | ||
964 | + /* All done. */ | ||
965 | + fesetenv_register (fe); | ||
966 | + return x * b; | ||
967 | + } | ||
968 | + } | ||
969 | + else if (b < 0) | ||
970 | + { | ||
971 | + /* For some reason, some PowerPC32 processors don't implement | ||
972 | + FE_INVALID_SQRT. */ | ||
973 | +#ifdef FE_INVALID_SQRT | ||
974 | + feraiseexcept (FE_INVALID_SQRT); | ||
975 | + | ||
976 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
977 | + if ((u.l & FE_INVALID) == 0) | ||
978 | +#endif | ||
979 | + feraiseexcept (FE_INVALID); | ||
980 | + b = a_nan.value; | ||
981 | + } | ||
982 | + return f_washf (b); | ||
983 | +} | ||
984 | Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c | ||
985 | =================================================================== | ||
986 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
987 | +++ git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 2014-08-29 10:34:07.772070587 -0700 | ||
988 | @@ -0,0 +1,134 @@ | ||
989 | +/* Double-precision floating point square root. | ||
990 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
991 | + This file is part of the GNU C Library. | ||
992 | + | ||
993 | + The GNU C Library is free software; you can redistribute it and/or | ||
994 | + modify it under the terms of the GNU Lesser General Public | ||
995 | + License as published by the Free Software Foundation; either | ||
996 | + version 2.1 of the License, or (at your option) any later version. | ||
997 | + | ||
998 | + The GNU C Library is distributed in the hope that it will be useful, | ||
999 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1000 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1001 | + Lesser General Public License for more details. | ||
1002 | + | ||
1003 | + You should have received a copy of the GNU Lesser General Public | ||
1004 | + License along with the GNU C Library; if not, write to the Free | ||
1005 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
1006 | + 02111-1307 USA. */ | ||
1007 | + | ||
1008 | +#include <math.h> | ||
1009 | +#include <math_private.h> | ||
1010 | +#include <fenv_libc.h> | ||
1011 | +#include <inttypes.h> | ||
1012 | + | ||
1013 | +#include <sysdep.h> | ||
1014 | +#include <ldsodefs.h> | ||
1015 | + | ||
1016 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
1017 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
1018 | +static const float two108 = 3.245185536584267269e+32; | ||
1019 | +static const float twom54 = 5.551115123125782702e-17; | ||
1020 | +static const float half = 0.5; | ||
1021 | + | ||
1022 | +/* The method is based on the descriptions in: | ||
1023 | + | ||
1024 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
1025 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
1026 | + | ||
1027 | + We find the actual square root and half of its reciprocal | ||
1028 | + simultaneously. */ | ||
1029 | + | ||
1030 | +#ifdef __STDC__ | ||
1031 | +double | ||
1032 | +__ieee754_sqrt (double b) | ||
1033 | +#else | ||
1034 | +double | ||
1035 | +__ieee754_sqrt (b) | ||
1036 | + double b; | ||
1037 | +#endif | ||
1038 | +{ | ||
1039 | + if (__builtin_expect (b > 0, 1)) | ||
1040 | + { | ||
1041 | + double y, g, h, d, r; | ||
1042 | + ieee_double_shape_type u; | ||
1043 | + | ||
1044 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
1045 | + { | ||
1046 | + fenv_t fe; | ||
1047 | + | ||
1048 | + fe = fegetenv_register (); | ||
1049 | + | ||
1050 | + u.value = b; | ||
1051 | + | ||
1052 | + relax_fenv_state (); | ||
1053 | + | ||
1054 | + __asm__ ("frsqrte %[estimate], %[x]\n" | ||
1055 | + : [estimate] "=f" (y) : [x] "f" (b)); | ||
1056 | + | ||
1057 | + /* Following Muller et al, page 168, equation 5.20. | ||
1058 | + | ||
1059 | + h goes to 1/(2*sqrt(b)) | ||
1060 | + g goes to sqrt(b). | ||
1061 | + | ||
1062 | + We need three iterations to get within 1ulp. */ | ||
1063 | + | ||
1064 | + /* Indicate that these can be performed prior to the branch. GCC | ||
1065 | + insists on sinking them below the branch, however; it seems like | ||
1066 | + they'd be better before the branch so that we can cover any latency | ||
1067 | + from storing the argument and loading its high word. Oh well. */ | ||
1068 | + | ||
1069 | + g = b * y; | ||
1070 | + h = 0.5 * y; | ||
1071 | + | ||
1072 | + /* Handle small numbers by scaling. */ | ||
1073 | + if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
1074 | + return __ieee754_sqrt (b * two108) * twom54; | ||
1075 | + | ||
1076 | +#define FMADD(a_, c_, b_) \ | ||
1077 | + ({ double __r; \ | ||
1078 | + __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ | ||
1079 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
1080 | + __r;}) | ||
1081 | +#define FNMSUB(a_, c_, b_) \ | ||
1082 | + ({ double __r; \ | ||
1083 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
1084 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
1085 | + __r;}) | ||
1086 | + | ||
1087 | + r = FNMSUB (g, h, half); | ||
1088 | + g = FMADD (g, r, g); | ||
1089 | + h = FMADD (h, r, h); | ||
1090 | + | ||
1091 | + r = FNMSUB (g, h, half); | ||
1092 | + g = FMADD (g, r, g); | ||
1093 | + h = FMADD (h, r, h); | ||
1094 | + | ||
1095 | + r = FNMSUB (g, h, half); | ||
1096 | + g = FMADD (g, r, g); | ||
1097 | + h = FMADD (h, r, h); | ||
1098 | + | ||
1099 | + /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ | ||
1100 | + | ||
1101 | + /* Final refinement. */ | ||
1102 | + d = FNMSUB (g, g, b); | ||
1103 | + | ||
1104 | + fesetenv_register (fe); | ||
1105 | + return FMADD (d, h, g); | ||
1106 | + } | ||
1107 | + } | ||
1108 | + else if (b < 0) | ||
1109 | + { | ||
1110 | + /* For some reason, some PowerPC32 processors don't implement | ||
1111 | + FE_INVALID_SQRT. */ | ||
1112 | +#ifdef FE_INVALID_SQRT | ||
1113 | + feraiseexcept (FE_INVALID_SQRT); | ||
1114 | + | ||
1115 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
1116 | + if ((u.l & FE_INVALID) == 0) | ||
1117 | +#endif | ||
1118 | + feraiseexcept (FE_INVALID); | ||
1119 | + b = a_nan.value; | ||
1120 | + } | ||
1121 | + return f_wash (b); | ||
1122 | +} | ||
1123 | Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c | ||
1124 | =================================================================== | ||
1125 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1126 | +++ git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 2014-08-29 10:34:07.772070587 -0700 | ||
1127 | @@ -0,0 +1,101 @@ | ||
1128 | +/* Single-precision floating point square root. | ||
1129 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
1130 | + This file is part of the GNU C Library. | ||
1131 | + | ||
1132 | + The GNU C Library is free software; you can redistribute it and/or | ||
1133 | + modify it under the terms of the GNU Lesser General Public | ||
1134 | + License as published by the Free Software Foundation; either | ||
1135 | + version 2.1 of the License, or (at your option) any later version. | ||
1136 | + | ||
1137 | + The GNU C Library is distributed in the hope that it will be useful, | ||
1138 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1139 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1140 | + Lesser General Public License for more details. | ||
1141 | + | ||
1142 | + You should have received a copy of the GNU Lesser General Public | ||
1143 | + License along with the GNU C Library; if not, write to the Free | ||
1144 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
1145 | + 02111-1307 USA. */ | ||
1146 | + | ||
1147 | +#include <math.h> | ||
1148 | +#include <math_private.h> | ||
1149 | +#include <fenv_libc.h> | ||
1150 | +#include <inttypes.h> | ||
1151 | + | ||
1152 | +#include <sysdep.h> | ||
1153 | +#include <ldsodefs.h> | ||
1154 | + | ||
1155 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
1156 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
1157 | +static const float threehalf = 1.5; | ||
1158 | + | ||
1159 | +/* The method is based on the descriptions in: | ||
1160 | + | ||
1161 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
1162 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
1163 | + | ||
1164 | + We find the reciprocal square root and use that to compute the actual | ||
1165 | + square root. */ | ||
1166 | + | ||
1167 | +#ifdef __STDC__ | ||
1168 | +float | ||
1169 | +__ieee754_sqrtf (float b) | ||
1170 | +#else | ||
1171 | +float | ||
1172 | +__ieee754_sqrtf (b) | ||
1173 | + float b; | ||
1174 | +#endif | ||
1175 | +{ | ||
1176 | + if (__builtin_expect (b > 0, 1)) | ||
1177 | + { | ||
1178 | +#define FMSUB(a_, c_, b_) \ | ||
1179 | + ({ double __r; \ | ||
1180 | + __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ | ||
1181 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
1182 | + __r;}) | ||
1183 | +#define FNMSUB(a_, c_, b_) \ | ||
1184 | + ({ double __r; \ | ||
1185 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
1186 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
1187 | + __r;}) | ||
1188 | + | ||
1189 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
1190 | + { | ||
1191 | + double y, x; | ||
1192 | + fenv_t fe; | ||
1193 | + | ||
1194 | + fe = fegetenv_register (); | ||
1195 | + | ||
1196 | + relax_fenv_state (); | ||
1197 | + | ||
1198 | + /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ | ||
1199 | + y = FMSUB (threehalf, b, b); | ||
1200 | + | ||
1201 | + /* Initial estimate. */ | ||
1202 | + __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); | ||
1203 | + | ||
1204 | + /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ | ||
1205 | + x = x * FNMSUB (y, x * x, threehalf); | ||
1206 | + x = x * FNMSUB (y, x * x, threehalf); | ||
1207 | + x = x * FNMSUB (y, x * x, threehalf); | ||
1208 | + | ||
1209 | + /* All done. */ | ||
1210 | + fesetenv_register (fe); | ||
1211 | + return x * b; | ||
1212 | + } | ||
1213 | + } | ||
1214 | + else if (b < 0) | ||
1215 | + { | ||
1216 | + /* For some reason, some PowerPC32 processors don't implement | ||
1217 | + FE_INVALID_SQRT. */ | ||
1218 | +#ifdef FE_INVALID_SQRT | ||
1219 | + feraiseexcept (FE_INVALID_SQRT); | ||
1220 | + | ||
1221 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
1222 | + if ((u.l & FE_INVALID) == 0) | ||
1223 | +#endif | ||
1224 | + feraiseexcept (FE_INVALID); | ||
1225 | + b = a_nan.value; | ||
1226 | + } | ||
1227 | + return f_washf (b); | ||
1228 | +} | ||
1229 | Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c | ||
1230 | =================================================================== | ||
1231 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1232 | +++ git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 2014-08-29 10:34:07.772070587 -0700 | ||
1233 | @@ -0,0 +1,134 @@ | ||
1234 | +/* Double-precision floating point square root. | ||
1235 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
1236 | + This file is part of the GNU C Library. | ||
1237 | + | ||
1238 | + The GNU C Library is free software; you can redistribute it and/or | ||
1239 | + modify it under the terms of the GNU Lesser General Public | ||
1240 | + License as published by the Free Software Foundation; either | ||
1241 | + version 2.1 of the License, or (at your option) any later version. | ||
1242 | + | ||
1243 | + The GNU C Library is distributed in the hope that it will be useful, | ||
1244 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1245 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1246 | + Lesser General Public License for more details. | ||
1247 | + | ||
1248 | + You should have received a copy of the GNU Lesser General Public | ||
1249 | + License along with the GNU C Library; if not, write to the Free | ||
1250 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
1251 | + 02111-1307 USA. */ | ||
1252 | + | ||
1253 | +#include <math.h> | ||
1254 | +#include <math_private.h> | ||
1255 | +#include <fenv_libc.h> | ||
1256 | +#include <inttypes.h> | ||
1257 | + | ||
1258 | +#include <sysdep.h> | ||
1259 | +#include <ldsodefs.h> | ||
1260 | + | ||
1261 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
1262 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
1263 | +static const float two108 = 3.245185536584267269e+32; | ||
1264 | +static const float twom54 = 5.551115123125782702e-17; | ||
1265 | +static const float half = 0.5; | ||
1266 | + | ||
1267 | +/* The method is based on the descriptions in: | ||
1268 | + | ||
1269 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
1270 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
1271 | + | ||
1272 | + We find the actual square root and half of its reciprocal | ||
1273 | + simultaneously. */ | ||
1274 | + | ||
1275 | +#ifdef __STDC__ | ||
1276 | +double | ||
1277 | +__ieee754_sqrt (double b) | ||
1278 | +#else | ||
1279 | +double | ||
1280 | +__ieee754_sqrt (b) | ||
1281 | + double b; | ||
1282 | +#endif | ||
1283 | +{ | ||
1284 | + if (__builtin_expect (b > 0, 1)) | ||
1285 | + { | ||
1286 | + double y, g, h, d, r; | ||
1287 | + ieee_double_shape_type u; | ||
1288 | + | ||
1289 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
1290 | + { | ||
1291 | + fenv_t fe; | ||
1292 | + | ||
1293 | + fe = fegetenv_register (); | ||
1294 | + | ||
1295 | + u.value = b; | ||
1296 | + | ||
1297 | + relax_fenv_state (); | ||
1298 | + | ||
1299 | + __asm__ ("frsqrte %[estimate], %[x]\n" | ||
1300 | + : [estimate] "=f" (y) : [x] "f" (b)); | ||
1301 | + | ||
1302 | + /* Following Muller et al, page 168, equation 5.20. | ||
1303 | + | ||
1304 | + h goes to 1/(2*sqrt(b)) | ||
1305 | + g goes to sqrt(b). | ||
1306 | + | ||
1307 | + We need three iterations to get within 1ulp. */ | ||
1308 | + | ||
1309 | + /* Indicate that these can be performed prior to the branch. GCC | ||
1310 | + insists on sinking them below the branch, however; it seems like | ||
1311 | + they'd be better before the branch so that we can cover any latency | ||
1312 | + from storing the argument and loading its high word. Oh well. */ | ||
1313 | + | ||
1314 | + g = b * y; | ||
1315 | + h = 0.5 * y; | ||
1316 | + | ||
1317 | + /* Handle small numbers by scaling. */ | ||
1318 | + if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
1319 | + return __ieee754_sqrt (b * two108) * twom54; | ||
1320 | + | ||
1321 | +#define FMADD(a_, c_, b_) \ | ||
1322 | + ({ double __r; \ | ||
1323 | + __asm__ ("fmadd %[r], %[a], %[c], %[b]\n" \ | ||
1324 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
1325 | + __r;}) | ||
1326 | +#define FNMSUB(a_, c_, b_) \ | ||
1327 | + ({ double __r; \ | ||
1328 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
1329 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
1330 | + __r;}) | ||
1331 | + | ||
1332 | + r = FNMSUB (g, h, half); | ||
1333 | + g = FMADD (g, r, g); | ||
1334 | + h = FMADD (h, r, h); | ||
1335 | + | ||
1336 | + r = FNMSUB (g, h, half); | ||
1337 | + g = FMADD (g, r, g); | ||
1338 | + h = FMADD (h, r, h); | ||
1339 | + | ||
1340 | + r = FNMSUB (g, h, half); | ||
1341 | + g = FMADD (g, r, g); | ||
1342 | + h = FMADD (h, r, h); | ||
1343 | + | ||
1344 | + /* g is now +/- 1ulp, or exactly equal to, the square root of b. */ | ||
1345 | + | ||
1346 | + /* Final refinement. */ | ||
1347 | + d = FNMSUB (g, g, b); | ||
1348 | + | ||
1349 | + fesetenv_register (fe); | ||
1350 | + return FMADD (d, h, g); | ||
1351 | + } | ||
1352 | + } | ||
1353 | + else if (b < 0) | ||
1354 | + { | ||
1355 | + /* For some reason, some PowerPC32 processors don't implement | ||
1356 | + FE_INVALID_SQRT. */ | ||
1357 | +#ifdef FE_INVALID_SQRT | ||
1358 | + feraiseexcept (FE_INVALID_SQRT); | ||
1359 | + | ||
1360 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
1361 | + if ((u.l & FE_INVALID) == 0) | ||
1362 | +#endif | ||
1363 | + feraiseexcept (FE_INVALID); | ||
1364 | + b = a_nan.value; | ||
1365 | + } | ||
1366 | + return f_wash (b); | ||
1367 | +} | ||
1368 | Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c | ||
1369 | =================================================================== | ||
1370 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1371 | +++ git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 2014-08-29 10:34:07.776070587 -0700 | ||
1372 | @@ -0,0 +1,101 @@ | ||
1373 | +/* Single-precision floating point square root. | ||
1374 | + Copyright (C) 2010 Free Software Foundation, Inc. | ||
1375 | + This file is part of the GNU C Library. | ||
1376 | + | ||
1377 | + The GNU C Library is free software; you can redistribute it and/or | ||
1378 | + modify it under the terms of the GNU Lesser General Public | ||
1379 | + License as published by the Free Software Foundation; either | ||
1380 | + version 2.1 of the License, or (at your option) any later version. | ||
1381 | + | ||
1382 | + The GNU C Library is distributed in the hope that it will be useful, | ||
1383 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1384 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1385 | + Lesser General Public License for more details. | ||
1386 | + | ||
1387 | + You should have received a copy of the GNU Lesser General Public | ||
1388 | + License along with the GNU C Library; if not, write to the Free | ||
1389 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
1390 | + 02111-1307 USA. */ | ||
1391 | + | ||
1392 | +#include <math.h> | ||
1393 | +#include <math_private.h> | ||
1394 | +#include <fenv_libc.h> | ||
1395 | +#include <inttypes.h> | ||
1396 | + | ||
1397 | +#include <sysdep.h> | ||
1398 | +#include <ldsodefs.h> | ||
1399 | + | ||
1400 | +static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; | ||
1401 | +static const ieee_float_shape_type a_inf = {.word = 0x7f800000 }; | ||
1402 | +static const float threehalf = 1.5; | ||
1403 | + | ||
1404 | +/* The method is based on the descriptions in: | ||
1405 | + | ||
1406 | + _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5; | ||
1407 | + _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9 | ||
1408 | + | ||
1409 | + We find the reciprocal square root and use that to compute the actual | ||
1410 | + square root. */ | ||
1411 | + | ||
1412 | +#ifdef __STDC__ | ||
1413 | +float | ||
1414 | +__ieee754_sqrtf (float b) | ||
1415 | +#else | ||
1416 | +float | ||
1417 | +__ieee754_sqrtf (b) | ||
1418 | + float b; | ||
1419 | +#endif | ||
1420 | +{ | ||
1421 | + if (__builtin_expect (b > 0, 1)) | ||
1422 | + { | ||
1423 | +#define FMSUB(a_, c_, b_) \ | ||
1424 | + ({ double __r; \ | ||
1425 | + __asm__ ("fmsub %[r], %[a], %[c], %[b]\n" \ | ||
1426 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
1427 | + __r;}) | ||
1428 | +#define FNMSUB(a_, c_, b_) \ | ||
1429 | + ({ double __r; \ | ||
1430 | + __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n" \ | ||
1431 | + : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \ | ||
1432 | + __r;}) | ||
1433 | + | ||
1434 | + if (__builtin_expect (b != a_inf.value, 1)) | ||
1435 | + { | ||
1436 | + double y, x; | ||
1437 | + fenv_t fe; | ||
1438 | + | ||
1439 | + fe = fegetenv_register (); | ||
1440 | + | ||
1441 | + relax_fenv_state (); | ||
1442 | + | ||
1443 | + /* Compute y = 1.5 * b - b. Uses fewer constants than y = 0.5 * b. */ | ||
1444 | + y = FMSUB (threehalf, b, b); | ||
1445 | + | ||
1446 | + /* Initial estimate. */ | ||
1447 | + __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b)); | ||
1448 | + | ||
1449 | + /* Iterate. x_{n+1} = x_n * (1.5 - y * (x_n * x_n)). */ | ||
1450 | + x = x * FNMSUB (y, x * x, threehalf); | ||
1451 | + x = x * FNMSUB (y, x * x, threehalf); | ||
1452 | + x = x * FNMSUB (y, x * x, threehalf); | ||
1453 | + | ||
1454 | + /* All done. */ | ||
1455 | + fesetenv_register (fe); | ||
1456 | + return x * b; | ||
1457 | + } | ||
1458 | + } | ||
1459 | + else if (b < 0) | ||
1460 | + { | ||
1461 | + /* For some reason, some PowerPC32 processors don't implement | ||
1462 | + FE_INVALID_SQRT. */ | ||
1463 | +#ifdef FE_INVALID_SQRT | ||
1464 | + feraiseexcept (FE_INVALID_SQRT); | ||
1465 | + | ||
1466 | + fenv_union_t u = { .fenv = fegetenv_register () }; | ||
1467 | + if ((u.l & FE_INVALID) == 0) | ||
1468 | +#endif | ||
1469 | + feraiseexcept (FE_INVALID); | ||
1470 | + b = a_nan.value; | ||
1471 | + } | ||
1472 | + return f_washf (b); | ||
1473 | +} | ||
1474 | Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies | ||
1475 | =================================================================== | ||
1476 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1477 | +++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies 2014-08-29 10:34:07.776070587 -0700 | ||
1478 | @@ -0,0 +1 @@ | ||
1479 | +powerpc/powerpc32/603e/fpu | ||
1480 | Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e300c3/fpu/Implies | ||
1481 | =================================================================== | ||
1482 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1483 | +++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e300c3/fpu/Implies 2014-08-29 10:34:07.776070587 -0700 | ||
1484 | @@ -0,0 +1,2 @@ | ||
1485 | +# e300c3 is a variant of 603e so use the same optimizations for sqrt | ||
1486 | +powerpc/powerpc32/603e/fpu | ||
1487 | Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies | ||
1488 | =================================================================== | ||
1489 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1490 | +++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies 2014-08-29 10:34:07.776070587 -0700 | ||
1491 | @@ -0,0 +1 @@ | ||
1492 | +powerpc/powerpc32/e500mc/fpu | ||
1493 | Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies | ||
1494 | =================================================================== | ||
1495 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1496 | +++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies 2014-08-29 10:34:07.776070587 -0700 | ||
1497 | @@ -0,0 +1 @@ | ||
1498 | +powerpc/powerpc32/e5500/fpu | ||
1499 | Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies | ||
1500 | =================================================================== | ||
1501 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1502 | +++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies 2014-08-29 10:34:07.776070587 -0700 | ||
1503 | @@ -0,0 +1 @@ | ||
1504 | +powerpc/powerpc32/e6500/fpu | ||
1505 | Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies | ||
1506 | =================================================================== | ||
1507 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1508 | +++ git/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies 2014-08-29 10:34:07.780070587 -0700 | ||
1509 | @@ -0,0 +1 @@ | ||
1510 | +powerpc/powerpc64/e5500/fpu | ||
1511 | Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies | ||
1512 | =================================================================== | ||
1513 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1514 | +++ git/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies 2014-08-29 10:34:07.780070587 -0700 | ||
1515 | @@ -0,0 +1 @@ | ||
1516 | +powerpc/powerpc64/e6500/fpu | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/grok_gold.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/grok_gold.patch new file mode 100644 index 0000000..26875c7 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/grok_gold.patch | |||
@@ -0,0 +1,34 @@ | |||
1 | Make ld --version output matching grok gold's output | ||
2 | |||
3 | adapted from from upstream branch roland/gold-vs-libc | ||
4 | |||
5 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
6 | Upstream-Status: Backport | ||
7 | |||
8 | |||
9 | Index: git/configure | ||
10 | =================================================================== | ||
11 | --- git.orig/configure 2014-08-29 10:32:34.464070587 -0700 | ||
12 | +++ git/configure 2014-08-29 10:32:34.456070587 -0700 | ||
13 | @@ -4592,7 +4592,7 @@ | ||
14 | # Found it, now check the version. | ||
15 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5 | ||
16 | $as_echo_n "checking version of $LD... " >&6; } | ||
17 | - ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'` | ||
18 | + ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU [Bbinutilsd][^.]* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'` | ||
19 | case $ac_prog_version in | ||
20 | '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; | ||
21 | 2.1[0-9][0-9]*|2.[2-9][0-9]*|[3-9].*|[1-9][0-9]*) | ||
22 | Index: git/configure.ac | ||
23 | =================================================================== | ||
24 | --- git.orig/configure.ac 2014-08-29 10:32:34.464070587 -0700 | ||
25 | +++ git/configure.ac 2014-08-29 10:32:34.460070587 -0700 | ||
26 | @@ -930,7 +930,7 @@ | ||
27 | [GNU assembler.* \([0-9]*\.[0-9.]*\)], | ||
28 | [2.1[0-9][0-9]*|2.[2-9][0-9]*|[3-9].*|[1-9][0-9]*], AS=: critic_missing="$critic_missing as") | ||
29 | AC_CHECK_PROG_VER(LD, $LD, --version, | ||
30 | - [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)], | ||
31 | + [GNU [Bbinutilsd][^.]* \([0-9][0-9]*\.[0-9.]*\)], | ||
32 | [2.1[0-9][0-9]*|2.[2-9][0-9]*|[3-9].*|[1-9][0-9]*], LD=: critic_missing="$critic_missing ld") | ||
33 | |||
34 | # These programs are version sensitive. | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/initgroups_keys.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/initgroups_keys.patch new file mode 100644 index 0000000..32aa15a --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/initgroups_keys.patch | |||
@@ -0,0 +1,20 @@ | |||
1 | This is needed since initgroups belongs to NET group | ||
2 | so when NET is disabled in eglibc build then it reports | ||
3 | as undefined symbol | ||
4 | |||
5 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
6 | Upstream-Status: Pending | ||
7 | |||
8 | Index: git/nss/getent.c | ||
9 | =================================================================== | ||
10 | --- git.orig/nss/getent.c 2014-08-27 05:15:25.996070587 +0000 | ||
11 | +++ git/nss/getent.c 2014-08-27 05:16:00.048070587 +0000 | ||
12 | @@ -879,7 +879,7 @@ | ||
13 | D(group) | ||
14 | D(gshadow) | ||
15 | D(hosts) | ||
16 | -D(initgroups) | ||
17 | +DN(initgroups) | ||
18 | D(netgroup) | ||
19 | D(networks) | ||
20 | D(passwd) | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ld-search-order.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ld-search-order.patch new file mode 100644 index 0000000..f518bc7 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ld-search-order.patch | |||
@@ -0,0 +1,56 @@ | |||
1 | Upstream-Status: Inappropriate [embedded specific] | ||
2 | |||
3 | The default lib search path order is: | ||
4 | |||
5 | 1) LD_LIBRARY_PATH | ||
6 | 2) RPATH from the binary | ||
7 | 3) ld.so.cache | ||
8 | 4) default search paths embedded in the linker | ||
9 | |||
10 | For nativesdk binaries which are being used alongside binaries on a host system, we | ||
11 | need the search paths to firstly search the shipped nativesdk libs but then also | ||
12 | cover the host system. For example we want the host system's libGL and this may be | ||
13 | in a non-standard location like /usr/lib/mesa. The only place the location is know | ||
14 | about is in the ld.so.cache of the host system. | ||
15 | |||
16 | Since nativesdk has a simple structure and doesn't need to use a cache itself, we | ||
17 | repurpose the cache for use as a last resort in finding host system binaries. This | ||
18 | means we need to switch the order of 3 and 4 above to make this work effectively. | ||
19 | |||
20 | RP 14/10/2010 | ||
21 | |||
22 | Index: git/elf/dl-load.c | ||
23 | =================================================================== | ||
24 | --- git.orig/elf/dl-load.c 2014-08-28 17:32:46.292070587 -0700 | ||
25 | +++ git/elf/dl-load.c 2014-08-28 17:33:56.048070587 -0700 | ||
26 | @@ -2050,7 +2050,14 @@ | ||
27 | fd = open_path (name, namelen, mode, | ||
28 | &loader->l_runpath_dirs, &realname, &fb, loader, | ||
29 | LA_SER_RUNPATH, &found_other_class); | ||
30 | - | ||
31 | + /* try the default path. */ | ||
32 | + if (fd == -1 | ||
33 | + && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL | ||
34 | + || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1)) | ||
35 | + && rtld_search_dirs.dirs != (void *) -1) | ||
36 | + fd = open_path (name, namelen, mode & __RTLD_SECURE, &rtld_search_dirs, | ||
37 | + &realname, &fb, l, LA_SER_DEFAULT, &found_other_class); | ||
38 | + /* Finally try ld.so.cache */ | ||
39 | #ifdef USE_LDCONFIG | ||
40 | if (fd == -1 | ||
41 | && (__glibc_likely ((mode & __RTLD_SECURE) == 0) | ||
42 | @@ -2113,14 +2120,6 @@ | ||
43 | } | ||
44 | #endif | ||
45 | |||
46 | - /* Finally, try the default path. */ | ||
47 | - if (fd == -1 | ||
48 | - && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL | ||
49 | - || __glibc_likely (!(l->l_flags_1 & DF_1_NODEFLIB))) | ||
50 | - && rtld_search_dirs.dirs != (void *) -1) | ||
51 | - fd = open_path (name, namelen, mode, &rtld_search_dirs, | ||
52 | - &realname, &fb, l, LA_SER_DEFAULT, &found_other_class); | ||
53 | - | ||
54 | /* Add another newline when we are tracing the library loading. */ | ||
55 | if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)) | ||
56 | _dl_debug_printf ("\n"); | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/mips-rld-map-check.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/mips-rld-map-check.patch new file mode 100644 index 0000000..9f593d6 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/mips-rld-map-check.patch | |||
@@ -0,0 +1,27 @@ | |||
1 | |||
2 | On mips target, binutils currently sets DT_MIPS_RLD_MAP to 0 in dynamic | ||
3 | section if a --version-script sets _RLD_MAP to local. This is apparently | ||
4 | a binutils bug, but libc shouldn't segfault in this case. | ||
5 | |||
6 | see also: http://sourceware.org/bugilla/show_bug.cgi?id=11615 | ||
7 | |||
8 | Upstream-Status: Pending | ||
9 | |||
10 | 9/19/2010 - added by Qing He <qing.he@intel.com> | ||
11 | |||
12 | |||
13 | --- | ||
14 | Index: git/sysdeps/mips/dl-machine.h | ||
15 | =================================================================== | ||
16 | --- git.orig/sysdeps/mips/dl-machine.h 2014-08-27 04:58:11.840070587 +0000 | ||
17 | +++ git/sysdeps/mips/dl-machine.h 2014-08-27 04:58:11.832070587 +0000 | ||
18 | @@ -70,7 +70,8 @@ | ||
19 | /* If there is a DT_MIPS_RLD_MAP entry in the dynamic section, fill it in | ||
20 | with the run-time address of the r_debug structure */ | ||
21 | #define ELF_MACHINE_DEBUG_SETUP(l,r) \ | ||
22 | -do { if ((l)->l_info[DT_MIPS (RLD_MAP)]) \ | ||
23 | +do { if ((l)->l_info[DT_MIPS (RLD_MAP)] && \ | ||
24 | + (l)->l_info[DT_MIPS (RLD_MAP)]->d_un.d_ptr) \ | ||
25 | *(ElfW(Addr) *)((l)->l_info[DT_MIPS (RLD_MAP)]->d_un.d_ptr) = \ | ||
26 | (ElfW(Addr)) (r); \ | ||
27 | } while (0) | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/multilib_readlib.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/multilib_readlib.patch new file mode 100644 index 0000000..13ffc46 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/multilib_readlib.patch | |||
@@ -0,0 +1,19 @@ | |||
1 | Upstream-Status: Inappropriate [embedded specific] | ||
2 | |||
3 | Replace the OECORE_KNOWN_INTERPRETER_NAMES with the value of | ||
4 | variable EGLIBC_KNOWN_INTERPRETER_NAMES. | ||
5 | |||
6 | Lianhao Lu, 08/01/2011 | ||
7 | |||
8 | Index: git/elf/readlib.c | ||
9 | =================================================================== | ||
10 | --- git.orig/elf/readlib.c 2014-08-29 10:34:16.824070587 -0700 | ||
11 | +++ git/elf/readlib.c 2014-08-29 10:34:16.816070587 -0700 | ||
12 | @@ -51,6 +51,7 @@ | ||
13 | #ifdef SYSDEP_KNOWN_INTERPRETER_NAMES | ||
14 | SYSDEP_KNOWN_INTERPRETER_NAMES | ||
15 | #endif | ||
16 | + OECORE_KNOWN_INTERPRETER_NAMES | ||
17 | }; | ||
18 | |||
19 | static struct known_names known_libs[] = | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/option-groups.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/option-groups.patch new file mode 100644 index 0000000..693bd2f --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/option-groups.patch | |||
@@ -0,0 +1,1397 @@ | |||
1 | Eglibc option group infrastructure | ||
2 | |||
3 | Upstream-Status: Pending | ||
4 | |||
5 | Index: git/option-groups.def | ||
6 | =================================================================== | ||
7 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
8 | +++ git/option-groups.def 2014-08-27 07:26:51.652070587 +0000 | ||
9 | @@ -0,0 +1,868 @@ | ||
10 | +# This file documents the option groups EGLIBC currently supports, in | ||
11 | +# a format akin to the Linux Kconfig system's. The syntax may change | ||
12 | +# over time. | ||
13 | +# | ||
14 | +# An entry of the form: | ||
15 | +# | ||
16 | +# config GROUP_NAME | ||
17 | +# bool "one-line explanation of what this option group controls" | ||
18 | +# help | ||
19 | +# Multi-line help explaining the option group's meaning in | ||
20 | +# some detail, terminated by indentation level. | ||
21 | +# | ||
22 | +# defines an option group whose variable is GROUP_NAME, with | ||
23 | +# meaningful values 'y' (enabled) and 'n' (disabled). The | ||
24 | +# documentation is formatted to be consumed by some sort of | ||
25 | +# interactive configuration interface, but EGLIBC doesn't have such an | ||
26 | +# interface yet. | ||
27 | +# | ||
28 | +# An option may have a 'depends on' line, indicating which other options | ||
29 | +# must also be enabled if this option is. At present, EGLIBC doesn't | ||
30 | +# check that these dependencies are satisfied. | ||
31 | +# | ||
32 | +# Option group variables get their default values from the file | ||
33 | +# 'option-groups.defaults', in the top directory of the EGLIBC source | ||
34 | +# tree. By default, all EGLIBC option groups are enabled --- their | ||
35 | +# variables are set to 'y'. | ||
36 | +# | ||
37 | +# After including 'option-groups.defaults', the EGLIBC make machinery | ||
38 | +# includes the file 'option-groups.config' from the top of the build | ||
39 | +# tree, if it is present. Developers can place assignments to option | ||
40 | +# group variables in that file to override the defaults. For example, | ||
41 | +# to disable an option group, place a line of the form: | ||
42 | +# | ||
43 | +# OPTION_GROUP_NAME = n | ||
44 | +# | ||
45 | +# in 'option-groups.config' at the top of your build tree. To | ||
46 | +# explicitly enable an option group, you may also write: | ||
47 | +# | ||
48 | +# OPTION_GROUP_NAME = y | ||
49 | +# | ||
50 | +# although this simply reestablishes the value already set by | ||
51 | +# 'option-groups.defaults'. | ||
52 | + | ||
53 | +config EGLIBC_ADVANCED_INET6 | ||
54 | + bool "IPv6 Advanced Sockets API support (RFC3542)" | ||
55 | + depends on EGLIBC_INET | ||
56 | + help | ||
57 | + This option group includes the functions specified by RFC 3542, | ||
58 | + "Advanced Sockets Application Program Interface (API) for | ||
59 | + IPv6". | ||
60 | + | ||
61 | + This option group includes the following functions: | ||
62 | + | ||
63 | + inet6_opt_append | ||
64 | + inet6_opt_find | ||
65 | + inet6_opt_finish | ||
66 | + inet6_opt_get_val | ||
67 | + inet6_opt_init | ||
68 | + inet6_option_alloc | ||
69 | + inet6_option_append | ||
70 | + inet6_option_find | ||
71 | + inet6_option_init | ||
72 | + inet6_option_next | ||
73 | + inet6_option_space | ||
74 | + inet6_opt_next | ||
75 | + inet6_opt_set_val | ||
76 | + inet6_rth_add | ||
77 | + inet6_rth_getaddr | ||
78 | + inet6_rth_init | ||
79 | + inet6_rth_reverse | ||
80 | + inet6_rth_segments | ||
81 | + inet6_rth_space | ||
82 | + | ||
83 | +config EGLIBC_BACKTRACE | ||
84 | + bool "Functions for producing backtraces" | ||
85 | + help | ||
86 | + This option group includes functions for producing a list of | ||
87 | + the function calls that are currently active in a thread, from | ||
88 | + within the thread itself. These functions are often used | ||
89 | + within signal handlers, to produce diagnostic output. | ||
90 | + | ||
91 | + This option group includes the following functions: | ||
92 | + | ||
93 | + backtrace | ||
94 | + backtrace_symbols | ||
95 | + backtrace_symbols_fd | ||
96 | + | ||
97 | +config EGLIBC_BIG_MACROS | ||
98 | + bool "Use extensive inline code" | ||
99 | + help | ||
100 | + This option group specifies whether certain pieces of code | ||
101 | + should be inlined to achieve maximum speed. If this option | ||
102 | + group is not selected, function calls will be used instead, | ||
103 | + hence reducing the library footprint. | ||
104 | + | ||
105 | +config EGLIBC_BSD | ||
106 | + bool "BSD-specific functions, and their compatibility stubs" | ||
107 | + help | ||
108 | + This option group includes functions specific to BSD kernels. | ||
109 | + A number of these functions have stub versions that are also | ||
110 | + included in libraries built for non-BSD systems for | ||
111 | + compatibility. | ||
112 | + | ||
113 | + This option group includes the following functions: | ||
114 | + | ||
115 | + chflags | ||
116 | + fchflags | ||
117 | + lchmod | ||
118 | + revoke | ||
119 | + setlogin | ||
120 | + | ||
121 | +config EGLIBC_CXX_TESTS | ||
122 | + bool "Tests that link against the standard C++ library." | ||
123 | + depends on POSIX_WIDE_CHAR_DEVICE_IO && EGLIBC_LIBM | ||
124 | + help | ||
125 | + This option group does not include any C library functions; | ||
126 | + instead, it controls which EGLIBC tests an ordinary 'make | ||
127 | + tests' runs. With this group disabled, tests that would | ||
128 | + normally link against the standard C++ library are not | ||
129 | + run. | ||
130 | + | ||
131 | + The standard C++ library depends on the math library 'libm' and | ||
132 | + the wide character I/O functions included in EGLIBC. So those | ||
133 | + option groups must be enabled if this test is enabled. | ||
134 | + | ||
135 | +config EGLIBC_CATGETS | ||
136 | + bool "Functions for accessing message catalogs" | ||
137 | + depends on EGLIBC_LOCALE_CODE | ||
138 | + help | ||
139 | + This option group includes functions for accessing message | ||
140 | + catalogs: catopen, catclose, and catgets. | ||
141 | + | ||
142 | + This option group depends on the EGLIBC_LOCALE_CODE | ||
143 | + option group. | ||
144 | + | ||
145 | +config EGLIBC_CHARSETS | ||
146 | + bool "iconv/gconv character set conversion libraries" | ||
147 | + help | ||
148 | + This option group includes support for character sets other | ||
149 | + than ASCII (ANSI_X3.4-1968) and Unicode and ISO-10646 in their | ||
150 | + various encodings. This affects both the character sets | ||
151 | + supported by the wide and multibyte character functions, and | ||
152 | + those supported by the 'iconv' functions. | ||
153 | + | ||
154 | + With this option group disabled, EGLIBC supports only the | ||
155 | + following character sets: | ||
156 | + | ||
157 | + ANSI_X3.4 - ASCII | ||
158 | + ANSI_X3.4-1968 | ||
159 | + ANSI_X3.4-1986 | ||
160 | + ASCII | ||
161 | + CP367 | ||
162 | + CSASCII | ||
163 | + IBM367 | ||
164 | + ISO-IR-6 | ||
165 | + ISO646-US | ||
166 | + ISO_646.IRV:1991 | ||
167 | + OSF00010020 | ||
168 | + US | ||
169 | + US-ASCII | ||
170 | + | ||
171 | + 10646-1:1993 - ISO 10646, in big-endian UCS4 form | ||
172 | + 10646-1:1993/UCS4 | ||
173 | + CSUCS4 | ||
174 | + ISO-10646 | ||
175 | + ISO-10646/UCS4 | ||
176 | + OSF00010104 | ||
177 | + OSF00010105 | ||
178 | + OSF00010106 | ||
179 | + UCS-4 | ||
180 | + UCS-4BE | ||
181 | + UCS4 | ||
182 | + | ||
183 | + UCS-4LE - ISO 10646, in little-endian UCS4 form | ||
184 | + | ||
185 | + ISO-10646/UTF-8 - ISO 10646, in UTF-8 form | ||
186 | + ISO-10646/UTF8 | ||
187 | + ISO-IR-193 | ||
188 | + OSF05010001 | ||
189 | + UTF-8 | ||
190 | + UTF8 | ||
191 | + | ||
192 | + ISO-10646/UCS2 - ISO 10646, in target-endian UCS2 form | ||
193 | + OSF00010100 | ||
194 | + OSF00010101 | ||
195 | + OSF00010102 | ||
196 | + UCS-2 | ||
197 | + UCS2 | ||
198 | + | ||
199 | + UCS-2BE - ISO 10646, in big-endian UCS2 form | ||
200 | + UNICODEBIG | ||
201 | + | ||
202 | + UCS-2LE - ISO 10646, in little-endian UCS2 form | ||
203 | + UNICODELITTLE | ||
204 | + | ||
205 | + WCHAR_T - EGLIBC's internal form (target-endian, | ||
206 | + 32-bit ISO 10646) | ||
207 | + | ||
208 | +config EGLIBC_CRYPT | ||
209 | + bool "Encryption library" | ||
210 | + help | ||
211 | + This option group includes the `libcrypt' library which | ||
212 | + provides functions for one-way encryption. Supported | ||
213 | + encryption algorithms include MD5, SHA-256, SHA-512 and DES. | ||
214 | + | ||
215 | +config EGLIBC_CRYPT_UFC | ||
216 | + bool "Ultra fast `crypt' implementation" | ||
217 | + depends on EGLIBC_CRYPT | ||
218 | + help | ||
219 | + This option group provides ultra fast DES-based implementation of | ||
220 | + the `crypt' function. When this option group is disabled, | ||
221 | + (a) the library will not provide the setkey[_r] and encrypt[_r] | ||
222 | + functions and (b) the crypt[_r] function will return NULL and set the | ||
223 | + errno to ENOSYS if /salt/ passed does not correspond to either MD5, | ||
224 | + SHA-256 or SHA-512 algorithm. | ||
225 | + | ||
226 | +config EGLIBC_DB_ALIASES | ||
227 | + bool "Functions for accessing the mail aliases database" | ||
228 | + help | ||
229 | + This option group includues functions for looking up mail | ||
230 | + aliases in '/etc/aliases' or using nsswitch. It includes the | ||
231 | + following functions: | ||
232 | + | ||
233 | + endaliasent | ||
234 | + getaliasbyname | ||
235 | + getaliasbyname_r | ||
236 | + getaliasent | ||
237 | + getaliasent_r | ||
238 | + setaliasent | ||
239 | + | ||
240 | + When this option group is disabled, the NSS service libraries | ||
241 | + also lack support for querying their mail alias tables. | ||
242 | + | ||
243 | +config EGLIBC_ENVZ | ||
244 | + bool "Functions for handling envz-style environment vectors." | ||
245 | + help | ||
246 | + This option group contains functions for creating and operating | ||
247 | + on envz vectors. An "envz vector" is a vector of strings in a | ||
248 | + contiguous block of memory, where each element is a name-value | ||
249 | + pair, and elements are separated from their neighbors by null | ||
250 | + characters. | ||
251 | + | ||
252 | + This option group includes the following functions: | ||
253 | + | ||
254 | + envz_add envz_merge | ||
255 | + envz_entry envz_remove | ||
256 | + envz_get envz_strip | ||
257 | + | ||
258 | +config EGLIBC_FCVT | ||
259 | + bool "Functions for converting floating-point numbers to strings" | ||
260 | + help | ||
261 | + This option group includes functions for converting | ||
262 | + floating-point numbers to strings. | ||
263 | + | ||
264 | + This option group includes the following functions: | ||
265 | + | ||
266 | + ecvt qecvt | ||
267 | + ecvt_r qecvt_r | ||
268 | + fcvt qfcvt | ||
269 | + fcvt_r qfcvt_r | ||
270 | + gcvt qgcvt | ||
271 | + | ||
272 | +config EGLIBC_FMTMSG | ||
273 | + bool "Functions for formatting messages" | ||
274 | + help | ||
275 | + This option group includes the following functions: | ||
276 | + | ||
277 | + addseverity fmtmsg | ||
278 | + | ||
279 | +config EGLIBC_FSTAB | ||
280 | + bool "Access functions for 'fstab'" | ||
281 | + help | ||
282 | + This option group includes functions for reading the mount | ||
283 | + point specification table, '/etc/fstab'. These functions are | ||
284 | + not included in the POSIX standard, which provides the | ||
285 | + 'getmntent' family of functions instead. | ||
286 | + | ||
287 | + This option group includes the following functions: | ||
288 | + | ||
289 | + endfsent getfsspec | ||
290 | + getfsent setfsent | ||
291 | + getfsfile | ||
292 | + | ||
293 | +config EGLIBC_FTRAVERSE | ||
294 | + bool "Functions for traversing file hierarchies" | ||
295 | + help | ||
296 | + This option group includes functions for traversing file | ||
297 | + UNIX file hierachies. | ||
298 | + | ||
299 | + This option group includes the following functions: | ||
300 | + | ||
301 | + fts_open ftw | ||
302 | + fts_read nftw | ||
303 | + fts_children ftw64 | ||
304 | + fts_set nftw64 | ||
305 | + fts_close | ||
306 | + | ||
307 | +config EGLIBC_GETLOGIN | ||
308 | + bool "The getlogin function" | ||
309 | + depends on EGLIBC_UTMP | ||
310 | + help | ||
311 | + This function group includes the 'getlogin' and 'getlogin_r' | ||
312 | + functions, which return the user name associated by the login | ||
313 | + activity with the current process's controlling terminal. | ||
314 | + | ||
315 | + With this option group disabled, the 'glob' function will not | ||
316 | + fall back on 'getlogin' to find the user's login name for tilde | ||
317 | + expansion when the 'HOME' environment variable is not set. | ||
318 | + | ||
319 | +config EGLIBC_IDN | ||
320 | + bool "International domain names support" | ||
321 | + help | ||
322 | + This option group includes the `libcidn' library which | ||
323 | + provides support for international domain names. | ||
324 | + | ||
325 | +config EGLIBC_INET | ||
326 | + bool "Networking support" | ||
327 | + help | ||
328 | + This option group includes networking-specific functions and | ||
329 | + data. With EGLIBC_INET disabled, the EGLIBC | ||
330 | + installation and API changes as follows: | ||
331 | + | ||
332 | + - The following libraries are not installed: | ||
333 | + | ||
334 | + libnsl | ||
335 | + libnss_compat | ||
336 | + libnss_dns | ||
337 | + libnss_hesiod | ||
338 | + libnss_nis | ||
339 | + libnss_nisplus | ||
340 | + libresolv | ||
341 | + | ||
342 | + - The following functions and variables are omitted from libc: | ||
343 | + | ||
344 | + authdes_create hstrerror svc_fdset | ||
345 | + authdes_getucred htonl svc_getreq | ||
346 | + authdes_pk_create htons svc_getreq_common | ||
347 | + authnone_create if_freenameindex svc_getreq_poll | ||
348 | + authunix_create if_indextoname svc_getreqset | ||
349 | + authunix_create_default if_nameindex svc_max_pollfd | ||
350 | + bindresvport if_nametoindex svc_pollfd | ||
351 | + callrpc in6addr_any svcraw_create | ||
352 | + cbc_crypt in6addr_loopback svc_register | ||
353 | + clnt_broadcast inet6_opt_append svc_run | ||
354 | + clnt_create inet6_opt_find svc_sendreply | ||
355 | + clnt_pcreateerror inet6_opt_finish svctcp_create | ||
356 | + clnt_perrno inet6_opt_get_val svcudp_bufcreate | ||
357 | + clnt_perror inet6_opt_init svcudp_create | ||
358 | + clntraw_create inet6_option_alloc svcudp_enablecache | ||
359 | + clnt_spcreateerror inet6_option_append svcunix_create | ||
360 | + clnt_sperrno inet6_option_find svcunixfd_create | ||
361 | + clnt_sperror inet6_option_init svc_unregister | ||
362 | + clnttcp_create inet6_option_next user2netname | ||
363 | + clntudp_bufcreate inet6_option_space xdecrypt | ||
364 | + clntudp_create inet6_opt_next xdr_accepted_reply | ||
365 | + clntunix_create inet6_opt_set_val xdr_array | ||
366 | + des_setparity inet6_rth_add xdr_authdes_cred | ||
367 | + ecb_crypt inet6_rth_getaddr xdr_authdes_verf | ||
368 | + endaliasent inet6_rth_init xdr_authunix_parms | ||
369 | + endhostent inet6_rth_reverse xdr_bool | ||
370 | + endnetent inet6_rth_segments xdr_bytes | ||
371 | + endnetgrent inet6_rth_space xdr_callhdr | ||
372 | + endprotoent inet_addr xdr_callmsg | ||
373 | + endrpcent inet_aton xdr_char | ||
374 | + endservent inet_lnaof xdr_cryptkeyarg | ||
375 | + ether_aton inet_makeaddr xdr_cryptkeyarg2 | ||
376 | + ether_aton_r inet_netof xdr_cryptkeyres | ||
377 | + ether_hostton inet_network xdr_des_block | ||
378 | + ether_line inet_nsap_addr xdr_double | ||
379 | + ether_ntoa inet_nsap_ntoa xdr_enum | ||
380 | + ether_ntoa_r inet_ntoa xdr_float | ||
381 | + ether_ntohost inet_ntop xdr_free | ||
382 | + freeaddrinfo inet_pton xdr_getcredres | ||
383 | + freeifaddrs innetgr xdr_hyper | ||
384 | + gai_strerror iruserok xdr_int | ||
385 | + getaddrinfo iruserok_af xdr_int16_t | ||
386 | + getaliasbyname key_decryptsession xdr_int32_t | ||
387 | + getaliasbyname_r key_decryptsession_pk xdr_int64_t | ||
388 | + getaliasent key_encryptsession xdr_int8_t | ||
389 | + getaliasent_r key_encryptsession_pk xdr_keybuf | ||
390 | + gethostbyaddr key_gendes xdr_key_netstarg | ||
391 | + gethostbyaddr_r key_get_conv xdr_key_netstres | ||
392 | + gethostbyname key_secretkey_is_set xdr_keystatus | ||
393 | + gethostbyname2 key_setnet xdr_long | ||
394 | + gethostbyname2_r key_setsecret xdr_longlong_t | ||
395 | + gethostbyname_r netname2host xdrmem_create | ||
396 | + gethostent netname2user xdr_netnamestr | ||
397 | + gethostent_r ntohl xdr_netobj | ||
398 | + getifaddrs ntohs xdr_opaque | ||
399 | + getipv4sourcefilter passwd2des xdr_opaque_auth | ||
400 | + get_myaddress pmap_getmaps xdr_pmap | ||
401 | + getnameinfo pmap_getport xdr_pmaplist | ||
402 | + getnetbyaddr pmap_rmtcall xdr_pointer | ||
403 | + getnetbyaddr_r pmap_set xdr_quad_t | ||
404 | + getnetbyname pmap_unset xdrrec_create | ||
405 | + getnetbyname_r rcmd xdrrec_endofrecord | ||
406 | + getnetent rcmd_af xdrrec_eof | ||
407 | + getnetent_r registerrpc xdrrec_skiprecord | ||
408 | + getnetgrent res_init xdr_reference | ||
409 | + getnetgrent_r rexec xdr_rejected_reply | ||
410 | + getnetname rexec_af xdr_replymsg | ||
411 | + getprotobyname rexecoptions xdr_rmtcall_args | ||
412 | + getprotobyname_r rpc_createerr xdr_rmtcallres | ||
413 | + getprotobynumber rresvport xdr_short | ||
414 | + getprotobynumber_r rresvport_af xdr_sizeof | ||
415 | + getprotoent rtime xdrstdio_create | ||
416 | + getprotoent_r ruserok xdr_string | ||
417 | + getpublickey ruserok_af xdr_u_char | ||
418 | + getrpcbyname ruserpass xdr_u_hyper | ||
419 | + getrpcbyname_r setaliasent xdr_u_int | ||
420 | + getrpcbynumber sethostent xdr_uint16_t | ||
421 | + getrpcbynumber_r setipv4sourcefilter xdr_uint32_t | ||
422 | + getrpcent setnetent xdr_uint64_t | ||
423 | + getrpcent_r setnetgrent xdr_uint8_t | ||
424 | + getrpcport setprotoent xdr_u_long | ||
425 | + getsecretkey setrpcent xdr_u_longlong_t | ||
426 | + getservbyname setservent xdr_union | ||
427 | + getservbyname_r setsourcefilter xdr_unixcred | ||
428 | + getservbyport svcauthdes_stats xdr_u_quad_t | ||
429 | + getservbyport_r svcerr_auth xdr_u_short | ||
430 | + getservent svcerr_decode xdr_vector | ||
431 | + getservent_r svcerr_noproc xdr_void | ||
432 | + getsourcefilter svcerr_noprog xdr_wrapstring | ||
433 | + h_errlist svcerr_progvers xencrypt | ||
434 | + h_errno svcerr_systemerr xprt_register | ||
435 | + herror svcerr_weakauth xprt_unregister | ||
436 | + h_nerr svc_exit | ||
437 | + host2netname svcfd_create | ||
438 | + | ||
439 | + - The rpcgen, nscd, and rpcinfo commands are not installed. | ||
440 | + | ||
441 | + - The 'rpc' file (a text file listing RPC services) is not installed. | ||
442 | + | ||
443 | + Socket-related system calls do not fall in this option group, | ||
444 | + because many are also used for other inter-process | ||
445 | + communication mechanisms. For example, the 'syslog' routines | ||
446 | + use Unix-domain sockets to communicate with the syslog daemon; | ||
447 | + syslog is valuable in non-networked contexts. | ||
448 | + | ||
449 | +config EGLIBC_INET_ANL | ||
450 | + bool "Asynchronous name lookup" | ||
451 | + depends on EGLIBC_INET | ||
452 | + help | ||
453 | + This option group includes the `libanl' library which | ||
454 | + provides support for asynchronous name lookup. | ||
455 | + | ||
456 | +config EGLIBC_LIBM | ||
457 | + bool "libm (math library)" | ||
458 | + help | ||
459 | + This option group includes the 'libm' library, containing | ||
460 | + mathematical functions. If this option group is omitted, then | ||
461 | + an EGLIBC installation does not include shared or unshared versions | ||
462 | + of the math library. | ||
463 | + | ||
464 | + Note that this does not remove all floating-point related | ||
465 | + functionality from EGLIBC; for example, 'printf' and 'scanf' | ||
466 | + can still print and read floating-point values with this option | ||
467 | + group disabled. | ||
468 | + | ||
469 | + Note that the ISO Standard C++ library 'libstdc++' depends on | ||
470 | + EGLIBC's math library 'libm'. If you disable this option | ||
471 | + group, you will not be able to build 'libstdc++' against the | ||
472 | + resulting EGLIBC installation. | ||
473 | + | ||
474 | +config EGLIBC_LOCALES | ||
475 | + bool "Locale definitions" | ||
476 | + help | ||
477 | + This option group includes all locale definitions other than | ||
478 | + that for the "C" locale. If this option group is omitted, then | ||
479 | + only the "C" locale is supported. | ||
480 | + | ||
481 | + | ||
482 | +config EGLIBC_LOCALE_CODE | ||
483 | + bool "Locale functions" | ||
484 | + depends on POSIX_C_LANG_WIDE_CHAR | ||
485 | + help | ||
486 | + This option group includes locale support functions, programs, | ||
487 | + and libraries. With EGLIBC_LOCALE_CODE disabled, | ||
488 | + EGLIBC supports only the 'C' locale (also known as 'POSIX'), | ||
489 | + and ignores the settings of the 'LANG' and 'LC_*' environment | ||
490 | + variables. | ||
491 | + | ||
492 | + With EGLIBC_LOCALE_CODE disabled, the following | ||
493 | + functions are omitted from libc: | ||
494 | + | ||
495 | + duplocale localeconv nl_langinfo rpmatch strfmon_l | ||
496 | + freelocale newlocale nl_langinfo_l strfmon uselocale | ||
497 | + | ||
498 | + Furthermore, only the LC_CTYPE and LC_TIME categories of the | ||
499 | + standard "C" locale are available. | ||
500 | + | ||
501 | + The EGLIBC_CATGETS option group depends on this option group. | ||
502 | + | ||
503 | + | ||
504 | +config EGLIBC_MEMUSAGE | ||
505 | + bool "Memory profiling library" | ||
506 | + help | ||
507 | + This option group includes the `libmemusage' library and | ||
508 | + the `memusage' and `memusagestat' utilities. | ||
509 | + These components provide memory profiling functions. | ||
510 | + | ||
511 | +config EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE | ||
512 | + int "Memory profiling library buffer size" | ||
513 | + depends on EGLIBC_MEMUSAGE | ||
514 | + default "32768" | ||
515 | + help | ||
516 | + Libmemusage library buffers the profiling data in memory | ||
517 | + before writing it out to disk. By default, the library | ||
518 | + allocates 1.5M buffer, which can be substantial for some | ||
519 | + systems. EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE option | ||
520 | + allows to change the default buffer size. It specifies | ||
521 | + the number of entries the buffer should have. | ||
522 | + On most architectures one buffer entry amounts to 48 bytes, | ||
523 | + so setting this option to the value of 512 will reduce the size of | ||
524 | + the memory buffer to 24K. | ||
525 | + | ||
526 | +config EGLIBC_NIS | ||
527 | + bool "Support for NIS, NIS+, and the special 'compat' services." | ||
528 | + depends on EGLIBC_INET && EGLIBC_SUNRPC | ||
529 | + help | ||
530 | + This option group includes the NIS, NIS+, and 'compat' Name | ||
531 | + Service Switch service libraries. When it is disabled, those | ||
532 | + services libraries are not installed; you should remove any | ||
533 | + references to them from your 'nsswitch.conf' file. | ||
534 | + | ||
535 | + This option group depends on the EGLIBC_INET option | ||
536 | + group; you must enable that to enable this option group. | ||
537 | + | ||
538 | +config EGLIBC_NSSWITCH | ||
539 | + bool "Name service switch (nsswitch) support" | ||
540 | + help | ||
541 | + This option group includes support for the 'nsswitch' facility. | ||
542 | + With this option group enabled, all EGLIBC functions for | ||
543 | + accessing various system databases (passwords and groups; | ||
544 | + networking; aliases; public keys; and so on) consult the | ||
545 | + '/etc/nsswitch.conf' configuration file to decide how to handle | ||
546 | + queries. | ||
547 | + | ||
548 | + With this option group disabled, EGLIBC uses a fixed list of | ||
549 | + services to satisfy queries on each database, as requested by | ||
550 | + configuration files specified when EGLIBC is built. Your | ||
551 | + 'option-groups.config' file must set the following two | ||
552 | + variables: | ||
553 | + | ||
554 | +config EGLIBC_NSSWITCH_FIXED_CONFIG | ||
555 | + string "Nsswitch fixed config filename" | ||
556 | + depends on !EGLIBC_NSSWITCH | ||
557 | + default "" | ||
558 | + help | ||
559 | + Set this to the name of a file whose contents observe the | ||
560 | + same syntax as an ordinary '/etc/nsswitch.conf' file. The | ||
561 | + EGLIBC build process parses this file just as EGLIBC would | ||
562 | + at run time if EGLIBC_NSSWITCH were enabled, and | ||
563 | + produces a C library that uses the nsswitch service | ||
564 | + libraries to search for database entries as this file | ||
565 | + specifies, instead of consulting '/etc/nsswitch.conf' at run | ||
566 | + time. | ||
567 | + | ||
568 | + This should be an absolute filename. The EGLIBC build | ||
569 | + process may use it from several different working | ||
570 | + directories. It may include references to Makefile | ||
571 | + variables like 'common-objpfx' (the top of the build tree, | ||
572 | + with a trailing slash), or '..' (the top of the source tree, | ||
573 | + with a trailing slash). | ||
574 | + | ||
575 | + The EGLIBC source tree includes a sample configuration file | ||
576 | + named 'nss/fixed-nsswitch.conf'; for simple configurations, | ||
577 | + you will probably want to delete references to databases not | ||
578 | + needed on your system. | ||
579 | + | ||
580 | +config EGLIBC_NSSWITCH_FIXED_FUNCTIONS | ||
581 | + string "Nsswitch fixed functions filename" | ||
582 | + depends on !EGLIBC_NSSWITCH | ||
583 | + default "" | ||
584 | + help | ||
585 | + The EGLIBC build process uses this file to decide which | ||
586 | + functions to make available from which service libraries. | ||
587 | + The file 'nss/fixed-nsswitch.functions' serves as a sample | ||
588 | + configuration file for this setting, and explains its syntax | ||
589 | + and meaning in more detail. | ||
590 | + | ||
591 | + This should be an absolute file name. The EGLIBC build | ||
592 | + process may use it from several different working | ||
593 | + directories. It may include references to Makefile | ||
594 | + variables like 'common-objpfx' (the top of the build tree, | ||
595 | + with a trailing slash), or '..' (the top of the source tree, | ||
596 | + with a trailing slash). | ||
597 | + | ||
598 | + Be sure to mention each function in each service you wish to | ||
599 | + use. If you do not mention a service's function here, the | ||
600 | + EGLIBC database access functions will not find it, even if | ||
601 | + it is listed in the EGLIBC_NSSWITCH_FIXED_CONFIG | ||
602 | + file. | ||
603 | + | ||
604 | + In this arrangement, EGLIBC will not use the 'dlopen' and | ||
605 | + 'dlsym' functions to find database access functions. Instead, | ||
606 | + libc hard-codes references to the service libraries' database | ||
607 | + access functions. You must explicitly link your program | ||
608 | + against the name service libraries (those whose names start | ||
609 | + with 'libnss_', in the sysroot's '/lib' directory) whose | ||
610 | + functions you intend to use. This arrangement helps | ||
611 | + system-wide static analysis tools decide which functions a | ||
612 | + system actually uses. | ||
613 | + | ||
614 | + Note that some nsswitch service libraries require other option | ||
615 | + groups to be enabled; for example, the EGLIBC_INET | ||
616 | + option group must be enabled to use the 'libnss_dns.so.2' | ||
617 | + service library, which uses the Domain Name System network | ||
618 | + protocol to answer queries. | ||
619 | + | ||
620 | +config EGLIBC_RCMD | ||
621 | + bool "Support for 'rcmd' and related library functions" | ||
622 | + depends on EGLIBC_INET | ||
623 | + help | ||
624 | + This option group includes functions for running commands on | ||
625 | + remote machines via the 'rsh' protocol, and doing authentication | ||
626 | + related to those functions. This also includes functions that | ||
627 | + use the 'rexec' protocol. | ||
628 | + | ||
629 | + This option group includes the following functions: | ||
630 | + | ||
631 | + rcmd ruserok | ||
632 | + rcmd_af ruserok_af | ||
633 | + rexec iruserok | ||
634 | + rexec_af iruserok_af | ||
635 | + rresvport ruserpass | ||
636 | + rresvport_af | ||
637 | + | ||
638 | +config EGLIBC_RTLD_DEBUG | ||
639 | + bool "Runtime linker debug print outs" | ||
640 | + help | ||
641 | + This option group enables debug output of the runtime linker | ||
642 | + which is activated via LD_DEBUG and LD_TRACE_PRELINKING | ||
643 | + environment variables. Disabling this option group yields | ||
644 | + a smaller runtime linker binary. | ||
645 | + BEWARE: Disabling this option group is likely to break | ||
646 | + the `ldd' utility which may also be used by the prelinker. | ||
647 | + In particular, the `--unused' ldd option will not work correctly. | ||
648 | + | ||
649 | +config EGLIBC_SPAWN | ||
650 | + bool "Support for POSIX posix_spawn functions" | ||
651 | + help | ||
652 | + This option group includes the POSIX functions for executing | ||
653 | + programs in child processes without using 'fork' or 'vfork'. | ||
654 | + | ||
655 | + This option group includes the following functions: | ||
656 | + | ||
657 | + posix_spawn | ||
658 | + posix_spawnattr_destroy | ||
659 | + posix_spawnattr_getflags | ||
660 | + posix_spawnattr_getpgroup | ||
661 | + posix_spawnattr_getschedparam | ||
662 | + posix_spawnattr_getschedpolicy | ||
663 | + posix_spawnattr_getsigdefault | ||
664 | + posix_spawnattr_getsigmask | ||
665 | + posix_spawnattr_init | ||
666 | + posix_spawnattr_setflags | ||
667 | + posix_spawnattr_setpgroup | ||
668 | + posix_spawnattr_setschedparam | ||
669 | + posix_spawnattr_setschedpolicy | ||
670 | + posix_spawnattr_setsigdefault | ||
671 | + posix_spawnattr_setsigmask | ||
672 | + posix_spawn_file_actions_addclose | ||
673 | + posix_spawn_file_actions_adddup2 | ||
674 | + posix_spawn_file_actions_addopen | ||
675 | + posix_spawn_file_actions_destroy | ||
676 | + posix_spawn_file_actions_init | ||
677 | + posix_spawnp | ||
678 | + | ||
679 | + This option group also provides the ability for the iconv, | ||
680 | + localedef, and locale programs to operate transparently on | ||
681 | + compressed charset definitions. When this option group is | ||
682 | + disabled, those programs will only operate on uncompressed | ||
683 | + charmap files. | ||
684 | + | ||
685 | +config EGLIBC_STREAMS | ||
686 | + bool "Support for accessing STREAMS." | ||
687 | + help | ||
688 | + This option group includes functions for reading and writing | ||
689 | + messages to and from STREAMS. The STREAMS interface provides a | ||
690 | + uniform mechanism for implementing networking services and other | ||
691 | + character-based I/O. (STREAMS are not to be confused with | ||
692 | + <stdio.h> FILE objects, also called 'streams'.) | ||
693 | + | ||
694 | + This option group includes the following functions: | ||
695 | + | ||
696 | + getmsg putpmsg | ||
697 | + getpmsg fattach | ||
698 | + isastream fdetach | ||
699 | + putmsg | ||
700 | + | ||
701 | +config EGLIBC_SUNRPC | ||
702 | + bool "Support for the Sun 'RPC' protocol." | ||
703 | + depends on EGLIBC_INET | ||
704 | + help | ||
705 | + This option group includes support for the Sun RPC protocols, | ||
706 | + including the 'rpcgen' and 'rpcinfo' programs. | ||
707 | + | ||
708 | +config EGLIBC_UTMP | ||
709 | + bool "Older access functions for 'utmp' login records" | ||
710 | + help | ||
711 | + This option group includes the older 'utent' family of | ||
712 | + functions for accessing user login records in the 'utmp' file. | ||
713 | + POSIX omits these functions in favor of the 'utxent' family, | ||
714 | + and they are obsolete on systems other than Linux. | ||
715 | + | ||
716 | + This option group includes the following functions: | ||
717 | + | ||
718 | + endutent | ||
719 | + getutent | ||
720 | + getutent_r | ||
721 | + getutid | ||
722 | + getutid_r | ||
723 | + getutline | ||
724 | + getutline_r | ||
725 | + logwtmp | ||
726 | + pututline | ||
727 | + setutent | ||
728 | + updwtmp | ||
729 | + utmpname | ||
730 | + | ||
731 | + This option group includes the following libraries: | ||
732 | + | ||
733 | + libutil.so (and libutil.a) | ||
734 | + | ||
735 | +config EGLIBC_UTMPX | ||
736 | + bool "POSIX access functions for 'utmp' login records" | ||
737 | + depends on EGLIBC_UTMP | ||
738 | + help | ||
739 | + This option group includes the POSIX functions for reading and | ||
740 | + writing user login records in the 'utmp' file (usually | ||
741 | + '/var/run/utmp'). The POSIX functions operate on 'struct | ||
742 | + utmpx' structures, as opposed to the family of older 'utent' | ||
743 | + functions, which operate on 'struct utmp' structures. | ||
744 | + | ||
745 | + This option group includes the following functions: | ||
746 | + | ||
747 | + endutxent | ||
748 | + getutmp | ||
749 | + getutmpx | ||
750 | + getutxent | ||
751 | + getutxid | ||
752 | + getutxline | ||
753 | + pututxline | ||
754 | + setutxent | ||
755 | + updwtmpx | ||
756 | + utmpxname | ||
757 | + | ||
758 | +config EGLIBC_WORDEXP | ||
759 | + bool "Shell-style word expansion" | ||
760 | + help | ||
761 | + This option group includes the 'wordexp' function for | ||
762 | + performing word expansion in the manner of the shell, and the | ||
763 | + accompanying 'wordfree' function. | ||
764 | + | ||
765 | +config POSIX_C_LANG_WIDE_CHAR | ||
766 | + bool "ISO C library wide character functions, excluding I/O" | ||
767 | + help | ||
768 | + This option group includes the functions defined by the ISO C | ||
769 | + standard for working with wide and multibyte characters in | ||
770 | + memory. Functions for reading and writing wide and multibyte | ||
771 | + characters from and to files call in the | ||
772 | + POSIX_WIDE_CHAR_DEVICE_IO option group. | ||
773 | + | ||
774 | + This option group includes the following functions: | ||
775 | + | ||
776 | + btowc mbsinit wcscspn wcstoll | ||
777 | + iswalnum mbsrtowcs wcsftime wcstombs | ||
778 | + iswalpha mbstowcs wcslen wcstoul | ||
779 | + iswblank mbtowc wcsncat wcstoull | ||
780 | + iswcntrl swprintf wcsncmp wcstoumax | ||
781 | + iswctype swscanf wcsncpy wcsxfrm | ||
782 | + iswdigit towctrans wcspbrk wctob | ||
783 | + iswgraph towlower wcsrchr wctomb | ||
784 | + iswlower towupper wcsrtombs wctrans | ||
785 | + iswprint vswprintf wcsspn wctype | ||
786 | + iswpunct vswscanf wcsstr wmemchr | ||
787 | + iswspace wcrtomb wcstod wmemcmp | ||
788 | + iswupper wcscat wcstof wmemcpy | ||
789 | + iswxdigit wcschr wcstoimax wmemmove | ||
790 | + mblen wcscmp wcstok wmemset | ||
791 | + mbrlen wcscoll wcstol | ||
792 | + mbrtowc wcscpy wcstold | ||
793 | + | ||
794 | +config POSIX_REGEXP | ||
795 | + bool "Regular expressions" | ||
796 | + help | ||
797 | + This option group includes the POSIX regular expression | ||
798 | + functions, and the associated non-POSIX extensions and | ||
799 | + compatibility functions. | ||
800 | + | ||
801 | + With POSIX_REGEXP disabled, the following functions are | ||
802 | + omitted from libc: | ||
803 | + | ||
804 | + re_comp re_max_failures regcomp | ||
805 | + re_compile_fastmap re_search regerror | ||
806 | + re_compile_pattern re_search_2 regexec | ||
807 | + re_exec re_set_registers regfree | ||
808 | + re_match re_set_syntax rpmatch | ||
809 | + re_match_2 re_syntax_options | ||
810 | + | ||
811 | + Furthermore, the compatibility regexp interface defined in the | ||
812 | + <regexp.h> header file, 'compile', 'step', and 'advance', is | ||
813 | + omitted. | ||
814 | + | ||
815 | +config POSIX_REGEXP_GLIBC | ||
816 | + bool "Regular expressions from GLIBC" | ||
817 | + depends on POSIX_REGEXP | ||
818 | + help | ||
819 | + This option group specifies which regular expression | ||
820 | + library to use. The choice is between regex | ||
821 | + implementation from GLIBC and regex implementation from | ||
822 | + libiberty. The GLIBC variant is fully POSIX conformant and | ||
823 | + optimized for speed; regex from libiberty is more than twice | ||
824 | + as small while still is enough for most practical purposes. | ||
825 | + | ||
826 | +config POSIX_WIDE_CHAR_DEVICE_IO | ||
827 | + bool "Input and output functions for wide characters" | ||
828 | + depends on POSIX_C_LANG_WIDE_CHAR | ||
829 | + help | ||
830 | + This option group includes functions for reading and writing | ||
831 | + wide characters to and from <stdio.h> streams. | ||
832 | + | ||
833 | + This option group includes the following functions: | ||
834 | + | ||
835 | + fgetwc fwprintf putwchar vwscanf | ||
836 | + fgetws fwscanf ungetwc wprintf | ||
837 | + fputwc getwc vfwprintf wscanf | ||
838 | + fputws getwchar vfwscanf | ||
839 | + fwide putwc vwprintf | ||
840 | + | ||
841 | + This option group further includes the following unlocked | ||
842 | + variants of the above functions: | ||
843 | + | ||
844 | + fgetwc_unlocked getwc_unlocked | ||
845 | + fgetws_unlocked getwchar_unlocked | ||
846 | + fputwc_unlocked putwc_unlocked | ||
847 | + fputws_unlocked putwchar_unlocked | ||
848 | + | ||
849 | + Note that the GNU standard C++ library, 'libstdc++.so', uses | ||
850 | + some of these functions; you will not be able to link or run | ||
851 | + C++ programs if you disable this option group. | ||
852 | + | ||
853 | + This option group also affects the behavior of the following | ||
854 | + functions: | ||
855 | + | ||
856 | + fdopen | ||
857 | + fopen | ||
858 | + fopen64 | ||
859 | + freopen | ||
860 | + freopen64 | ||
861 | + | ||
862 | + These functions all take an OPENTYPE parameter which may | ||
863 | + contain a string of the form ",ccs=CHARSET", indicating that | ||
864 | + the underlying file uses the character set named CHARSET. | ||
865 | + This produces a wide-oriented stream, which is only useful | ||
866 | + when the functions included in this option group are present. | ||
867 | + If the user attempts to open a file specifying a character set | ||
868 | + in the OPENTYPE parameter, and EGLIBC was built with this | ||
869 | + option group disabled, the function returns NULL, and sets | ||
870 | + errno to EINVAL. | ||
871 | + | ||
872 | + | ||
873 | +# This helps Emacs users browse this file using the page motion commands | ||
874 | +# and commands like 'pages-directory'. | ||
875 | +# Local Variables: | ||
876 | +# page-delimiter: "^config\\s-" | ||
877 | +# End: | ||
878 | Index: git/option-groups.mak | ||
879 | =================================================================== | ||
880 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
881 | +++ git/option-groups.mak 2014-08-27 07:26:51.652070587 +0000 | ||
882 | @@ -0,0 +1,41 @@ | ||
883 | +# Setup file for subdirectory Makefiles that define EGLIBC option groups. | ||
884 | + | ||
885 | +# EGLIBC shouldn't need to override this. However, the | ||
886 | +# cross-build-friendly localedef includes this makefile to get option | ||
887 | +# group variable definitions; it uses a single build tree for all the | ||
888 | +# multilibs, and needs to be able to specify a different option group | ||
889 | +# configuration file for each multilib. | ||
890 | +option_group_config_file ?= $(objdir)/option-groups.config | ||
891 | + | ||
892 | +# Read the default settings for all options. | ||
893 | +# We're included before ../Rules, so we can't assume $(..) is set. | ||
894 | +include $(firstword $(..) ../)option-groups.defaults | ||
895 | + | ||
896 | +# Read the developer's option group selections, overriding the | ||
897 | +# defaults from option-groups.defaults. | ||
898 | +-include $(option_group_config_file) | ||
899 | + | ||
900 | +# $(call option-disabled, VAR) is 'y' if VAR is not 'y', or 'n' otherwise. | ||
901 | +# VAR should be a variable name, not a variable reference; this is | ||
902 | +# less general, but more terse for the intended use. | ||
903 | +# You can use it to add a file to a list if an option group is | ||
904 | +# disabled, like this: | ||
905 | +# routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) += ... | ||
906 | +define option-disabled | ||
907 | +$(firstword $(subst y,n,$(filter y,$($(strip $(1))))) y) | ||
908 | +endef | ||
909 | + | ||
910 | +# Establish 'routines-y', etc. as simply-expanded variables. | ||
911 | +aux-y := | ||
912 | +extra-libs-others-y := | ||
913 | +extra-libs-y := | ||
914 | +extra-objs-y := | ||
915 | +install-bin-y := | ||
916 | +install-others-y := | ||
917 | +install-sbin-y := | ||
918 | +others-y := | ||
919 | +others-pie-y := | ||
920 | +routines-y := | ||
921 | +test-srcs-y := | ||
922 | +tests-y := | ||
923 | +xtests-y := | ||
924 | Index: git/option-groups.defaults | ||
925 | =================================================================== | ||
926 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
927 | +++ git/option-groups.defaults 2014-08-27 07:24:41.652070587 +0000 | ||
928 | @@ -0,0 +1,47 @@ | ||
929 | +# This file sets default values for all option group variables | ||
930 | +# mentioned in option-groups.def; see that file for a description of | ||
931 | +# each option group. | ||
932 | +# | ||
933 | +# Subdirectory makefiles include this file before including the user's | ||
934 | +# settings from option-groups.config at the top of the build tree; | ||
935 | +# that file need only refer to those options whose default settings | ||
936 | +# are to be changed. | ||
937 | +# | ||
938 | +# By default, all option groups are enabled. | ||
939 | +OPTION_EGLIBC_ADVANCED_INET6 = y | ||
940 | +OPTION_EGLIBC_BACKTRACE = y | ||
941 | +OPTION_EGLIBC_BIG_MACROS = y | ||
942 | +OPTION_EGLIBC_BSD = y | ||
943 | +OPTION_EGLIBC_CXX_TESTS = y | ||
944 | +OPTION_EGLIBC_CATGETS = y | ||
945 | +OPTION_EGLIBC_CHARSETS = y | ||
946 | +OPTION_EGLIBC_CRYPT = y | ||
947 | +OPTION_EGLIBC_CRYPT_UFC = y | ||
948 | +OPTION_EGLIBC_DB_ALIASES = y | ||
949 | +OPTION_EGLIBC_ENVZ = y | ||
950 | +OPTION_EGLIBC_FCVT = y | ||
951 | +OPTION_EGLIBC_FMTMSG = y | ||
952 | +OPTION_EGLIBC_FSTAB = y | ||
953 | +OPTION_EGLIBC_FTRAVERSE = y | ||
954 | +OPTION_EGLIBC_GETLOGIN = y | ||
955 | +OPTION_EGLIBC_IDN = y | ||
956 | +OPTION_EGLIBC_INET = y | ||
957 | +OPTION_EGLIBC_INET_ANL = y | ||
958 | +OPTION_EGLIBC_LIBM = y | ||
959 | +OPTION_EGLIBC_LOCALES = y | ||
960 | +OPTION_EGLIBC_LOCALE_CODE = y | ||
961 | +OPTION_EGLIBC_MEMUSAGE = y | ||
962 | +OPTION_EGLIBC_NIS = y | ||
963 | +OPTION_EGLIBC_NSSWITCH = y | ||
964 | +OPTION_EGLIBC_RCMD = y | ||
965 | +OPTION_EGLIBC_RTLD_DEBUG = y | ||
966 | +OPTION_EGLIBC_SPAWN = y | ||
967 | +OPTION_EGLIBC_STREAMS = y | ||
968 | +OPTION_EGLIBC_SUNRPC = y | ||
969 | +OPTION_EGLIBC_UTMP = y | ||
970 | +OPTION_EGLIBC_UTMPX = y | ||
971 | +OPTION_EGLIBC_WORDEXP = y | ||
972 | +OPTION_POSIX_C_LANG_WIDE_CHAR = y | ||
973 | +OPTION_POSIX_REGEXP = y | ||
974 | +OPTION_POSIX_REGEXP_GLIBC = y | ||
975 | +OPTION_POSIX_WIDE_CHAR_DEVICE_IO = y | ||
976 | Index: git/Makefile | ||
977 | =================================================================== | ||
978 | --- git.orig/Makefile 2014-08-27 07:24:37.540070587 +0000 | ||
979 | +++ git/Makefile 2014-08-27 07:24:41.656070587 +0000 | ||
980 | @@ -24,6 +24,7 @@ | ||
981 | |||
982 | include Makeconfig | ||
983 | |||
984 | +include options-config/Makefile | ||
985 | |||
986 | # This is the default target; it makes everything except the tests. | ||
987 | .PHONY: all | ||
988 | Index: git/EGLIBC.option-groups | ||
989 | =================================================================== | ||
990 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
991 | +++ git/EGLIBC.option-groups 2014-08-27 07:24:41.656070587 +0000 | ||
992 | @@ -0,0 +1,122 @@ | ||
993 | + -*- mode: text -*- | ||
994 | + | ||
995 | + The EGLIBC Component Configuration System | ||
996 | + Jim Blandy <jimb@codesourcery.com> | ||
997 | + | ||
998 | +Introduction | ||
999 | + | ||
1000 | +The GNU C library (GLIBC) provides a broad range of functionality, | ||
1001 | +ranging from internationalization support to transcendental | ||
1002 | +mathematical functions. Its website boasts that "nearly all known and | ||
1003 | +useful functions from any other C library are available." This | ||
1004 | +exhaustive approach has been one of GLIBC's strengths on desktop and | ||
1005 | +server systems, but it has also given GLIBC a large footprint, both in | ||
1006 | +memory and on disk, making it a challenge to use in embedded systems | ||
1007 | +with limited resources. | ||
1008 | + | ||
1009 | +The Embedded GNU C library (EGLIBC) is a variant of the GNU C library | ||
1010 | +designed to work well on embedded systems. In particular, EGLIBC's | ||
1011 | +component configuration system allows embedded developers to build | ||
1012 | +customized versions of the library that include only the features | ||
1013 | +their application uses, reducing its space requirements. | ||
1014 | + | ||
1015 | +EGLIBC's component configuration system categorizes the library's | ||
1016 | +functions into "option groups", and allows you to include or exclude | ||
1017 | +option groups individually. Some option groups depend on others; | ||
1018 | +EGLIBC tracks these relationships, and ensures that the selected | ||
1019 | +configuration yields a functioning library. | ||
1020 | + | ||
1021 | + | ||
1022 | +Consistent and Predictable Behavior | ||
1023 | + | ||
1024 | +A flexible configuration system is a mixed blessing: if the options | ||
1025 | +offered are poorly designed, it can be hard to see which choices will | ||
1026 | +have the desired effects, and choices with obscure consequences can | ||
1027 | +make debugging difficult. EGLIBC's configuration follows some general | ||
1028 | +principles to reduce these risks: | ||
1029 | + | ||
1030 | +- EGLIBC has a single default configuration for each target | ||
1031 | + architecture. | ||
1032 | + | ||
1033 | +- In the default configuration, all option groups are enabled, and | ||
1034 | + EGLIBC is upwardly API- and ABI-compatible with GLIBC. | ||
1035 | + | ||
1036 | +- As much as possible, configurations only affect what functions are | ||
1037 | + present, not how they behave. If the system works with an option | ||
1038 | + group disabled, it will still work with it enabled. | ||
1039 | + | ||
1040 | +- As much as possible, configurations only select option groups --- | ||
1041 | + they do not describe characteristics of the target architecture. | ||
1042 | + | ||
1043 | +These rules mean that you have a simple debugging strategy available | ||
1044 | +if you suspect that your EGLIBC configuration might be the source of a | ||
1045 | +problem: fall back to the default configuration, re-test, and then | ||
1046 | +disable option groups one by one, until the problem reappears. | ||
1047 | + | ||
1048 | + | ||
1049 | +The Option Groups | ||
1050 | + | ||
1051 | +To see the current full list of implemented option groups, refer to the | ||
1052 | +file 'option-groups.def' at the top of the source tree, or run | ||
1053 | +'make menuconfig' from the top-level build directory. | ||
1054 | + | ||
1055 | +The POSIX.1-2001 specification includes a suggested partition of all | ||
1056 | +the functions in the POSIX C API into option groups: math functions | ||
1057 | +like 'sin' and 'cos'; networking functions like 'socket' and | ||
1058 | +'connect'; and so on. EGLIBC could use this partitioning as the basis | ||
1059 | +for future option groups. | ||
1060 | + | ||
1061 | + | ||
1062 | +Implementation | ||
1063 | + | ||
1064 | +The EGLIBC component configuration system resembles the approach used | ||
1065 | +by the Linux kernel to select device drivers, network protocols, and | ||
1066 | +other features. A file named 'option-groups.config' in the top-level | ||
1067 | +build directory contains assignments to Make variables, each of which | ||
1068 | +enables or disables a particular option group. If the variable's | ||
1069 | +value is set to 'y', then the option group is enabled; if it set to | ||
1070 | +anything else, the option group is omitted. The file | ||
1071 | +'option-groups.defaults', at the top of the source tree, establishes | ||
1072 | +default values for all variables; all option groups are enabled by | ||
1073 | +default. | ||
1074 | + | ||
1075 | +For example, the following 'option-groups.config' would omit locale | ||
1076 | +data, but include mathematical functions, and everything else: | ||
1077 | + | ||
1078 | + OPTION_EGLIBC_LOCALES = n | ||
1079 | + OPTION_EGLIBC_LIBM = y | ||
1080 | + | ||
1081 | +Like the Linux kernel, EGLIBC supports a similar set of '*config' make | ||
1082 | +targets to make it easier to create 'option-groups.config', with all | ||
1083 | +dependencies between option groups automatically satisfied. Run | ||
1084 | +'make help' to see the list of supported make config targets. For | ||
1085 | +example, 'make menuconfig' will update the current config utilising a | ||
1086 | +menu based program. | ||
1087 | + | ||
1088 | +The option group names and their type (boolean, int, hex, string), help | ||
1089 | +description, and dependencies with other option groups, are described by | ||
1090 | +'option-groups.def' at the top of the source tree, analogous to the | ||
1091 | +'Kconfig' files in the Linux kernel. | ||
1092 | + | ||
1093 | +In general, each option group variable controls whether a given set of | ||
1094 | +object files in EGLIBC is compiled and included in the final | ||
1095 | +libraries, or omitted from the build. | ||
1096 | + | ||
1097 | +Each subdirectory's Makefile categorizes its routines, libraries, and | ||
1098 | +executables by option group. For example, EGLIBC's 'math/Makefile' | ||
1099 | +places the 'libm' library in the OPTION_EGLIBC_LIBM group as follows: | ||
1100 | + | ||
1101 | + extra-libs-$(OPTION_EGLIBC_LIBM) := libm | ||
1102 | + | ||
1103 | +Finally, common code in 'Makerules' cites the value of the variable | ||
1104 | +'extra-libs-y', selecting only those libraries that belong to enabled | ||
1105 | +option groups to be built. | ||
1106 | + | ||
1107 | + | ||
1108 | +Current Status and Future Directions | ||
1109 | + | ||
1110 | +The EGLIBC component configuration system described here is still | ||
1111 | +under development. | ||
1112 | + | ||
1113 | +We have used the system to subset some portions of EGLIBC's | ||
1114 | +Index: libc/configure.ac | ||
1115 | Index: git/configure.ac | ||
1116 | =================================================================== | ||
1117 | --- git.orig/configure.ac 2014-08-27 07:24:41.196070587 +0000 | ||
1118 | +++ git/configure.ac 2014-08-27 07:24:41.656070587 +0000 | ||
1119 | @@ -127,6 +127,16 @@ | ||
1120 | [sysheaders='']) | ||
1121 | AC_SUBST(sysheaders) | ||
1122 | |||
1123 | +AC_ARG_WITH([kconfig], | ||
1124 | + AC_HELP_STRING([--with-kconfig=PATH], | ||
1125 | + [location of kconfig tools to use (from Linux | ||
1126 | + kernel builds) to re-use for configuring EGLIBC | ||
1127 | + option groups]), | ||
1128 | + [KCONFIG_TOOLS=$withval], | ||
1129 | + [KCONFIG_TOOLS='']) | ||
1130 | +AC_SUBST(KCONFIG_TOOLS) | ||
1131 | + | ||
1132 | + | ||
1133 | AC_SUBST(use_default_link) | ||
1134 | AC_ARG_WITH([default-link], | ||
1135 | AC_HELP_STRING([--with-default-link], | ||
1136 | Index: git/config.make.in | ||
1137 | =================================================================== | ||
1138 | --- git.orig/config.make.in 2014-08-27 07:24:37.560070587 +0000 | ||
1139 | +++ git/config.make.in 2014-08-27 07:24:41.656070587 +0000 | ||
1140 | @@ -46,6 +46,8 @@ | ||
1141 | c++-sysincludes = @CXX_SYSINCLUDES@ | ||
1142 | all-warnings = @all_warnings@ | ||
1143 | |||
1144 | +kconfig_tools = @KCONFIG_TOOLS@ | ||
1145 | + | ||
1146 | have-z-combreloc = @libc_cv_z_combreloc@ | ||
1147 | have-z-execstack = @libc_cv_z_execstack@ | ||
1148 | have-Bgroup = @libc_cv_Bgroup@ | ||
1149 | Index: git/configure | ||
1150 | =================================================================== | ||
1151 | --- git.orig/configure 2014-08-27 07:24:41.192070587 +0000 | ||
1152 | +++ git/configure 2014-08-27 07:24:41.660070587 +0000 | ||
1153 | @@ -619,6 +619,7 @@ | ||
1154 | PERL | ||
1155 | BASH_SHELL | ||
1156 | libc_cv_gcc_static_libgcc | ||
1157 | +KCONFIG_TOOLS | ||
1158 | CXX_SYSINCLUDES | ||
1159 | SYSINCLUDES | ||
1160 | AUTOCONF | ||
1161 | @@ -733,6 +734,7 @@ | ||
1162 | with_binutils | ||
1163 | with_selinux | ||
1164 | with_headers | ||
1165 | +with_kconfig | ||
1166 | with_default_link | ||
1167 | enable_sanity_checks | ||
1168 | enable_shared | ||
1169 | @@ -1437,6 +1439,9 @@ | ||
1170 | --with-selinux if building with SELinux support | ||
1171 | --with-headers=PATH location of system headers to use (for example | ||
1172 | /usr/src/linux/include) [default=compiler default] | ||
1173 | + --with-kconfig=PATH location of kconfig tools to use (from Linux kernel | ||
1174 | + builds) to re-use for configuring EGLIBC option | ||
1175 | + groups | ||
1176 | --with-default-link do not use explicit linker scripts | ||
1177 | --with-cpu=CPU select code for CPU variant | ||
1178 | |||
1179 | @@ -3400,6 +3405,14 @@ | ||
1180 | |||
1181 | |||
1182 | |||
1183 | +# Check whether --with-kconfig was given. | ||
1184 | +if test "${with_kconfig+set}" = set; then | ||
1185 | + withval=$with_kconfig; KCONFIG_TOOLS=$withval | ||
1186 | +else | ||
1187 | + KCONFIG_TOOLS='' | ||
1188 | +fi | ||
1189 | + | ||
1190 | + | ||
1191 | |||
1192 | # Check whether --with-default-link was given. | ||
1193 | if test "${with_default_link+set}" = set; then : | ||
1194 | Index: git/options-config/Makefile | ||
1195 | =================================================================== | ||
1196 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1197 | +++ git/options-config/Makefile 2014-08-27 07:24:41.652070587 +0000 | ||
1198 | @@ -0,0 +1,55 @@ | ||
1199 | +# =========================================================================== | ||
1200 | +# EGLIBC option-groups configuration targets | ||
1201 | +# These targets are included from top-level makefile | ||
1202 | + | ||
1203 | +ifneq ($(kconfig_tools),) | ||
1204 | +ifneq (no,$(PERL)) | ||
1205 | + | ||
1206 | +ocdir := options-config | ||
1207 | + | ||
1208 | +OconfigDefaults := option-groups.defaults | ||
1209 | +OconfigDefaults_tmp := $(common-objpfx).tmp.defconfig | ||
1210 | +OconfigDef := option-groups.def | ||
1211 | +Oconfig := $(common-objpfx)option-groups.config | ||
1212 | +Oconfig_tmp := $(common-objpfx).tmp.config | ||
1213 | + | ||
1214 | +conf := $(kconfig_tools)/conf | ||
1215 | +mconf := $(kconfig_tools)/mconf | ||
1216 | + | ||
1217 | +preproc := $(PERL) $(ocdir)/config-preproc.pl | ||
1218 | +postproc := $(PERL) $(ocdir)/config-postproc.pl | ||
1219 | + | ||
1220 | +PHONY += defconfig config menuconfig | ||
1221 | + | ||
1222 | +defconfig: $(conf) $(OconfigDefaults) $(OconfigDef) | ||
1223 | + rm -f $(OconfigDefaults_tmp) | ||
1224 | + rm -f $(Oconfig_tmp) | ||
1225 | + $(preproc) $(OconfigDefaults) > $(OconfigDefaults_tmp) | ||
1226 | + KCONFIG_CONFIG=$(Oconfig_tmp) $< --defconfig=$(OconfigDefaults_tmp) \ | ||
1227 | + $(OconfigDef) | ||
1228 | + $(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig) | ||
1229 | + rm $(Oconfig_tmp) | ||
1230 | + rm $(OconfigDefaults_tmp) | ||
1231 | + | ||
1232 | +config: $(conf) $(OconfigDefaults) $(OconfigDef) | ||
1233 | + rm -f $(Oconfig_tmp) | ||
1234 | + $(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp) | ||
1235 | + KCONFIG_CONFIG=$(Oconfig_tmp) $< --oldaskconfig $(OconfigDef) | ||
1236 | + $(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig) | ||
1237 | + rm $(Oconfig_tmp) | ||
1238 | + | ||
1239 | +menuconfig: $(mconf) $(OconfigDefaults) $(OconfigDef) | ||
1240 | + rm -f $(Oconfig_tmp) | ||
1241 | + $(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp) | ||
1242 | + KCONFIG_CONFIG=$(Oconfig_tmp) $< $(OconfigDef) | ||
1243 | + $(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig) | ||
1244 | + rm $(Oconfig_tmp) | ||
1245 | + | ||
1246 | +# Help text used by make help | ||
1247 | +help: | ||
1248 | + @echo ' defconfig - New config with default from default config' | ||
1249 | + @echo ' config - Update current config utilising a line-oriented program' | ||
1250 | + @echo ' menuconfig - Update current config utilising a menu based program' | ||
1251 | + | ||
1252 | +endif | ||
1253 | +endif | ||
1254 | Index: git/options-config/config-postproc.pl | ||
1255 | =================================================================== | ||
1256 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1257 | +++ git/options-config/config-postproc.pl 2014-08-27 07:24:41.652070587 +0000 | ||
1258 | @@ -0,0 +1,58 @@ | ||
1259 | +#!/usr/bin/perl | ||
1260 | + | ||
1261 | +$usage = "usage: $0 <default config file> <config file>\n"; | ||
1262 | + | ||
1263 | +die "$usage" unless @ARGV; | ||
1264 | +$defaults = shift @ARGV; | ||
1265 | +die "$usage" unless @ARGV; | ||
1266 | +die "Could not open $ARGV[0]" unless -T $ARGV[0]; | ||
1267 | + | ||
1268 | +sub yank { | ||
1269 | + @option = grep(!($_ =~ /$_[0]\s*=/), @option); | ||
1270 | +} | ||
1271 | + | ||
1272 | +open(DEFAULTS, $defaults) || die "Could not open $defaults\n"; | ||
1273 | + | ||
1274 | +# get the full list of available options using the default config file | ||
1275 | +$i = 0; | ||
1276 | +while (<DEFAULTS>) { | ||
1277 | + if (/^\s*OPTION_(\w+\s*=.*$)/) { | ||
1278 | + $option[$i++] = $1; | ||
1279 | + } | ||
1280 | +} | ||
1281 | + | ||
1282 | +# now go through the config file, making the necessary changes | ||
1283 | +while (<>) { | ||
1284 | + if (/Linux Kernel Configuration/) { | ||
1285 | + # change title | ||
1286 | + s/Linux Kernel/Option Groups/; | ||
1287 | + print; | ||
1288 | + } elsif (/^\s*CONFIG_(\w+)\s*=/) { | ||
1289 | + # this is an explicit option set line, change CONFIG_ to OPTION_ | ||
1290 | + # before printing and remove this option from option list | ||
1291 | + $opt = $1; | ||
1292 | + yank($opt); | ||
1293 | + s/CONFIG_/OPTION_/g; | ||
1294 | + print; | ||
1295 | + } elsif (/^\s*#\s+CONFIG_(\w+) is not set/) { | ||
1296 | + # this is a comment line for an unset boolean option, change CONFIG_ | ||
1297 | + # to OPTION_, remove this option from option list, and convert to | ||
1298 | + # explicit OPTION_FOO=n | ||
1299 | + $opt = $1; | ||
1300 | + yank($opt); | ||
1301 | + s/CONFIG_/OPTION_/g; | ||
1302 | + print "OPTION_$opt=n\n"; | ||
1303 | + } else { | ||
1304 | + print; | ||
1305 | + } | ||
1306 | +} | ||
1307 | + | ||
1308 | +# any boolean options left in @options, are options that were not mentioned in | ||
1309 | +# the config file, and implicitly that means the option must be set =n, | ||
1310 | +# so do that here. | ||
1311 | +foreach $opt (@option) { | ||
1312 | + if ($opt =~ /=\s*[yn]/) { | ||
1313 | + $opt =~ s/=\s*[yn]/=n/; | ||
1314 | + print "OPTION_$opt\n"; | ||
1315 | + } | ||
1316 | +} | ||
1317 | Index: git/options-config/config-preproc.pl | ||
1318 | =================================================================== | ||
1319 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1320 | +++ git/options-config/config-preproc.pl 2014-08-27 07:24:41.652070587 +0000 | ||
1321 | @@ -0,0 +1,8 @@ | ||
1322 | +#!/usr/bin/perl | ||
1323 | + | ||
1324 | +if (@ARGV) { | ||
1325 | + while (<>) { | ||
1326 | + s/OPTION_/CONFIG_/g; | ||
1327 | + print; | ||
1328 | + } | ||
1329 | +} | ||
1330 | Index: git/scripts/option-groups.awk | ||
1331 | =================================================================== | ||
1332 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1333 | +++ git/scripts/option-groups.awk 2014-08-27 07:26:51.652070587 +0000 | ||
1334 | @@ -0,0 +1,63 @@ | ||
1335 | +# option-groups.awk --- generate option group header file | ||
1336 | +# Given input files containing makefile-style assignments to variables, | ||
1337 | +# print out a header file that #defines an appropriate preprocessor | ||
1338 | +# symbol for each variable left set to 'y'. | ||
1339 | + | ||
1340 | +BEGIN { FS="=" } | ||
1341 | + | ||
1342 | +# Trim spaces. | ||
1343 | +{ gsub (/[[:blank:]]/, "") } | ||
1344 | + | ||
1345 | +# Skip comments. | ||
1346 | +/^#/ { next } | ||
1347 | + | ||
1348 | +# Process assignments. | ||
1349 | +NF == 2 { | ||
1350 | + vars[$1] = $2 | ||
1351 | +} | ||
1352 | + | ||
1353 | +# Print final values. | ||
1354 | +END { | ||
1355 | + print "/* This file is automatically generated by scripts/option-groups.awk" | ||
1356 | + print " in the EGLIBC source tree." | ||
1357 | + print "" | ||
1358 | + print " It defines macros that indicate which EGLIBC option groups were" | ||
1359 | + print " configured in 'option-groups.config' when this C library was" | ||
1360 | + print " built. For each option group named OPTION_foo, it #defines" | ||
1361 | + print " __OPTION_foo to be 1 if the group is enabled, or leaves that" | ||
1362 | + print " symbol undefined if the group is disabled. */" | ||
1363 | + print "" | ||
1364 | + print "#ifndef __GNU_OPTION_GROUPS_H" | ||
1365 | + print "#define __GNU_OPTION_GROUPS_H" | ||
1366 | + print "" | ||
1367 | + | ||
1368 | + # Produce a sorted list of variable names. | ||
1369 | + i=0 | ||
1370 | + for (var in vars) | ||
1371 | + names[i++] = var | ||
1372 | + n = asort (names) | ||
1373 | + | ||
1374 | + for (i = 1; i <= n; i++) | ||
1375 | + { | ||
1376 | + var = names[i] | ||
1377 | + if (var ~ /^OPTION_/) | ||
1378 | + { | ||
1379 | + if (vars[var] == "y") | ||
1380 | + print "#define __" var " 1" | ||
1381 | + else if (vars[var] == "n") | ||
1382 | + print "/* #undef __" var " */" | ||
1383 | + else if (vars[var] ~ /^[0-9]+/ || | ||
1384 | + vars[var] ~ /^0x[0-9aAbBcCdDeEfF]+/ || | ||
1385 | + vars[var] ~ /^\"/) | ||
1386 | + print "#define __" var " " vars[var] | ||
1387 | + else | ||
1388 | + print "/* #undef __" var " */" | ||
1389 | + # Ignore variables that don't have boolean, int, hex, or | ||
1390 | + # string values. Ideally, this would be driven by the types | ||
1391 | + # given in option-groups.def. | ||
1392 | + } | ||
1393 | + } | ||
1394 | + | ||
1395 | + print "" | ||
1396 | + print "#endif /* __GNU_OPTION_GROUPS_H */" | ||
1397 | +} | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ppc-sqrt_finite.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ppc-sqrt_finite.patch new file mode 100644 index 0000000..6ea666b --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ppc-sqrt_finite.patch | |||
@@ -0,0 +1,184 @@ | |||
1 | on ppc fixes the errors like below | ||
2 | | ./.libs/libpulsecore-1.1.so: undefined reference to `__sqrt_finite' | ||
3 | | collect2: ld returned 1 exit status | ||
4 | |||
5 | Upstream-Status: Pending | ||
6 | |||
7 | ChangeLog | ||
8 | |||
9 | 2012-01-06 Khem Raj <raj.khem@gmail.com> | ||
10 | |||
11 | * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c: Add __*_finite alias. | ||
12 | Remove cruft. | ||
13 | * sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c: Ditto. | ||
14 | * sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c: Ditto. | ||
15 | * sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c: Ditto. | ||
16 | |||
17 | Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c | ||
18 | =================================================================== | ||
19 | --- libc.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c | ||
20 | +++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c | ||
21 | @@ -39,14 +39,8 @@ static const float half = 0.5; | ||
22 | We find the actual square root and half of its reciprocal | ||
23 | simultaneously. */ | ||
24 | |||
25 | -#ifdef __STDC__ | ||
26 | double | ||
27 | __ieee754_sqrt (double b) | ||
28 | -#else | ||
29 | -double | ||
30 | -__ieee754_sqrt (b) | ||
31 | - double b; | ||
32 | -#endif | ||
33 | { | ||
34 | if (__builtin_expect (b > 0, 1)) | ||
35 | { | ||
36 | @@ -132,3 +126,4 @@ __ieee754_sqrt (b) | ||
37 | } | ||
38 | return f_wash (b); | ||
39 | } | ||
40 | +strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
41 | Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c | ||
42 | =================================================================== | ||
43 | --- libc.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c | ||
44 | +++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c | ||
45 | @@ -37,14 +37,8 @@ static const float threehalf = 1.5; | ||
46 | We find the reciprocal square root and use that to compute the actual | ||
47 | square root. */ | ||
48 | |||
49 | -#ifdef __STDC__ | ||
50 | float | ||
51 | __ieee754_sqrtf (float b) | ||
52 | -#else | ||
53 | -float | ||
54 | -__ieee754_sqrtf (b) | ||
55 | - float b; | ||
56 | -#endif | ||
57 | { | ||
58 | if (__builtin_expect (b > 0, 1)) | ||
59 | { | ||
60 | @@ -99,3 +93,4 @@ __ieee754_sqrtf (b) | ||
61 | } | ||
62 | return f_washf (b); | ||
63 | } | ||
64 | +strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
65 | Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c | ||
66 | =================================================================== | ||
67 | --- libc.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c | ||
68 | +++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c | ||
69 | @@ -39,14 +39,8 @@ static const float half = 0.5; | ||
70 | We find the actual square root and half of its reciprocal | ||
71 | simultaneously. */ | ||
72 | |||
73 | -#ifdef __STDC__ | ||
74 | double | ||
75 | __ieee754_sqrt (double b) | ||
76 | -#else | ||
77 | -double | ||
78 | -__ieee754_sqrt (b) | ||
79 | - double b; | ||
80 | -#endif | ||
81 | { | ||
82 | if (__builtin_expect (b > 0, 1)) | ||
83 | { | ||
84 | @@ -132,3 +126,4 @@ __ieee754_sqrt (b) | ||
85 | } | ||
86 | return f_wash (b); | ||
87 | } | ||
88 | +strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
89 | Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c | ||
90 | =================================================================== | ||
91 | --- libc.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c | ||
92 | +++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c | ||
93 | @@ -37,14 +37,8 @@ static const float threehalf = 1.5; | ||
94 | We find the reciprocal square root and use that to compute the actual | ||
95 | square root. */ | ||
96 | |||
97 | -#ifdef __STDC__ | ||
98 | float | ||
99 | __ieee754_sqrtf (float b) | ||
100 | -#else | ||
101 | -float | ||
102 | -__ieee754_sqrtf (b) | ||
103 | - float b; | ||
104 | -#endif | ||
105 | { | ||
106 | if (__builtin_expect (b > 0, 1)) | ||
107 | { | ||
108 | @@ -99,3 +93,4 @@ __ieee754_sqrtf (b) | ||
109 | } | ||
110 | return f_washf (b); | ||
111 | } | ||
112 | +strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
113 | Index: libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c | ||
114 | =================================================================== | ||
115 | --- libc.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c | ||
116 | +++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c | ||
117 | @@ -132,3 +132,4 @@ __ieee754_sqrt (b) | ||
118 | } | ||
119 | return f_wash (b); | ||
120 | } | ||
121 | +strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
122 | Index: libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c | ||
123 | =================================================================== | ||
124 | --- libc.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c | ||
125 | +++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c | ||
126 | @@ -99,3 +99,4 @@ __ieee754_sqrtf (b) | ||
127 | } | ||
128 | return f_washf (b); | ||
129 | } | ||
130 | +strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
131 | Index: libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c | ||
132 | =================================================================== | ||
133 | --- libc.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c | ||
134 | +++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c | ||
135 | @@ -132,3 +132,4 @@ __ieee754_sqrt (b) | ||
136 | } | ||
137 | return f_wash (b); | ||
138 | } | ||
139 | +strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
140 | Index: libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c | ||
141 | =================================================================== | ||
142 | --- libc.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c | ||
143 | +++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c | ||
144 | @@ -99,3 +99,4 @@ __ieee754_sqrtf (b) | ||
145 | } | ||
146 | return f_washf (b); | ||
147 | } | ||
148 | +strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
149 | Index: libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c | ||
150 | =================================================================== | ||
151 | --- libc.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c | ||
152 | +++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c | ||
153 | @@ -132,3 +132,4 @@ __ieee754_sqrt (b) | ||
154 | } | ||
155 | return f_wash (b); | ||
156 | } | ||
157 | +strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
158 | Index: libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c | ||
159 | =================================================================== | ||
160 | --- libc.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c | ||
161 | +++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c | ||
162 | @@ -99,3 +99,4 @@ __ieee754_sqrtf (b) | ||
163 | } | ||
164 | return f_washf (b); | ||
165 | } | ||
166 | +strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
167 | Index: libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c | ||
168 | =================================================================== | ||
169 | --- libc.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c | ||
170 | +++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c | ||
171 | @@ -132,3 +132,4 @@ __ieee754_sqrt (b) | ||
172 | } | ||
173 | return f_wash (b); | ||
174 | } | ||
175 | +strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
176 | Index: libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c | ||
177 | =================================================================== | ||
178 | --- libc.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c | ||
179 | +++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c | ||
180 | @@ -99,3 +99,4 @@ __ieee754_sqrtf (b) | ||
181 | } | ||
182 | return f_washf (b); | ||
183 | } | ||
184 | +strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ppc_slow_ieee754_sqrt.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ppc_slow_ieee754_sqrt.patch new file mode 100644 index 0000000..5b819bc --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ppc_slow_ieee754_sqrt.patch | |||
@@ -0,0 +1,365 @@ | |||
1 | __ieee754_sqrt{,f} are now inline functions and call out __slow versions | ||
2 | |||
3 | |||
4 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
5 | Upstream-Status: Pending | ||
6 | Index: git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c | ||
7 | =================================================================== | ||
8 | --- git.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 2014-08-29 10:35:02.616070587 -0700 | ||
9 | +++ git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c 2014-08-29 10:35:02.604070587 -0700 | ||
10 | @@ -40,7 +40,7 @@ | ||
11 | simultaneously. */ | ||
12 | |||
13 | double | ||
14 | -__ieee754_sqrt (double b) | ||
15 | +__slow_ieee754_sqrt (double b) | ||
16 | { | ||
17 | if (__builtin_expect (b > 0, 1)) | ||
18 | { | ||
19 | @@ -77,7 +77,7 @@ | ||
20 | |||
21 | /* Handle small numbers by scaling. */ | ||
22 | if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
23 | - return __ieee754_sqrt (b * two108) * twom54; | ||
24 | + return __slow_ieee754_sqrt (b * two108) * twom54; | ||
25 | |||
26 | #define FMADD(a_, c_, b_) \ | ||
27 | ({ double __r; \ | ||
28 | @@ -126,4 +126,12 @@ | ||
29 | } | ||
30 | return f_wash (b); | ||
31 | } | ||
32 | + | ||
33 | +#undef __ieee754_sqrt | ||
34 | +double | ||
35 | +__ieee754_sqrt (double x) | ||
36 | +{ | ||
37 | + return __slow_ieee754_sqrt (x); | ||
38 | +} | ||
39 | + | ||
40 | strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
41 | Index: git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c | ||
42 | =================================================================== | ||
43 | --- git.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 2014-08-29 10:35:02.616070587 -0700 | ||
44 | +++ git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c 2014-08-29 10:35:02.604070587 -0700 | ||
45 | @@ -38,7 +38,7 @@ | ||
46 | square root. */ | ||
47 | |||
48 | float | ||
49 | -__ieee754_sqrtf (float b) | ||
50 | +__slow_ieee754_sqrtf (float b) | ||
51 | { | ||
52 | if (__builtin_expect (b > 0, 1)) | ||
53 | { | ||
54 | @@ -93,4 +93,10 @@ | ||
55 | } | ||
56 | return f_washf (b); | ||
57 | } | ||
58 | +#undef __ieee754_sqrtf | ||
59 | +float | ||
60 | +__ieee754_sqrtf (float x) | ||
61 | +{ | ||
62 | + return __slow_ieee754_sqrtf (x); | ||
63 | +} | ||
64 | strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
65 | Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c | ||
66 | =================================================================== | ||
67 | --- git.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 2014-08-29 10:35:02.616070587 -0700 | ||
68 | +++ git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c 2014-08-29 10:35:02.604070587 -0700 | ||
69 | @@ -40,7 +40,7 @@ | ||
70 | simultaneously. */ | ||
71 | |||
72 | double | ||
73 | -__ieee754_sqrt (double b) | ||
74 | +__slow_ieee754_sqrt (double b) | ||
75 | { | ||
76 | if (__builtin_expect (b > 0, 1)) | ||
77 | { | ||
78 | @@ -77,7 +77,7 @@ | ||
79 | |||
80 | /* Handle small numbers by scaling. */ | ||
81 | if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
82 | - return __ieee754_sqrt (b * two108) * twom54; | ||
83 | + return __slow_ieee754_sqrt (b * two108) * twom54; | ||
84 | |||
85 | #define FMADD(a_, c_, b_) \ | ||
86 | ({ double __r; \ | ||
87 | @@ -126,4 +126,12 @@ | ||
88 | } | ||
89 | return f_wash (b); | ||
90 | } | ||
91 | + | ||
92 | +#undef __ieee754_sqrt | ||
93 | +double | ||
94 | +__ieee754_sqrt (double x) | ||
95 | +{ | ||
96 | + return __slow_ieee754_sqrt (x); | ||
97 | +} | ||
98 | + | ||
99 | strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
100 | Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c | ||
101 | =================================================================== | ||
102 | --- git.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 2014-08-29 10:35:02.616070587 -0700 | ||
103 | +++ git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c 2014-08-29 10:35:02.604070587 -0700 | ||
104 | @@ -38,7 +38,7 @@ | ||
105 | square root. */ | ||
106 | |||
107 | float | ||
108 | -__ieee754_sqrtf (float b) | ||
109 | +__slow_ieee754_sqrtf (float b) | ||
110 | { | ||
111 | if (__builtin_expect (b > 0, 1)) | ||
112 | { | ||
113 | @@ -93,4 +93,11 @@ | ||
114 | } | ||
115 | return f_washf (b); | ||
116 | } | ||
117 | +#undef __ieee754_sqrtf | ||
118 | +float | ||
119 | +__ieee754_sqrtf (float x) | ||
120 | +{ | ||
121 | + return __slow_ieee754_sqrtf (x); | ||
122 | +} | ||
123 | + | ||
124 | strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
125 | Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c | ||
126 | =================================================================== | ||
127 | --- git.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 2014-08-29 10:35:02.616070587 -0700 | ||
128 | +++ git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c 2014-08-29 10:35:02.604070587 -0700 | ||
129 | @@ -41,10 +41,10 @@ | ||
130 | |||
131 | #ifdef __STDC__ | ||
132 | double | ||
133 | -__ieee754_sqrt (double b) | ||
134 | +__slow_ieee754_sqrt (double b) | ||
135 | #else | ||
136 | double | ||
137 | -__ieee754_sqrt (b) | ||
138 | +__slow_ieee754_sqrt (b) | ||
139 | double b; | ||
140 | #endif | ||
141 | { | ||
142 | @@ -83,7 +83,7 @@ | ||
143 | |||
144 | /* Handle small numbers by scaling. */ | ||
145 | if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
146 | - return __ieee754_sqrt (b * two108) * twom54; | ||
147 | + return __slow_ieee754_sqrt (b * two108) * twom54; | ||
148 | |||
149 | #define FMADD(a_, c_, b_) \ | ||
150 | ({ double __r; \ | ||
151 | @@ -132,4 +132,12 @@ | ||
152 | } | ||
153 | return f_wash (b); | ||
154 | } | ||
155 | + | ||
156 | +#undef __ieee754_sqrt | ||
157 | +double | ||
158 | +__ieee754_sqrt (double x) | ||
159 | +{ | ||
160 | + return __slow_ieee754_sqrt (x); | ||
161 | +} | ||
162 | + | ||
163 | strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
164 | Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c | ||
165 | =================================================================== | ||
166 | --- git.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 2014-08-29 10:35:02.616070587 -0700 | ||
167 | +++ git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c 2014-08-29 10:35:02.604070587 -0700 | ||
168 | @@ -39,10 +39,10 @@ | ||
169 | |||
170 | #ifdef __STDC__ | ||
171 | float | ||
172 | -__ieee754_sqrtf (float b) | ||
173 | +__slow_ieee754_sqrtf (float b) | ||
174 | #else | ||
175 | float | ||
176 | -__ieee754_sqrtf (b) | ||
177 | +__slow_ieee754_sqrtf (b) | ||
178 | float b; | ||
179 | #endif | ||
180 | { | ||
181 | @@ -99,4 +99,12 @@ | ||
182 | } | ||
183 | return f_washf (b); | ||
184 | } | ||
185 | + | ||
186 | +#undef __ieee754_sqrtf | ||
187 | +float | ||
188 | +__ieee754_sqrtf (float x) | ||
189 | +{ | ||
190 | + return __slow_ieee754_sqrtf (x); | ||
191 | +} | ||
192 | + | ||
193 | strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
194 | Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c | ||
195 | =================================================================== | ||
196 | --- git.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 2014-08-29 10:35:02.616070587 -0700 | ||
197 | +++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c 2014-08-29 10:35:02.608070587 -0700 | ||
198 | @@ -41,10 +41,10 @@ | ||
199 | |||
200 | #ifdef __STDC__ | ||
201 | double | ||
202 | -__ieee754_sqrt (double b) | ||
203 | +__slow_ieee754_sqrt (double b) | ||
204 | #else | ||
205 | double | ||
206 | -__ieee754_sqrt (b) | ||
207 | +__slow_ieee754_sqrt (b) | ||
208 | double b; | ||
209 | #endif | ||
210 | { | ||
211 | @@ -83,7 +83,7 @@ | ||
212 | |||
213 | /* Handle small numbers by scaling. */ | ||
214 | if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
215 | - return __ieee754_sqrt (b * two108) * twom54; | ||
216 | + return __slow_ieee754_sqrt (b * two108) * twom54; | ||
217 | |||
218 | #define FMADD(a_, c_, b_) \ | ||
219 | ({ double __r; \ | ||
220 | @@ -132,4 +132,12 @@ | ||
221 | } | ||
222 | return f_wash (b); | ||
223 | } | ||
224 | + | ||
225 | +#undef __ieee754_sqrt | ||
226 | +double | ||
227 | +__ieee754_sqrt (double x) | ||
228 | +{ | ||
229 | + return __slow_ieee754_sqrt (x); | ||
230 | +} | ||
231 | + | ||
232 | strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
233 | Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c | ||
234 | =================================================================== | ||
235 | --- git.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 2014-08-29 10:35:02.616070587 -0700 | ||
236 | +++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c 2014-08-29 10:35:02.608070587 -0700 | ||
237 | @@ -39,10 +39,10 @@ | ||
238 | |||
239 | #ifdef __STDC__ | ||
240 | float | ||
241 | -__ieee754_sqrtf (float b) | ||
242 | +__slow_ieee754_sqrtf (float b) | ||
243 | #else | ||
244 | float | ||
245 | -__ieee754_sqrtf (b) | ||
246 | +__slow_ieee754_sqrtf (b) | ||
247 | float b; | ||
248 | #endif | ||
249 | { | ||
250 | @@ -99,4 +99,12 @@ | ||
251 | } | ||
252 | return f_washf (b); | ||
253 | } | ||
254 | + | ||
255 | +#undef __ieee754_sqrtf | ||
256 | +float | ||
257 | +__ieee754_sqrtf (float x) | ||
258 | +{ | ||
259 | + return __slow_ieee754_sqrtf (x); | ||
260 | +} | ||
261 | + | ||
262 | strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
263 | Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c | ||
264 | =================================================================== | ||
265 | --- git.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 2014-08-29 10:35:02.616070587 -0700 | ||
266 | +++ git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c 2014-08-29 10:35:02.608070587 -0700 | ||
267 | @@ -41,10 +41,10 @@ | ||
268 | |||
269 | #ifdef __STDC__ | ||
270 | double | ||
271 | -__ieee754_sqrt (double b) | ||
272 | +__slow_ieee754_sqrt (double b) | ||
273 | #else | ||
274 | double | ||
275 | -__ieee754_sqrt (b) | ||
276 | +__slow_ieee754_sqrt (b) | ||
277 | double b; | ||
278 | #endif | ||
279 | { | ||
280 | @@ -83,7 +83,7 @@ | ||
281 | |||
282 | /* Handle small numbers by scaling. */ | ||
283 | if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
284 | - return __ieee754_sqrt (b * two108) * twom54; | ||
285 | + return __slow_ieee754_sqrt (b * two108) * twom54; | ||
286 | |||
287 | #define FMADD(a_, c_, b_) \ | ||
288 | ({ double __r; \ | ||
289 | @@ -132,4 +132,12 @@ | ||
290 | } | ||
291 | return f_wash (b); | ||
292 | } | ||
293 | + | ||
294 | +#undef __ieee754_sqrt | ||
295 | +double | ||
296 | +__ieee754_sqrt (double x) | ||
297 | +{ | ||
298 | + return __slow_ieee754_sqrt (x); | ||
299 | +} | ||
300 | + | ||
301 | strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
302 | Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c | ||
303 | =================================================================== | ||
304 | --- git.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 2014-08-29 10:35:02.616070587 -0700 | ||
305 | +++ git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c 2014-08-29 10:35:02.608070587 -0700 | ||
306 | @@ -39,10 +39,10 @@ | ||
307 | |||
308 | #ifdef __STDC__ | ||
309 | float | ||
310 | -__ieee754_sqrtf (float b) | ||
311 | +__slow_ieee754_sqrtf (float b) | ||
312 | #else | ||
313 | float | ||
314 | -__ieee754_sqrtf (b) | ||
315 | +__slow_ieee754_sqrtf (b) | ||
316 | float b; | ||
317 | #endif | ||
318 | { | ||
319 | @@ -99,4 +99,12 @@ | ||
320 | } | ||
321 | return f_washf (b); | ||
322 | } | ||
323 | + | ||
324 | +#undef __ieee754_sqrtf | ||
325 | +float | ||
326 | +__ieee754_sqrtf (float x) | ||
327 | +{ | ||
328 | + return __slow_ieee754_sqrtf (x); | ||
329 | +} | ||
330 | + | ||
331 | strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
332 | Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c | ||
333 | =================================================================== | ||
334 | --- git.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 2014-08-29 10:35:02.616070587 -0700 | ||
335 | +++ git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 2014-08-29 10:35:02.608070587 -0700 | ||
336 | @@ -132,4 +132,12 @@ | ||
337 | } | ||
338 | return f_wash (b); | ||
339 | } | ||
340 | + | ||
341 | +#undef __ieee754_sqrt | ||
342 | +double | ||
343 | +__ieee754_sqrt (double x) | ||
344 | +{ | ||
345 | + return __slow_ieee754_sqrt (x); | ||
346 | +} | ||
347 | + | ||
348 | strong_alias (__ieee754_sqrt, __sqrt_finite) | ||
349 | Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c | ||
350 | =================================================================== | ||
351 | --- git.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 2014-08-29 10:35:02.616070587 -0700 | ||
352 | +++ git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 2014-08-29 10:35:02.608070587 -0700 | ||
353 | @@ -99,4 +99,12 @@ | ||
354 | } | ||
355 | return f_washf (b); | ||
356 | } | ||
357 | + | ||
358 | +#undef __ieee754_sqrtf | ||
359 | +float | ||
360 | +__ieee754_sqrtf (float x) | ||
361 | +{ | ||
362 | + return __slow_ieee754_sqrtf (x); | ||
363 | +} | ||
364 | + | ||
365 | strong_alias (__ieee754_sqrtf, __sqrtf_finite) | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ppce6500-32b_slow_ieee754_sqrt.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ppce6500-32b_slow_ieee754_sqrt.patch new file mode 100644 index 0000000..4c6c107 --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/ppce6500-32b_slow_ieee754_sqrt.patch | |||
@@ -0,0 +1,47 @@ | |||
1 | __ieee754_sqrt{,f} are now inline functions and call out __slow versions | ||
2 | |||
3 | |||
4 | Signed-off-by: chunrong guo <B40290@freescale.com> | ||
5 | Upstream-Status: Pending | ||
6 | |||
7 | diff -rNu libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c | ||
8 | --- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 2014-04-08 04:39:58.487229887 -0500 | ||
9 | +++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c 2014-04-08 04:40:52.643069198 -0500 | ||
10 | @@ -41,10 +41,10 @@ | ||
11 | |||
12 | #ifdef __STDC__ | ||
13 | double | ||
14 | -__ieee754_sqrt (double b) | ||
15 | +__slow_ieee754_sqrt (double b) | ||
16 | #else | ||
17 | double | ||
18 | -__ieee754_sqrt (b) | ||
19 | +__slow_ieee754_sqrt (b) | ||
20 | double b; | ||
21 | #endif | ||
22 | { | ||
23 | @@ -83,7 +83,7 @@ | ||
24 | |||
25 | /* Handle small numbers by scaling. */ | ||
26 | if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0)) | ||
27 | - return __ieee754_sqrt (b * two108) * twom54; | ||
28 | + return __slow_ieee754_sqrt (b * two108) * twom54; | ||
29 | |||
30 | #define FMADD(a_, c_, b_) \ | ||
31 | ({ double __r; \ | ||
32 | diff -rNu libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c | ||
33 | --- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 2014-04-08 04:39:58.487229887 -0500 | ||
34 | +++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c 2014-04-08 04:41:26.017067682 -0500 | ||
35 | @@ -39,10 +39,10 @@ | ||
36 | |||
37 | #ifdef __STDC__ | ||
38 | float | ||
39 | -__ieee754_sqrtf (float b) | ||
40 | +__slow_ieee754_sqrtf (float b) | ||
41 | #else | ||
42 | float | ||
43 | -__ieee754_sqrtf (b) | ||
44 | +__slow_ieee754_sqrtf (b) | ||
45 | float b; | ||
46 | #endif | ||
47 | { | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/relocatable_sdk.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/relocatable_sdk.patch new file mode 100644 index 0000000..ca5f17b --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/relocatable_sdk.patch | |||
@@ -0,0 +1,108 @@ | |||
1 | Upstream-Status: Inappropriate [SDK specific] | ||
2 | |||
3 | This patch puts the dynamic loader path in the binaries, SYSTEM_DIRS strings | ||
4 | and lengths as well as ld.so.cache path in the dynamic loader to specific | ||
5 | sections in memory. The sections that contain paths have been allocated a 4096 | ||
6 | byte section, which is the maximum path length in linux. This will allow the | ||
7 | relocating script to parse the ELF binary, detect the section and easily replace | ||
8 | the strings in a certain path. | ||
9 | |||
10 | Signed-off-by: Laurentiu Palcu <laurentiu.palcu@intel.com> | ||
11 | |||
12 | Index: libc/elf/interp.c | ||
13 | =================================================================== | ||
14 | --- libc.orig/elf/interp.c | ||
15 | +++ libc/elf/interp.c | ||
16 | @@ -16,5 +16,5 @@ | ||
17 | License along with the GNU C Library; if not, see | ||
18 | <http://www.gnu.org/licenses/>. */ | ||
19 | |||
20 | -const char __invoke_dynamic_linker__[] __attribute__ ((section (".interp"))) | ||
21 | +const char __invoke_dynamic_linker__[4096] __attribute__ ((section (".interp"))) | ||
22 | = RUNTIME_LINKER; | ||
23 | Index: libc/elf/dl-load.c | ||
24 | =================================================================== | ||
25 | --- libc.orig/elf/dl-load.c | ||
26 | +++ libc/elf/dl-load.c | ||
27 | @@ -144,8 +144,8 @@ static size_t max_capstrlen attribute_re | ||
28 | /* Get the generated information about the trusted directories. */ | ||
29 | #include "trusted-dirs.h" | ||
30 | |||
31 | -static const char system_dirs[] = SYSTEM_DIRS; | ||
32 | -static const size_t system_dirs_len[] = | ||
33 | +static const char system_dirs[4096] __attribute__ ((section (".sysdirs"))) = SYSTEM_DIRS; | ||
34 | +volatile static const size_t system_dirs_len[] __attribute__ ((section (".sysdirslen"))) = | ||
35 | { | ||
36 | SYSTEM_DIRS_LEN | ||
37 | }; | ||
38 | Index: libc/elf/dl-cache.c | ||
39 | =================================================================== | ||
40 | --- libc.orig/elf/dl-cache.c | ||
41 | +++ libc/elf/dl-cache.c | ||
42 | @@ -133,6 +133,10 @@ do \ | ||
43 | while (0) | ||
44 | |||
45 | |||
46 | +const char LD_SO_CACHE[4096] __attribute__ ((section (".ldsocache"))) = | ||
47 | + SYSCONFDIR "/ld.so.cache"; | ||
48 | + | ||
49 | + | ||
50 | int | ||
51 | internal_function | ||
52 | _dl_cache_libcmp (const char *p1, const char *p2) | ||
53 | Index: libc/elf/ldconfig.c | ||
54 | =================================================================== | ||
55 | --- libc.orig/elf/ldconfig.c | ||
56 | +++ libc/elf/ldconfig.c | ||
57 | @@ -166,6 +166,9 @@ static struct argp argp = | ||
58 | options, parse_opt, NULL, doc, NULL, more_help, NULL | ||
59 | }; | ||
60 | |||
61 | + | ||
62 | +extern const char LD_SO_CACHE[4096] __attribute__ ((section (".ldsocache"))); | ||
63 | + | ||
64 | /* Check if string corresponds to an important hardware capability or | ||
65 | a platform. */ | ||
66 | static int | ||
67 | Index: libc/sysdeps/generic/dl-cache.h | ||
68 | =================================================================== | ||
69 | --- libc.orig/sysdeps/generic/dl-cache.h | ||
70 | +++ libc/sysdeps/generic/dl-cache.h | ||
71 | @@ -27,10 +27,6 @@ | ||
72 | ((flags) == 1 || (flags) == _DL_CACHE_DEFAULT_ID) | ||
73 | #endif | ||
74 | |||
75 | -#ifndef LD_SO_CACHE | ||
76 | -# define LD_SO_CACHE SYSCONFDIR "/ld.so.cache" | ||
77 | -#endif | ||
78 | - | ||
79 | #ifndef add_system_dir | ||
80 | # define add_system_dir(dir) add_dir (dir) | ||
81 | #endif | ||
82 | Index: libc/elf/rtld.c | ||
83 | =================================================================== | ||
84 | --- libc.orig/elf/rtld.c | ||
85 | +++ libc/elf/rtld.c | ||
86 | @@ -99,6 +99,7 @@ uintptr_t __pointer_chk_guard_local | ||
87 | strong_alias (__pointer_chk_guard_local, __pointer_chk_guard) | ||
88 | #endif | ||
89 | |||
90 | +extern const char LD_SO_CACHE[4096] __attribute__ ((section (".ldsocache"))); | ||
91 | |||
92 | /* List of auditing DSOs. */ | ||
93 | static struct audit_list | ||
94 | @@ -1031,12 +1032,12 @@ of this helper program; chances are you | ||
95 | --list list all dependencies and how they are resolved\n\ | ||
96 | --verify verify that given object really is a dynamically linked\n\ | ||
97 | object we can handle\n\ | ||
98 | - --inhibit-cache Do not use " LD_SO_CACHE "\n\ | ||
99 | + --inhibit-cache Do not use %s\n\ | ||
100 | --library-path PATH use given PATH instead of content of the environment\n\ | ||
101 | variable LD_LIBRARY_PATH\n\ | ||
102 | --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\ | ||
103 | in LIST\n\ | ||
104 | - --audit LIST use objects named in LIST as auditors\n"); | ||
105 | + --audit LIST use objects named in LIST as auditors\n", LD_SO_CACHE); | ||
106 | |||
107 | ++_dl_skip_args; | ||
108 | --_dl_argc; | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/relocatable_sdk_fix_openpath.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/relocatable_sdk_fix_openpath.patch new file mode 100644 index 0000000..f164f8f --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/relocatable_sdk_fix_openpath.patch | |||
@@ -0,0 +1,41 @@ | |||
1 | Upstream-Status: Inappropriate [SDK specific] | ||
2 | |||
3 | eglibc-nativesdk: Fix buffer overrun with a relocated SDK | ||
4 | |||
5 | When ld-linux-*.so.2 is relocated to a path that is longer than the | ||
6 | original fixed location, the dynamic loader will crash in open_path | ||
7 | because it implicitly assumes that max_dirnamelen is a fixed size that | ||
8 | never changes. | ||
9 | |||
10 | The allocated buffer will not be large enough to contain the directory | ||
11 | path string which is larger than the fixed location provided at build | ||
12 | time. | ||
13 | |||
14 | Signed-off-by: Jason Wessel <jason.wessel@windriver.com> | ||
15 | |||
16 | --- | ||
17 | elf/dl-load.c | 12 ++++++++++++ | ||
18 | 1 file changed, 12 insertions(+) | ||
19 | |||
20 | --- a/elf/dl-load.c | ||
21 | +++ b/elf/dl-load.c | ||
22 | @@ -1919,7 +1919,19 @@ open_path (const char *name, size_t name | ||
23 | given on the command line when rtld is run directly. */ | ||
24 | return -1; | ||
25 | |||
26 | + do | ||
27 | + { | ||
28 | + struct r_search_path_elem *this_dir = *dirs; | ||
29 | + if (this_dir->dirnamelen > max_dirnamelen) | ||
30 | + { | ||
31 | + max_dirnamelen = this_dir->dirnamelen; | ||
32 | + } | ||
33 | + } | ||
34 | + while (*++dirs != NULL); | ||
35 | + | ||
36 | buf = alloca (max_dirnamelen + max_capstrlen + namelen); | ||
37 | + | ||
38 | + dirs = sps->dirs; | ||
39 | do | ||
40 | { | ||
41 | struct r_search_path_elem *this_dir = *dirs; | ||
diff --git a/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/timezone-re-written-tzselect-as-posix-sh.patch b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/timezone-re-written-tzselect-as-posix-sh.patch new file mode 100644 index 0000000..55547de --- /dev/null +++ b/meta-linaro-toolchain/recipes-core/glibc/glibc-linaro-2.20/timezone-re-written-tzselect-as-posix-sh.patch | |||
@@ -0,0 +1,38 @@ | |||
1 | timezone: re-written tzselect as posix sh | ||
2 | |||
3 | To avoid the bash dependency. | ||
4 | |||
5 | Upstream-Status: Pending | ||
6 | |||
7 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
8 | --- | ||
9 | timezone/Makefile | 2 +- | ||
10 | timezone/tzselect.ksh | 2 +- | ||
11 | 2 files changed, 2 insertions(+), 2 deletions(-) | ||
12 | |||
13 | Index: git/timezone/Makefile | ||
14 | =================================================================== | ||
15 | --- git.orig/timezone/Makefile 2014-08-27 05:35:58.008070587 +0000 | ||
16 | +++ git/timezone/Makefile 2014-08-27 05:36:37.908070587 +0000 | ||
17 | @@ -114,7 +114,7 @@ | ||
18 | |||
19 | |||
20 | $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make | ||
21 | - sed -e 's|/bin/bash|$(BASH)|' \ | ||
22 | + sed -e 's|/bin/bash|/bin/sh|' \ | ||
23 | -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \ | ||
24 | -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \ | ||
25 | -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \ | ||
26 | Index: git/timezone/tzselect.ksh | ||
27 | =================================================================== | ||
28 | --- git.orig/timezone/tzselect.ksh 2014-08-27 05:35:58.008070587 +0000 | ||
29 | +++ git/timezone/tzselect.ksh 2014-08-27 05:35:58.000070587 +0000 | ||
30 | @@ -35,7 +35,7 @@ | ||
31 | |||
32 | # Specify default values for environment variables if they are unset. | ||
33 | : ${AWK=awk} | ||
34 | -: ${TZDIR=`pwd`} | ||
35 | +: ${TZDIR=$(pwd)} | ||
36 | |||
37 | # Check for awk Posix compliance. | ||
38 | ($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1 | ||