summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/glibc/glibc/eglibc-use-option-groups.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/glibc/glibc/eglibc-use-option-groups.patch')
-rw-r--r--meta/recipes-core/glibc/glibc/eglibc-use-option-groups.patch16631
1 files changed, 16631 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/eglibc-use-option-groups.patch b/meta/recipes-core/glibc/glibc/eglibc-use-option-groups.patch
new file mode 100644
index 0000000000..f53a8994fc
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/eglibc-use-option-groups.patch
@@ -0,0 +1,16631 @@
1Forward port eglibc options groups support
2
3Upstream-Status: Pending
4
5Index: 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
67Index: 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)
107Index: 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
124Index: 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
137Index: 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
172Index: 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
228Index: 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
284Index: 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
297Index: 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)
376Index: 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. */
404Index: 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)
464Index: 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 \
488Index: 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;
510Index: 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
587Index: 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
611Index: 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
634Index: 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
655Index: 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;
679Index: 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)
707Index: 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 {
737Index: 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
760Index: 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
845Index: 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); \
860Index: 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
913Index: 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
994Index: 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 \
1015Index: 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
1078Index: 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
1101Index: 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
1130Index: 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
1172Index: 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))
1185Index: 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
1233Index: 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);
1246Index: 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);
1259Index: 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)
1284Index: 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, \
1321Index: 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
1437Index: 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)
1603Index: 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+ };
1656Index: 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 */
1703Index: 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)
1741Index: 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
1754Index: 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) \
1823Index: 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 *));
1880Index: 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
1929Index: 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 }
2011Index: 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
2055Index: 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
2124Index: 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
2137Index: 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;
2183Index: 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. */
2206Index: 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 */
2269Index: 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
2310Index: 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 */
2369Index: 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.
2466Index: 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
2511Index: 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.
2549Index: 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))
2579Index: 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
2617Index: 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;
2642Index: 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
2655Index: 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 \
2679Index: 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 {
2739Index: 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
2769Index: 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)
2839Index: 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. */
2859Index: 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
2872Index: 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
2948Index: 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
3038Index: 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
3072Index: 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
3138Index: 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"
3146Index: 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
3173Index: 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)
3299Index: 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+}
4107Index: 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 }
4223Index: 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
4287Index: 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))
4391Index: 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 */
4681Index: 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
4718Index: 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 (&regex, '\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
4740Index: 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 },
4766Index: 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
4790Index: 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
4861Index: 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)
4926Index: 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
5096Index: 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. */
5469Index: 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 */
5666Index: 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
5710Index: 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
5765Index: 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);
5954Index: 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 }
6016Index: 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 ? &regs : (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
14233Index: 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
14246Index: 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
14298Index: 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);
14328Index: 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
14360Index: 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
14430Index: 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
14500Index: 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. */
14542Index: 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. */
14569Index: 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
14597Index: 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 }
14641Index: 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 {
14668Index: 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
14695Index: 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,
14778Index: 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 ();
14927Index: 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
15020Index: 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;
15058Index: 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 */
15093Index: 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
15113Index: 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
15156Index: 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;
15180Index: 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
15207Index: 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;
15231Index: 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
15270Index: 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 }
15298Index: 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 }
15321Index: 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)
15415Index: 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)
15443Index: 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
15457Index: git/sysdeps/ieee754/dbl-64/s_sin.c
15458===================================================================
15459--- git.orig/sysdeps/ieee754/dbl-64/s_sin.c 2014-08-29 20:00:54.260070587 -0700
15460+++ git/sysdeps/ieee754/dbl-64/s_sin.c 2014-08-29 20:01:15.240070587 -0700
15461@@ -447,21 +447,19 @@
15462 }
15463 else
15464 {
15465- double t;
15466 if (a > 0)
15467 {
15468 m = 1;
15469- t = a;
15470 db = da;
15471 }
15472 else
15473 {
15474 m = 0;
15475- t = -a;
15476+ a = -a;
15477 db = -da;
15478 }
15479- u.x = big + t;
15480- y = t - (u.x - big);
15481+ u.x = big + a;
15482+ y = a - (u.x - big);
15483 res = do_sin (u, y, db, &cor);
15484 cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
15485 retval = ((res == res + cor) ? ((m) ? res : -res)
15486@@ -673,21 +671,19 @@
15487 }
15488 else
15489 {
15490- double t;
15491 if (a > 0)
15492 {
15493 m = 1;
15494- t = a;
15495 db = da;
15496 }
15497 else
15498 {
15499 m = 0;
15500- t = -a;
15501+ a = -a;
15502 db = -da;
15503 }
15504- u.x = big + t;
15505- y = t - (u.x - big);
15506+ u.x = big + a;
15507+ y = a - (u.x - big);
15508 res = do_sin (u, y, db, &cor);
15509 cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
15510 retval = ((res == res + cor) ? ((m) ? res : -res)
15511Index: git/sysdeps/ieee754/ldbl-opt/Makefile
15512===================================================================
15513--- git.orig/sysdeps/ieee754/ldbl-opt/Makefile 2014-08-29 20:00:54.452070587 -0700
15514+++ git/sysdeps/ieee754/ldbl-opt/Makefile 2014-08-29 20:01:15.244070587 -0700
15515@@ -11,19 +11,18 @@
15516 routines += math_ldbl_opt nldbl-compat
15517
15518 extra-libs += libnldbl
15519-libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
15520+libnldbl-calls = asprintf dprintf fprintf fscanf iovfscanf \
15521 obstack_printf obstack_vprintf printf scanf snprintf \
15522- sprintf sscanf swprintf swscanf vasprintf vdprintf vfprintf \
15523- vfscanf vfwprintf vfwscanf vprintf vscanf vsnprintf \
15524- vsprintf vsscanf vswprintf vswscanf vwprintf vwscanf \
15525- wprintf wscanf printf_fp printf_size \
15526- fprintf_chk fwprintf_chk printf_chk snprintf_chk sprintf_chk \
15527- swprintf_chk vfprintf_chk vfwprintf_chk vprintf_chk \
15528- vsnprintf_chk vsprintf_chk vswprintf_chk vwprintf_chk \
15529- wprintf_chk asprintf_chk vasprintf_chk dprintf_chk \
15530+ sprintf sscanf vasprintf vdprintf vfprintf \
15531+ vfscanf vprintf vscanf vsnprintf \
15532+ vsprintf vsscanf \
15533+ printf_fp printf_size \
15534+ fprintf_chk printf_chk snprintf_chk sprintf_chk \
15535+ vfprintf_chk vprintf_chk \
15536+ vsnprintf_chk vsprintf_chk \
15537+ asprintf_chk vasprintf_chk dprintf_chk \
15538 vdprintf_chk obstack_printf_chk obstack_vprintf_chk \
15539 syslog syslog_chk vsyslog vsyslog_chk \
15540- strfmon strfmon_l \
15541 strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \
15542 qecvt qfcvt qgcvt qecvt_r qfcvt_r \
15543 isinf isnan finite signbit scalb log2 lgamma_r ceil \
15544@@ -38,9 +37,15 @@
15545 casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \
15546 cabs carg cimag creal clog10 \
15547 isoc99_scanf isoc99_fscanf isoc99_sscanf \
15548- isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
15549+ isoc99_vscanf isoc99_vfscanf isoc99_vsscanf
15550+libnldbl-calls-$(OPTION_EGLIBC_LOCALE_CODE) += strfmon strfmon_l
15551+libnldbl-calls-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += fwprintf fwscanf \
15552+ swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf \
15553+ vwprintf vwscanf wprintf wscanf fwprintf_chk swprintf_chk \
15554+ vfwprintf_chk vswprintf_chk vwprintf_chk wprintf_chk \
15555 isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
15556 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf
15557+libnldbl-calls += $(libnldbl-calls-y)
15558 libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
15559 libnldbl-inhibit-o = $(object-suffixes)
15560 libnldbl-static-only-routines = $(libnldbl-routines)
15561Index: git/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
15562===================================================================
15563--- git.orig/sysdeps/ieee754/ldbl-opt/nldbl-compat.c 2014-08-29 20:00:54.468070587 -0700
15564+++ git/sysdeps/ieee754/ldbl-opt/nldbl-compat.c 2014-08-29 20:01:15.244070587 -0700
15565@@ -26,6 +26,7 @@
15566 #include <locale/localeinfo.h>
15567 #include <sys/syslog.h>
15568 #include <bits/libc-lock.h>
15569+#include <gnu/option-groups.h>
15570
15571 #include "nldbl-compat.h"
15572
15573@@ -33,20 +34,14 @@
15574 libc_hidden_proto (__nldbl_vsscanf)
15575 libc_hidden_proto (__nldbl_vsprintf)
15576 libc_hidden_proto (__nldbl_vfscanf)
15577-libc_hidden_proto (__nldbl_vfwscanf)
15578 libc_hidden_proto (__nldbl_vdprintf)
15579-libc_hidden_proto (__nldbl_vswscanf)
15580-libc_hidden_proto (__nldbl_vfwprintf)
15581-libc_hidden_proto (__nldbl_vswprintf)
15582 libc_hidden_proto (__nldbl_vsnprintf)
15583 libc_hidden_proto (__nldbl_vasprintf)
15584 libc_hidden_proto (__nldbl_obstack_vprintf)
15585-libc_hidden_proto (__nldbl___vfwprintf_chk)
15586 libc_hidden_proto (__nldbl___vsnprintf_chk)
15587 libc_hidden_proto (__nldbl___vfprintf_chk)
15588 libc_hidden_proto (__nldbl___vsyslog_chk)
15589 libc_hidden_proto (__nldbl___vsprintf_chk)
15590-libc_hidden_proto (__nldbl___vswprintf_chk)
15591 libc_hidden_proto (__nldbl___vasprintf_chk)
15592 libc_hidden_proto (__nldbl___vdprintf_chk)
15593 libc_hidden_proto (__nldbl___obstack_vprintf_chk)
15594@@ -54,8 +49,17 @@
15595 libc_hidden_proto (__nldbl___vstrfmon_l)
15596 libc_hidden_proto (__nldbl___isoc99_vsscanf)
15597 libc_hidden_proto (__nldbl___isoc99_vfscanf)
15598+
15599+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15600+libc_hidden_proto (__nldbl_vfwscanf)
15601+libc_hidden_proto (__nldbl_vswscanf)
15602+libc_hidden_proto (__nldbl_vfwprintf)
15603+libc_hidden_proto (__nldbl_vswprintf)
15604+libc_hidden_proto (__nldbl___vfwprintf_chk)
15605+libc_hidden_proto (__nldbl___vswprintf_chk)
15606 libc_hidden_proto (__nldbl___isoc99_vswscanf)
15607 libc_hidden_proto (__nldbl___isoc99_vfwscanf)
15608+#endif
15609
15610 static void
15611 __nldbl_cleanup (void *arg)
15612@@ -117,6 +121,7 @@
15613 }
15614 weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf)
15615
15616+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15617 int
15618 attribute_compat_text_section weak_function
15619 __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...)
15620@@ -130,6 +135,7 @@
15621
15622 return done;
15623 }
15624+#endif
15625
15626 int
15627 attribute_compat_text_section
15628@@ -226,6 +232,7 @@
15629 return done;
15630 }
15631
15632+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15633 int
15634 attribute_compat_text_section
15635 __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
15636@@ -239,6 +246,7 @@
15637
15638 return done;
15639 }
15640+#endif
15641
15642 int
15643 attribute_compat_text_section weak_function
15644@@ -264,6 +272,7 @@
15645 }
15646 libc_hidden_def (__nldbl_vdprintf)
15647
15648+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15649 int
15650 attribute_compat_text_section weak_function
15651 __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
15652@@ -275,6 +284,7 @@
15653 return res;
15654 }
15655 libc_hidden_def (__nldbl_vfwprintf)
15656+#endif
15657
15658 int
15659 attribute_compat_text_section
15660@@ -297,6 +307,7 @@
15661 libc_hidden_def (__nldbl_vsnprintf)
15662 weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf)
15663
15664+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15665 int
15666 attribute_compat_text_section weak_function
15667 __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt,
15668@@ -330,6 +341,7 @@
15669
15670 return done;
15671 }
15672+#endif
15673
15674 int
15675 attribute_compat_text_section
15676@@ -419,6 +431,7 @@
15677 return done;
15678 }
15679
15680+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15681 int
15682 attribute_compat_text_section
15683 __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
15684@@ -491,6 +504,7 @@
15685
15686 return done;
15687 }
15688+#endif
15689
15690 int
15691 attribute_compat_text_section
15692@@ -506,6 +520,7 @@
15693 return done;
15694 }
15695
15696+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15697 int
15698 attribute_compat_text_section
15699 __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
15700@@ -519,6 +534,7 @@
15701
15702 return done;
15703 }
15704+#endif
15705
15706 int
15707 attribute_compat_text_section
15708@@ -563,6 +579,7 @@
15709 return done;
15710 }
15711
15712+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15713 int
15714 attribute_compat_text_section
15715 __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
15716@@ -577,6 +594,7 @@
15717
15718 return done;
15719 }
15720+#endif
15721
15722 int
15723 attribute_compat_text_section
15724@@ -590,6 +608,7 @@
15725 }
15726 libc_hidden_def (__nldbl___vfprintf_chk)
15727
15728+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15729 int
15730 attribute_compat_text_section
15731 __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
15732@@ -601,6 +620,7 @@
15733 return res;
15734 }
15735 libc_hidden_def (__nldbl___vfwprintf_chk)
15736+#endif
15737
15738 int
15739 attribute_compat_text_section
15740@@ -635,6 +655,7 @@
15741 }
15742 libc_hidden_def (__nldbl___vsprintf_chk)
15743
15744+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15745 int
15746 attribute_compat_text_section
15747 __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen,
15748@@ -668,6 +689,7 @@
15749
15750 return done;
15751 }
15752+#endif
15753
15754 int
15755 attribute_compat_text_section
15756@@ -775,6 +797,7 @@
15757 return ___printf_fp (fp, &info_no_ldbl, args);
15758 }
15759
15760+#if __OPTION_EGLIBC_LOCALE_CODE
15761 ssize_t
15762 attribute_compat_text_section
15763 __nldbl_strfmon (char *s, size_t maxsize, const char *format, ...)
15764@@ -829,6 +852,7 @@
15765 return res;
15766 }
15767 libc_hidden_def (__nldbl___vstrfmon_l)
15768+#endif
15769
15770 void
15771 attribute_compat_text_section
15772@@ -941,6 +965,7 @@
15773 return done;
15774 }
15775
15776+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15777 int
15778 attribute_compat_text_section
15779 __nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
15780@@ -1014,6 +1039,7 @@
15781
15782 return done;
15783 }
15784+#endif
15785
15786 #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
15787 compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0);
15788@@ -1057,6 +1083,7 @@
15789 compat_symbol (libc, __nldbl___strfmon_l, __strfmon_l, GLIBC_2_1);
15790 #endif
15791 #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_2)
15792+# ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15793 compat_symbol (libc, __nldbl_swprintf, swprintf, GLIBC_2_2);
15794 compat_symbol (libc, __nldbl_vwprintf, vwprintf, GLIBC_2_2);
15795 compat_symbol (libc, __nldbl_wprintf, wprintf, GLIBC_2_2);
15796@@ -1069,6 +1096,7 @@
15797 compat_symbol (libc, __nldbl_vswscanf, vswscanf, GLIBC_2_2);
15798 compat_symbol (libc, __nldbl_vwscanf, vwscanf, GLIBC_2_2);
15799 compat_symbol (libc, __nldbl_wscanf, wscanf, GLIBC_2_2);
15800+# endif
15801 #endif
15802 #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3)
15803 compat_symbol (libc, __nldbl_strfmon_l, strfmon_l, GLIBC_2_3);
15804Index: git/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
15805===================================================================
15806--- git.orig/sysdeps/ieee754/ldbl-opt/nldbl-compat.h 2014-08-29 20:00:54.468070587 -0700
15807+++ git/sysdeps/ieee754/ldbl-opt/nldbl-compat.h 2014-08-29 20:01:15.244070587 -0700
15808@@ -30,6 +30,7 @@
15809 #include <math.h>
15810 #include <monetary.h>
15811 #include <sys/syslog.h>
15812+#include <gnu/option-groups.h>
15813
15814
15815 /* Declare the __nldbl_NAME function the wrappers call that's in libc.so. */
15816@@ -37,19 +38,15 @@
15817
15818 NLDBL_DECL (_IO_vfscanf);
15819 NLDBL_DECL (vfscanf);
15820-NLDBL_DECL (vfwscanf);
15821 NLDBL_DECL (obstack_vprintf);
15822 NLDBL_DECL (vasprintf);
15823 NLDBL_DECL (dprintf);
15824 NLDBL_DECL (vdprintf);
15825 NLDBL_DECL (fprintf);
15826 NLDBL_DECL (vfprintf);
15827-NLDBL_DECL (vfwprintf);
15828 NLDBL_DECL (vsnprintf);
15829 NLDBL_DECL (vsprintf);
15830 NLDBL_DECL (vsscanf);
15831-NLDBL_DECL (vswprintf);
15832-NLDBL_DECL (vswscanf);
15833 NLDBL_DECL (__asprintf);
15834 NLDBL_DECL (asprintf);
15835 NLDBL_DECL (__printf_fp);
15836@@ -66,12 +63,18 @@
15837 NLDBL_DECL (__isoc99_vscanf);
15838 NLDBL_DECL (__isoc99_vfscanf);
15839 NLDBL_DECL (__isoc99_vsscanf);
15840+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15841+NLDBL_DECL (vfwscanf);
15842+NLDBL_DECL (vfwprintf);
15843+NLDBL_DECL (vswprintf);
15844+NLDBL_DECL (vswscanf);
15845 NLDBL_DECL (__isoc99_wscanf);
15846 NLDBL_DECL (__isoc99_fwscanf);
15847 NLDBL_DECL (__isoc99_swscanf);
15848 NLDBL_DECL (__isoc99_vwscanf);
15849 NLDBL_DECL (__isoc99_vfwscanf);
15850 NLDBL_DECL (__isoc99_vswscanf);
15851+#endif
15852
15853 /* This one does not exist in the normal interface, only
15854 __nldbl___vstrfmon really exists. */
15855@@ -82,22 +85,23 @@
15856 since we don't compile with _FORTIFY_SOURCE. */
15857 extern int __nldbl___vfprintf_chk (FILE *__restrict, int,
15858 const char *__restrict, _G_va_list);
15859-extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
15860- const wchar_t *__restrict, __gnuc_va_list);
15861 extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t,
15862 const char *__restrict, _G_va_list) __THROW;
15863 extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t,
15864 const char *__restrict, _G_va_list)
15865 __THROW;
15866-extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
15867- const wchar_t *__restrict, __gnuc_va_list)
15868- __THROW;
15869 extern int __nldbl___vasprintf_chk (char **, int, const char *, _G_va_list)
15870 __THROW;
15871 extern int __nldbl___vdprintf_chk (int, int, const char *, _G_va_list);
15872 extern int __nldbl___obstack_vprintf_chk (struct obstack *, int, const char *,
15873 _G_va_list) __THROW;
15874 extern void __nldbl___vsyslog_chk (int, int, const char *, va_list);
15875-
15876+#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15877+extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
15878+ const wchar_t *__restrict, __gnuc_va_list);
15879+extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
15880+ const wchar_t *__restrict, __gnuc_va_list)
15881+ __THROW;
15882+#endif
15883
15884 #endif /* __NLDBL_COMPAT_H */
15885Index: git/sysdeps/unix/sysv/linux/gethostid.c
15886===================================================================
15887--- git.orig/sysdeps/unix/sysv/linux/gethostid.c 2014-08-29 20:00:58.840070587 -0700
15888+++ git/sysdeps/unix/sysv/linux/gethostid.c 2014-08-29 20:01:15.244070587 -0700
15889@@ -21,6 +21,7 @@
15890 #include <unistd.h>
15891 #include <netdb.h>
15892 #include <not-cancel.h>
15893+#include <gnu/option-groups.h>
15894
15895 #define HOSTIDFILE "/etc/hostid"
15896
15897@@ -89,6 +90,7 @@
15898 return id;
15899 }
15900
15901+#if __OPTION_EGLIBC_INET
15902 /* Getting from the file was not successful. An intelligent guess for
15903 a unique number of a host is its IP address. Return this. */
15904 if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0')
15905@@ -115,5 +117,9 @@
15906 /* For the return value to be not exactly the IP address we do some
15907 bit fiddling. */
15908 return (int32_t) (in.s_addr << 16 | in.s_addr >> 16);
15909+#else
15910+ /* Return an arbitrary value. */
15911+ return 0;
15912+#endif
15913 }
15914 #endif
15915Index: git/sysdeps/unix/sysv/linux/libc_fatal.c
15916===================================================================
15917--- git.orig/sysdeps/unix/sysv/linux/libc_fatal.c 2014-08-29 20:00:58.980070587 -0700
15918+++ git/sysdeps/unix/sysv/linux/libc_fatal.c 2014-08-29 20:01:15.244070587 -0700
15919@@ -23,6 +23,7 @@
15920 #include <string.h>
15921 #include <sys/mman.h>
15922 #include <sys/uio.h>
15923+#include <gnu/option-groups.h>
15924
15925 static bool
15926 writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
15927@@ -40,6 +41,7 @@
15928 static void
15929 backtrace_and_maps (int do_abort, bool written, int fd)
15930 {
15931+#if __OPTION_EGLIBC_BACKTRACE
15932 if (do_abort > 1 && written)
15933 {
15934 void *addrs[64];
15935@@ -62,6 +64,7 @@
15936 close_not_cancel_no_status (fd2);
15937 }
15938 }
15939+#endif /* __OPTION_EGLIBC_BACKTRACE */
15940 }
15941 #define BEFORE_ABORT backtrace_and_maps
15942
15943Index: git/time/Makefile
15944===================================================================
15945--- git.orig/time/Makefile 2014-08-29 20:00:59.504070587 -0700
15946+++ git/time/Makefile 2014-08-29 20:01:15.244070587 -0700
15947@@ -18,6 +18,8 @@
15948 #
15949 # Makefile for time routines
15950 #
15951+include ../option-groups.mak
15952+
15953 subdir := time
15954
15955 include ../Makeconfig
15956@@ -30,14 +32,20 @@
15957 tzfile getitimer setitimer \
15958 stime dysize timegm ftime \
15959 getdate strptime strptime_l \
15960- strftime wcsftime strftime_l wcsftime_l \
15961+ strftime strftime_l \
15962 timespec_get
15963-aux := era alt_digit lc-time-cleanup
15964+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
15965+ := wcsftime wcsftime_l
15966+aux-$(OPTION_EGLIBC_LOCALE_CODE) += alt_digit era lc-time-cleanup
15967
15968-tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
15969- tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
15970+tests := test_time clocktest tst-posixtz \
15971+ tst-getdate tst-mktime tst-mktime2 tst-strftime \
15972 tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
15973 tst-strptime3 bug-getdate1 tst-strptime-whitespace
15974+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
15975+ += tst-strptime tst-ftime_l
15976+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
15977+ += tst_wcsftime
15978
15979 include ../Rules
15980
15981Index: git/time/strftime_l.c
15982===================================================================
15983--- git.orig/time/strftime_l.c 2014-08-29 20:00:59.528070587 -0700
15984+++ git/time/strftime_l.c 2014-08-29 20:01:15.244070587 -0700
15985@@ -35,6 +35,10 @@
15986 # include "../locale/localeinfo.h"
15987 #endif
15988
15989+#ifdef _LIBC
15990+# include <gnu/option-groups.h>
15991+#endif
15992+
15993 #if defined emacs && !defined HAVE_BCOPY
15994 # define HAVE_MEMCPY 1
15995 #endif
15996@@ -882,7 +886,7 @@
15997 case L_('C'):
15998 if (modifier == L_('E'))
15999 {
16000-#if HAVE_STRUCT_ERA_ENTRY
16001+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
16002 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
16003 if (era)
16004 {
16005@@ -955,7 +959,7 @@
16006
16007 if (modifier == L_('O') && 0 <= number_value)
16008 {
16009-#ifdef _NL_CURRENT
16010+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
16011 /* Get the locale specific alternate representation of
16012 the number NUMBER_VALUE. If none exist NULL is returned. */
16013 const CHAR_T *cp = nl_get_alt_digit (number_value
16014@@ -1260,7 +1264,7 @@
16015 case L_('Y'):
16016 if (modifier == 'E')
16017 {
16018-#if HAVE_STRUCT_ERA_ENTRY
16019+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
16020 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
16021 if (era)
16022 {
16023@@ -1285,7 +1289,7 @@
16024 case L_('y'):
16025 if (modifier == L_('E'))
16026 {
16027-#if HAVE_STRUCT_ERA_ENTRY
16028+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
16029 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
16030 if (era)
16031 {
16032Index: git/time/strptime_l.c
16033===================================================================
16034--- git.orig/time/strptime_l.c 2014-08-29 20:00:59.528070587 -0700
16035+++ git/time/strptime_l.c 2014-08-29 20:01:15.244070587 -0700
16036@@ -29,6 +29,7 @@
16037
16038 #ifdef _LIBC
16039 # define HAVE_LOCALTIME_R 0
16040+# include <gnu/option-groups.h>
16041 # include "../locale/localeinfo.h"
16042 #endif
16043
16044@@ -84,7 +85,7 @@
16045 if (val < from || val > to) \
16046 return NULL; \
16047 } while (0)
16048-#ifdef _NL_CURRENT
16049+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
16050 # define get_alt_number(from, to, n) \
16051 ({ \
16052 __label__ do_normal; \
16053@@ -820,6 +821,7 @@
16054 s.want_xday = 1;
16055 break;
16056 case 'C':
16057+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16058 if (s.decided != raw)
16059 {
16060 if (s.era_cnt >= 0)
16061@@ -856,10 +858,12 @@
16062
16063 s.decided = raw;
16064 }
16065+#endif
16066 /* The C locale has no era information, so use the
16067 normal representation. */
16068 goto match_century;
16069 case 'y':
16070+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16071 if (s.decided != raw)
16072 {
16073 get_number(0, 9999, 4);
16074@@ -918,9 +922,10 @@
16075
16076 s.decided = raw;
16077 }
16078-
16079+#endif
16080 goto match_year_in_century;
16081 case 'Y':
16082+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16083 if (s.decided != raw)
16084 {
16085 num_eras = _NL_CURRENT_WORD (LC_TIME,
16086@@ -948,6 +953,7 @@
16087
16088 s.decided = raw;
16089 }
16090+#endif
16091 get_number (0, 9999, 4);
16092 tm->tm_year = val - 1900;
16093 s.want_century = 0;
16094@@ -1118,6 +1124,7 @@
16095 tm->tm_year = (s.century - 19) * 100;
16096 }
16097
16098+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16099 if (s.era_cnt != -1)
16100 {
16101 era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);
16102@@ -1132,6 +1139,7 @@
16103 tm->tm_year = era->start_date[0];
16104 }
16105 else
16106+#endif
16107 if (s.want_era)
16108 {
16109 /* No era found but we have seen an E modifier. Rectify some
16110Index: git/timezone/Makefile
16111===================================================================
16112--- git.orig/timezone/Makefile 2014-08-29 20:01:14.044070587 -0700
16113+++ git/timezone/Makefile 2014-08-29 20:01:15.244070587 -0700
16114@@ -115,7 +115,7 @@
16115
16116 $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
16117 sed -e 's|/bin/bash|/bin/sh|' \
16118- -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
16119+ -e '/TZDIR=/s|\$$(pwd)|$(zonedir)|' \
16120 -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
16121 -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \
16122 -e '/REPORT_BUGS_TO=/s|=.*|="$(REPORT_BUGS_TO)"|' \
16123Index: git/wcsmbs/Makefile
16124===================================================================
16125--- git.orig/wcsmbs/Makefile 2014-08-29 20:00:59.548070587 -0700
16126+++ git/wcsmbs/Makefile 2014-08-29 20:01:15.244070587 -0700
16127@@ -18,15 +18,21 @@
16128 #
16129 # Sub-makefile for wcsmbs portion of the library.
16130 #
16131+include ../option-groups.mak
16132+
16133 subdir := wcsmbs
16134
16135 include ../Makeconfig
16136
16137 headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h
16138
16139-routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
16140+# These functions are used by printf_fp.c, even in the plain case; see
16141+# comments there for OPTION_EGLIBC_LOCALE_CODE.
16142+routines := wmemcpy wmemset
16143+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16144+ := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
16145 wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
16146- wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy wmempcpy \
16147+ wmemcmp wmemmove wcpcpy wcpncpy wmempcpy \
16148 btowc wctob mbsinit \
16149 mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
16150 mbsnrtowcs wcsnrtombs wcsnlen wcschrnul \
16151@@ -38,14 +44,19 @@
16152 wcscoll_l wcsxfrm_l \
16153 wcscasecmp wcsncase wcscasecmp_l wcsncase_l \
16154 wcsmbsload mbsrtowcs_l \
16155- isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
16156 isoc99_swscanf isoc99_vswscanf \
16157 mbrtoc16 c16rtomb
16158+routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
16159+ += isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf
16160
16161 strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy
16162-tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
16163- tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
16164- tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests))
16165+tests := tst-wchar-h
16166+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
16167+ += tst-btowc tst-mbrtowc tst-mbrtowc2 tst-wcrtomb tst-c16c32-1
16168+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16169+ += tst-wcstof wcsmbs-tst1 tst-wcsnlen \
16170+ tst-wcpncpy tst-mbsrtowcs \
16171+ wcsatcliff $(addprefix test-,$(strop-tests))
16172 tests-ifunc := $(strop-tests:%=test-%-ifunc)
16173 tests += $(tests-ifunc)
16174
16175Index: git/wcsmbs/wcsmbsload.c
16176===================================================================
16177--- git.orig/wcsmbs/wcsmbsload.c 2014-08-29 20:00:59.580070587 -0700
16178+++ git/wcsmbs/wcsmbsload.c 2014-08-29 20:01:15.248070587 -0700
16179@@ -21,6 +21,7 @@
16180 #include <limits.h>
16181 #include <stdlib.h>
16182 #include <string.h>
16183+#include <gnu/option-groups.h>
16184
16185 #include <locale/localeinfo.h>
16186 #include <wcsmbsload.h>
16187@@ -143,6 +144,7 @@
16188 })
16189
16190
16191+#if __OPTION_EGLIBC_LOCALE_CODE
16192 /* Some of the functions here must not be used while setlocale is called. */
16193 __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
16194
16195@@ -211,6 +213,17 @@
16196
16197 __libc_rwlock_unlock (__libc_setlocale_lock);
16198 }
16199+#else
16200+void
16201+internal_function
16202+__wcsmbs_load_conv (struct __locale_data *new_category)
16203+{
16204+ /* When OPTION_EGLIBC_LOCALE_CODE is disabled, we should never reach
16205+ this point: there is no way to change locales, so every locale
16206+ passed to get_gconv_fcts should be _nl_C_LC_CTYPE. */
16207+ abort ();
16208+}
16209+#endif
16210
16211
16212 /* Clone the current conversion function set. */
16213Index: git/wctype/Makefile
16214===================================================================
16215--- git.orig/wctype/Makefile 2014-08-29 20:00:59.584070587 -0700
16216+++ git/wctype/Makefile 2014-08-29 20:01:15.248070587 -0700
16217@@ -18,14 +18,20 @@
16218 #
16219 # Sub-makefile for wctype portion of the library.
16220 #
16221+include ../option-groups.mak
16222+
16223 subdir := wctype
16224
16225 include ../Makeconfig
16226
16227 headers := wctype.h
16228-routines := wcfuncs wctype iswctype wctrans towctrans \
16229- wcfuncs_l wctype_l iswctype_l wctrans_l towctrans_l
16230+routines := wctrans towctrans towctrans_l
16231+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16232+ := wcfuncs wctype iswctype \
16233+ wcfuncs_l wctype_l iswctype_l wctrans_l
16234
16235-tests := test_wctype test_wcfuncs bug-wctypeh
16236+tests :=
16237+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16238+ += test_wctype test_wcfuncs bug-wctypeh
16239
16240 include ../Rules
16241Index: git/sysdeps/nptl/Makefile
16242===================================================================
16243--- git.orig/sysdeps/nptl/Makefile 2014-08-29 20:00:58.036070587 -0700
16244+++ git/sysdeps/nptl/Makefile 2014-08-29 20:01:15.248070587 -0700
16245@@ -18,6 +18,9 @@
16246
16247 ifeq ($(subdir),nptl)
16248 libpthread-sysdep_routines += errno-loc
16249+ifeq ($(OPTION_EGLIBC_BIG_MACROS),n)
16250+sysdep_routines += small-macros-fns
16251+endif
16252 endif
16253
16254 ifeq ($(subdir),rt)
16255Index: git/sysdeps/nptl/bits/libc-lock.h
16256===================================================================
16257--- git.orig/sysdeps/nptl/bits/libc-lock.h 2014-08-29 20:00:58.036070587 -0700
16258+++ git/sysdeps/nptl/bits/libc-lock.h 2014-08-29 20:01:15.248070587 -0700
16259@@ -24,6 +24,14 @@
16260 #include <stddef.h>
16261
16262
16263+#ifdef _LIBC
16264+# include <lowlevellock.h>
16265+# include <tls.h>
16266+# include <pthread-functions.h>
16267+# include <errno.h> /* For EBUSY. */
16268+# include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */
16269+#endif
16270+
16271 /* Mutex type. */
16272 #if defined _LIBC || defined _IO_MTSAFE_IO
16273 # if (defined NOT_IN_libc && !defined IS_IN_libpthread) || !defined _LIBC
16274@@ -87,6 +95,14 @@
16275
16276 /* Lock the recursive named lock variable. */
16277 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
16278+# if __OPTION_EGLIBC_BIG_MACROS != 1
16279+/* EGLIBC: Declare wrapper function for a big macro if either
16280+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16281+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16282+extern void __libc_lock_lock_recursive_fn (__libc_lock_recursive_t *);
16283+libc_hidden_proto (__libc_lock_lock_recursive_fn);
16284+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16285+# if __OPTION_EGLIBC_BIG_MACROS
16286 # define __libc_lock_lock_recursive(NAME) \
16287 do { \
16288 void *self = THREAD_SELF; \
16289@@ -97,6 +113,10 @@
16290 } \
16291 ++(NAME).cnt; \
16292 } while (0)
16293+# else
16294+# define __libc_lock_lock_recursive(NAME) \
16295+ __libc_lock_lock_recursive_fn (&(NAME))
16296+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16297 #else
16298 # define __libc_lock_lock_recursive(NAME) \
16299 __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
16300@@ -104,6 +124,14 @@
16301
16302 /* Try to lock the recursive named lock variable. */
16303 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
16304+# if __OPTION_EGLIBC_BIG_MACROS != 1
16305+/* EGLIBC: Declare wrapper function for a big macro if either
16306+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16307+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16308+extern int __libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *);
16309+libc_hidden_proto (__libc_lock_trylock_recursive_fn);
16310+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16311+# if __OPTION_EGLIBC_BIG_MACROS
16312 # define __libc_lock_trylock_recursive(NAME) \
16313 ({ \
16314 int result = 0; \
16315@@ -122,6 +150,10 @@
16316 ++(NAME).cnt; \
16317 result; \
16318 })
16319+# else
16320+# define __libc_lock_trylock_recursive(NAME) \
16321+ __libc_lock_trylock_recursive_fn (&(NAME))
16322+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16323 #else
16324 # define __libc_lock_trylock_recursive(NAME) \
16325 __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0)
16326@@ -129,6 +161,14 @@
16327
16328 /* Unlock the recursive named lock variable. */
16329 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
16330+# if __OPTION_EGLIBC_BIG_MACROS != 1
16331+/* EGLIBC: Declare wrapper function for a big macro if either
16332+ !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
16333+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16334+extern void __libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *);
16335+libc_hidden_proto (__libc_lock_unlock_recursive_fn);
16336+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16337+# if __OPTION_EGLIBC_BIG_MACROS
16338 /* We do no error checking here. */
16339 # define __libc_lock_unlock_recursive(NAME) \
16340 do { \
16341@@ -138,6 +178,10 @@
16342 lll_unlock ((NAME).lock, LLL_PRIVATE); \
16343 } \
16344 } while (0)
16345+# else
16346+# define __libc_lock_unlock_recursive(NAME) \
16347+ __libc_lock_unlock_recursive_fn (&(NAME))
16348+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16349 #else
16350 # define __libc_lock_unlock_recursive(NAME) \
16351 __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
16352Index: git/sysdeps/nptl/bits/libc-lockP.h
16353===================================================================
16354--- git.orig/sysdeps/nptl/bits/libc-lockP.h 2014-08-29 20:00:58.044070587 -0700
16355+++ git/sysdeps/nptl/bits/libc-lockP.h 2014-08-29 20:01:15.248070587 -0700
16356@@ -33,6 +33,8 @@
16357 #include <lowlevellock.h>
16358 #include <tls.h>
16359 #include <pthread-functions.h>
16360+#include <errno.h> /* For EBUSY. */
16361+#include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */
16362
16363 /* Mutex type. */
16364 #if defined NOT_IN_libc && !defined IS_IN_libpthread
16365@@ -159,10 +161,22 @@
16366
16367 /* Lock the named lock variable. */
16368 #if !defined NOT_IN_libc || defined IS_IN_libpthread
16369-# ifndef __libc_lock_lock
16370-# define __libc_lock_lock(NAME) \
16371+# if __OPTION_EGLIBC_BIG_MACROS != 1
16372+/* EGLIBC: Declare wrapper function for a big macro if either
16373+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16374+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16375+extern void __libc_lock_lock_fn (__libc_lock_t *);
16376+libc_hidden_proto (__libc_lock_lock_fn);
16377+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16378+# if __OPTION_EGLIBC_BIG_MACROS
16379+# ifndef __libc_lock_lock
16380+# define __libc_lock_lock(NAME) \
16381 ({ lll_lock (NAME, LLL_PRIVATE); 0; })
16382-# endif
16383+# endif
16384+# else
16385+# define __libc_lock_lock(NAME) \
16386+ __libc_lock_lock_fn (&(NAME))
16387+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16388 #else
16389 # undef __libc_lock_lock
16390 # define __libc_lock_lock(NAME) \
16391@@ -175,10 +189,22 @@
16392
16393 /* Try to lock the named lock variable. */
16394 #if !defined NOT_IN_libc || defined IS_IN_libpthread
16395-# ifndef __libc_lock_trylock
16396-# define __libc_lock_trylock(NAME) \
16397+# if __OPTION_EGLIBC_BIG_MACROS != 1
16398+/* EGLIBC: Declare wrapper function for a big macro if either
16399+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16400+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16401+extern int __libc_lock_trylock_fn (__libc_lock_t *);
16402+libc_hidden_proto (__libc_lock_trylock_fn);
16403+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16404+# if __OPTION_EGLIBC_BIG_MACROS
16405+# ifndef __libc_lock_trylock
16406+# define __libc_lock_trylock(NAME) \
16407 lll_trylock (NAME)
16408-# endif
16409+# endif
16410+# else
16411+# define __libc_lock_trylock(NAME) \
16412+ __libc_lock_trylock_fn (&(NAME))
16413+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16414 #else
16415 # undef __libc_lock_trylock
16416 # define __libc_lock_trylock(NAME) \
16417@@ -194,8 +220,20 @@
16418
16419 /* Unlock the named lock variable. */
16420 #if !defined NOT_IN_libc || defined IS_IN_libpthread
16421+# if __OPTION_EGLIBC_BIG_MACROS != 1
16422+/* EGLIBC: Declare wrapper function for a big macro if either
16423+ !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
16424+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16425+extern void __libc_lock_unlock_fn (__libc_lock_t *);
16426+libc_hidden_proto (__libc_lock_unlock_fn);
16427+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16428+# if __OPTION_EGLIBC_BIG_MACROS
16429 # define __libc_lock_unlock(NAME) \
16430 lll_unlock (NAME, LLL_PRIVATE)
16431+# else
16432+# define __libc_lock_unlock(NAME) \
16433+ __libc_lock_unlock_fn (&(NAME))
16434+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16435 #else
16436 # define __libc_lock_unlock(NAME) \
16437 __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
16438Index: git/sysdeps/nptl/small-macros-fns.c
16439===================================================================
16440--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16441+++ git/sysdeps/nptl/small-macros-fns.c 2014-08-29 20:01:15.248070587 -0700
16442@@ -0,0 +1,72 @@
16443+/* EGLIBC: function wrappers for big macros.
16444+ Copyright (C) 2009 Free Software Foundation, Inc.
16445+ This file is part of the GNU C Library.
16446+
16447+ The GNU C Library is free software; you can redistribute it and/or
16448+ modify it under the terms of the GNU Lesser General Public License as
16449+ published by the Free Software Foundation; either version 2.1 of the
16450+ License, or (at your option) any later version.
16451+
16452+ The GNU C Library is distributed in the hope that it will be useful,
16453+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16454+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16455+ Lesser General Public License for more details.
16456+
16457+ You should have received a copy of the GNU Lesser General Public
16458+ License along with the GNU C Library; see the file COPYING.LIB. If not,
16459+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16460+ Boston, MA 02111-1307, USA. */
16461+
16462+#include <gnu/option-groups.h>
16463+
16464+/* Handle macros from ./bits/libc-lock.h. */
16465+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
16466+
16467+/* Get the macros for function bodies through a back door. */
16468+# undef __OPTION_EGLIBC_BIG_MACROS
16469+# define __OPTION_EGLIBC_BIG_MACROS 2
16470+# include <bits/libc-lock.h>
16471+
16472+void
16473+__libc_lock_lock_fn (__libc_lock_t *name)
16474+{
16475+ __libc_lock_lock (*name);
16476+}
16477+libc_hidden_def (__libc_lock_lock_fn);
16478+
16479+void
16480+__libc_lock_lock_recursive_fn (__libc_lock_recursive_t *name)
16481+{
16482+ __libc_lock_lock_recursive (*name);
16483+}
16484+libc_hidden_def (__libc_lock_lock_recursive_fn);
16485+
16486+int
16487+__libc_lock_trylock_fn (__libc_lock_t *name)
16488+{
16489+ return __libc_lock_trylock (*name);
16490+}
16491+libc_hidden_def (__libc_lock_trylock_fn);
16492+
16493+int
16494+__libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *name)
16495+{
16496+ return __libc_lock_trylock_recursive (*name);
16497+}
16498+libc_hidden_def (__libc_lock_trylock_recursive_fn);
16499+
16500+void
16501+__libc_lock_unlock_fn (__libc_lock_t *name)
16502+{
16503+ __libc_lock_unlock (*name);
16504+}
16505+libc_hidden_def (__libc_lock_unlock_fn);
16506+
16507+void
16508+__libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *name)
16509+{
16510+ __libc_lock_unlock_recursive (*name);
16511+}
16512+libc_hidden_def (__libc_lock_unlock_recursive_fn);
16513+
16514+#endif /*defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)*/
16515Index: git/include/libc-symbols.h
16516===================================================================
16517--- git.orig/include/libc-symbols.h 2014-08-29 20:00:47.144070587 -0700
16518+++ git/include/libc-symbols.h 2014-08-29 20:01:15.248070587 -0700
16519@@ -60,8 +60,11 @@
16520 /* Define these macros for the benefit of portable GNU code that wants to check
16521 them. Of course, STDC_HEADERS is never false when building libc! */
16522 #define STDC_HEADERS 1
16523-#define HAVE_MBSTATE_T 1
16524-#define HAVE_MBSRTOWCS 1
16525+
16526+#if __OPTION_EGLIBC_LOCALE_CODE
16527+# define HAVE_MBSTATE_T 1
16528+# define HAVE_MBSRTOWCS 1
16529+#endif
16530 #define HAVE_LIBINTL_H 1
16531 #define HAVE_WCTYPE_H 1
16532 #define HAVE_ISWCTYPE 1
16533Index: git/crypt/crypt_common.c
16534===================================================================
16535--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16536+++ git/crypt/crypt_common.c 2014-08-29 20:01:15.248070587 -0700
16537@@ -0,0 +1,42 @@
16538+/*
16539+ * crypt: crypt(3) implementation
16540+ *
16541+ * Copyright (C) 1991-2014 Free Software Foundation, Inc.
16542+ *
16543+ * This library is free software; you can redistribute it and/or
16544+ * modify it under the terms of the GNU Lesser General Public
16545+ * License as published by the Free Software Foundation; either
16546+ * version 2.1 of the License, or (at your option) any later version.
16547+ *
16548+ * This library is distributed in the hope that it will be useful,
16549+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16550+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16551+ * Lesser General Public License for more details.
16552+ *
16553+ * You should have received a copy of the GNU Lesser General Public
16554+ * License along with this library; see the file COPYING.LIB. If not,
16555+ * see <http://www.gnu.org/licenses/>.
16556+ *
16557+ * General Support routines
16558+ *
16559+ */
16560+
16561+#include "crypt-private.h"
16562+
16563+/* Table with characters for base64 transformation. */
16564+static const char b64t[64] =
16565+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
16566+
16567+void
16568+__b64_from_24bit (char **cp, int *buflen,
16569+ unsigned int b2, unsigned int b1, unsigned int b0,
16570+ int n)
16571+{
16572+ unsigned int w = (b2 << 16) | (b1 << 8) | b0;
16573+ while (n-- > 0 && (*buflen) > 0)
16574+ {
16575+ *(*cp)++ = b64t[w & 0x3f];
16576+ --(*buflen);
16577+ w >>= 6;
16578+ }
16579+}
16580Index: git/crypt/crypt_util.c
16581===================================================================
16582--- git.orig/crypt/crypt_util.c 2014-08-29 20:00:43.028070587 -0700
16583+++ git/crypt/crypt_util.c 2014-08-29 20:01:15.248070587 -0700
16584@@ -242,10 +242,6 @@
16585 */
16586 static ufc_long efp[16][64][2];
16587
16588-/* Table with characters for base64 transformation. */
16589-static const char b64t[64] =
16590-"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
16591-
16592 /*
16593 * For use by the old, non-reentrant routines
16594 * (crypt/encrypt/setkey)
16595@@ -949,17 +945,3 @@
16596 {
16597 __setkey_r(__key, &_ufc_foobar);
16598 }
16599-
16600-void
16601-__b64_from_24bit (char **cp, int *buflen,
16602- unsigned int b2, unsigned int b1, unsigned int b0,
16603- int n)
16604-{
16605- unsigned int w = (b2 << 16) | (b1 << 8) | b0;
16606- while (n-- > 0 && (*buflen) > 0)
16607- {
16608- *(*cp)++ = b64t[w & 0x3f];
16609- --(*buflen);
16610- w >>= 6;
16611- }
16612-}
16613Index: git/sysdeps/arm/Makefile
16614===================================================================
16615--- git.orig/sysdeps/arm/Makefile 2014-08-29 20:29:37.000000000 -0700
16616+++ git/sysdeps/arm/Makefile 2014-08-29 20:31:09.904070587 -0700
16617@@ -37,10 +37,13 @@
16618 # get offset to rtld_global._dl_hwcap
16619 gen-as-const-headers += rtld-global-offsets.sym tlsdesc.sym
16620 aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math
16621-aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \
16622+aeabi_routines = aeabi_assert aeabi_errno_addr \
16623 aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \
16624 aeabi_memmove aeabi_memset \
16625 aeabi_read_tp libc-aeabi_read_tp
16626+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
16627+aeabi_routines += aeabi_localeconv
16628+endif
16629
16630 sysdep_routines += $(aeabi_constants) $(aeabi_routines)
16631 static-only-routines += $(aeabi_constants) aeabi_read_tp