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.patch16578
1 files changed, 16578 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..332b8f73a6
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/eglibc-use-option-groups.patch
@@ -0,0 +1,16578 @@
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+DN(initgroups)
4210-D(netgroup)
4211-D(networks)
4212+DN(netgroup)
4213+DN(networks)
4214 D(passwd)
4215-D(protocols)
4216-D(rpc)
4217-D(services)
4218+DN(protocols)
4219+DN(rpc)
4220+DN(services)
4221 D(shadow)
4222 #undef D
4223 { NULL, NULL }
4224Index: git/nss/getnssent_r.c
4225===================================================================
4226--- git.orig/nss/getnssent_r.c 2014-08-29 20:00:52.976070587 -0700
4227+++ git/nss/getnssent_r.c 2014-08-29 20:01:15.220070587 -0700
4228@@ -16,6 +16,7 @@
4229 <http://www.gnu.org/licenses/>. */
4230
4231 #include <errno.h>
4232+#include <gnu/option-groups.h>
4233 #include <netdb.h>
4234 #include "nsswitch.h"
4235
4236@@ -59,11 +60,13 @@
4237 } fct;
4238 int no_more;
4239
4240+#if __OPTION_EGLIBC_INET
4241 if (res && __res_maybe_init (&_res, 0) == -1)
4242 {
4243 __set_h_errno (NETDB_INTERNAL);
4244 return;
4245 }
4246+#endif /* __OPTION_EGLIBC_INET */
4247
4248 /* Cycle through the services and run their `setXXent' functions until
4249 we find an available service. */
4250@@ -101,11 +104,13 @@
4251 } fct;
4252 int no_more;
4253
4254+#if __OPTION_EGLIBC_INET
4255 if (res && __res_maybe_init (&_res, 0) == -1)
4256 {
4257 __set_h_errno (NETDB_INTERNAL);
4258 return;
4259 }
4260+#endif /* __OPTION_EGLIBC_INET */
4261
4262 /* Cycle through all the services and run their endXXent functions. */
4263 no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
4264@@ -141,12 +146,14 @@
4265 int no_more;
4266 enum nss_status status;
4267
4268+#if __OPTION_EGLIBC_INET
4269 if (res && __res_maybe_init (&_res, 0) == -1)
4270 {
4271 *h_errnop = NETDB_INTERNAL;
4272 *result = NULL;
4273 return errno;
4274 }
4275+#endif /* __OPTION_EGLIBC_INET */
4276
4277 /* Initialize status to return if no more functions are found. */
4278 status = NSS_STATUS_NOTFOUND;
4279@@ -161,7 +168,7 @@
4280 int is_last_nip = *nip == *last_nip;
4281
4282 status = DL_CALL_FCT (fct.f,
4283- (resbuf, buffer, buflen, &errno, &h_errno));
4284+ (resbuf, buffer, buflen, &errno, h_errnop));
4285
4286 /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
4287 provided buffer is too small. In this case we should give
4288Index: git/nss/Makefile
4289===================================================================
4290--- git.orig/nss/Makefile 2014-08-29 20:00:52.972070587 -0700
4291+++ git/nss/Makefile 2014-08-29 20:01:15.220070587 -0700
4292@@ -18,29 +18,36 @@
4293 #
4294 # Makefile for name service switch.
4295 #
4296+include ../option-groups.mak
4297+
4298 subdir := nss
4299
4300 include ../Makeconfig
4301
4302 headers := nss.h
4303
4304-# This is the trivial part which goes into libc itself.
4305-routines = nsswitch getnssent getnssent_r digits_dots \
4306- $(addsuffix -lookup,$(databases))
4307-
4308 # These are the databases that go through nss dispatch.
4309 # Caution: if you add a database here, you must add its real name
4310 # in databases.def, too.
4311-databases = proto service hosts network grp pwd rpc ethers \
4312- spwd netgrp key alias sgrp
4313+databases-y = grp pwd spwd sgrp
4314+databases-$(OPTION_EGLIBC_INET) \
4315+ += proto service hosts network rpc ethers \
4316+ netgrp key
4317+databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
4318+
4319+# This is the trivial part which goes into libc itself.
4320+routines-y += nsswitch getnssent getnssent_r \
4321+ $(addsuffix -lookup,$(databases-y))
4322+routines-$(OPTION_EGLIBC_INET) += digits_dots
4323
4324 others := getent makedb
4325 install-bin := getent makedb
4326 makedb-modules = xmalloc hash-string
4327 extra-objs += $(makedb-modules:=.o)
4328
4329-tests = test-netdb tst-nss-test1 test-digits-dots
4330-xtests = bug-erange
4331+tests = tst-nss-test1
4332+tests-$(OPTION_EGLIBC_INET) += test-netdb test-digits-dots
4333+xtests-$(OPTION_EGLIBC_INET) += bug-erange
4334
4335 # Specify rules for the nss_* modules. We have some services.
4336 services := files db
4337@@ -55,7 +62,7 @@
4338 vpath %.c $(subdir-dirs) ../locale/programs ../intl
4339
4340
4341-libnss_files-routines := $(addprefix files-,$(databases)) \
4342+libnss_files-routines := $(addprefix files-,$(databases-y)) \
4343 files-initgroups files-have_o_cloexec files-init
4344
4345 libnss_db-dbs := $(addprefix db-,\
4346@@ -78,6 +85,45 @@
4347 tests += $(tests-static)
4348 endif
4349
4350+ifneq ($(OPTION_EGLIBC_NSSWITCH),y)
4351+
4352+ifndef OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG
4353+$(error OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG variable left unset)
4354+endif
4355+
4356+ifndef OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS
4357+$(error OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS variable left unset)
4358+endif
4359+
4360+ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)))
4361+$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed config file)
4362+$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG))
4363+endif
4364+
4365+ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)))
4366+$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed functions file)
4367+$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS))
4368+endif
4369+
4370+before-compile := $(objpfx)fixed-nsswitch.h
4371+generated := fixed-nsswitch.h
4372+$(objpfx)fixed-nsswitch.h $(objfpx)fixed-nsswitch-libs: \
4373+ $(objpfx)gen-fixed-nsswitch \
4374+ $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
4375+ $< $(objpfx)fixed-nsswitch.h \
4376+ $(objpfx)fixed-nsswitch-libs \
4377+ $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
4378+
4379+$(objpfx)gen-fixed-nsswitch: gen-fixed-nsswitch.c \
4380+ $(common-objpfx)option-groups.config \
4381+ $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)
4382+ $(native-compile)
4383+gen-fixed-nsswitch-CFLAGS = \
4384+ -g3 -O -Wall \
4385+ -I $(objpfx) \
4386+ -DFIXED_FUNCTIONS='"$(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)"'
4387+endif
4388+
4389 include ../Rules
4390
4391 ifeq (yes,$(have-selinux))
4392Index: git/nss/nsswitch.c
4393===================================================================
4394--- git.orig/nss/nsswitch.c 2014-08-29 20:00:53.004070587 -0700
4395+++ git/nss/nsswitch.c 2014-08-29 20:01:15.220070587 -0700
4396@@ -26,6 +26,7 @@
4397 #include <stdio_ext.h>
4398 #include <stdlib.h>
4399 #include <string.h>
4400+#include <gnu/option-groups.h>
4401
4402 #include <aliases.h>
4403 #include <grp.h>
4404@@ -41,6 +42,15 @@
4405 #include "../nscd/nscd_proto.h"
4406 #include <sysdep.h>
4407
4408+/* When OPTION_EGLIBC_NSSWITCH is disabled, we use fixed tables of
4409+ databases and services, generated at library build time. Thus:
4410+ - We can't reconfigure individual databases, so we don't need a
4411+ name-to-database map.
4412+ - We never add databases or service libraries, or look up functions
4413+ at runtime, so there's no need for a lock to protect our tables.
4414+ See ../option-groups.def for the details. */
4415+#if __OPTION_EGLIBC_NSSWITCH
4416+
4417 /* Prototypes for the local functions. */
4418 static name_database *nss_parse_file (const char *fname) internal_function;
4419 static name_database_entry *nss_getline (char *line) internal_function;
4420@@ -79,6 +89,9 @@
4421
4422 __libc_lock_define_initialized (static, lock)
4423
4424+#define lock_nsswitch __libc_lock_lock (lock)
4425+#define unlock_nsswitch __libc_lock_unlock (lock)
4426+
4427 #if !defined DO_STATIC_NSS || defined SHARED
4428 /* String with revision number of the shared object files. */
4429 static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15;
4430@@ -93,6 +106,20 @@
4431 __libc_freeres. */
4432 static name_database_entry *defconfig_entries;
4433
4434+#else /* __OPTION_EGLIBC_NSSWITCH */
4435+
4436+/* Bring in the statically initialized service table we generated at
4437+ build time. */
4438+#include "fixed-nsswitch.h"
4439+
4440+const static name_database *service_table = &fixed_name_database;
4441+
4442+/* Nothing ever changes, so there's no need to lock anything. */
4443+#define lock_nsswitch (0)
4444+#define unlock_nsswitch (0)
4445+
4446+#endif /* __OPTION_EGLIBC_NSSWITCH */
4447+
4448
4449 #ifdef USE_NSCD
4450 /* Nonzero if this is the nscd process. */
4451@@ -109,20 +136,22 @@
4452 const char *defconfig, service_user **ni)
4453 {
4454 /* Prevent multiple threads to change the service table. */
4455- __libc_lock_lock (lock);
4456+ lock_nsswitch;
4457
4458 /* Reconsider database variable in case some other thread called
4459 `__nss_configure_lookup' while we waited for the lock. */
4460 if (*ni != NULL)
4461 {
4462- __libc_lock_unlock (lock);
4463+ unlock_nsswitch;
4464 return 0;
4465 }
4466
4467+#if __OPTION_EGLIBC_NSSWITCH
4468 /* Are we initialized yet? */
4469 if (service_table == NULL)
4470 /* Read config file. */
4471 service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
4472+#endif
4473
4474 /* Test whether configuration data is available. */
4475 if (service_table != NULL)
4476@@ -144,6 +173,7 @@
4477 *ni = entry->service;
4478 }
4479
4480+#if __OPTION_EGLIBC_NSSWITCH
4481 /* No configuration data is available, either because nsswitch.conf
4482 doesn't exist or because it doesn't have a line for this database.
4483
4484@@ -166,13 +196,23 @@
4485 {
4486 entry->next = defconfig_entries;
4487 entry->service = *ni;
4488- entry->name[0] = '\0';
4489+ entry->name = "";
4490 defconfig_entries = entry;
4491 }
4492 }
4493 }
4494+#else
4495+ /* Without the dynamic behavior, we can't process defconfig. The
4496+ databases the user specified at library build time are all you
4497+ get. */
4498+ if (*ni == NULL)
4499+ {
4500+ unlock_nsswitch;
4501+ return -1;
4502+ }
4503+#endif
4504
4505- __libc_lock_unlock (lock);
4506+ unlock_nsswitch;
4507
4508 return *ni != NULL ? 0 : -1;
4509 }
4510@@ -252,6 +292,7 @@
4511 libc_hidden_def (__nss_next2)
4512
4513
4514+#if __OPTION_EGLIBC_NSSWITCH
4515 int
4516 attribute_compat_text_section
4517 __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
4518@@ -300,13 +341,13 @@
4519 }
4520
4521 /* Prevent multiple threads to change the service table. */
4522- __libc_lock_lock (lock);
4523+ lock_nsswitch;
4524
4525 /* Install new rules. */
4526 *databases[cnt].dbp = new_db;
4527 __nss_database_custom[cnt] = true;
4528
4529- __libc_lock_unlock (lock);
4530+ unlock_nsswitch;
4531
4532 return 0;
4533 }
4534@@ -402,7 +443,7 @@
4535 void **found, *result;
4536
4537 /* We now modify global data. Protect it. */
4538- __libc_lock_lock (lock);
4539+ lock_nsswitch;
4540
4541 /* Search the tree of functions previously requested. Data in the
4542 tree are `known_function' structures, whose first member is a
4543@@ -413,7 +454,7 @@
4544 enough to a pointer to our structure to use as a lookup key that
4545 will be passed to `known_compare' (above). */
4546
4547- found = __tsearch (&fct_name, &ni->known, &known_compare);
4548+ found = __tsearch (&fct_name, &ni->known.tree, &known_compare);
4549 if (found == NULL)
4550 /* This means out-of-memory. */
4551 result = NULL;
4552@@ -440,7 +481,7 @@
4553 #endif
4554 /* Oops. We can't instantiate this node properly.
4555 Remove it from the tree. */
4556- __tdelete (&fct_name, &ni->known, &known_compare);
4557+ __tdelete (&fct_name, &ni->known.tree, &known_compare);
4558 free (known);
4559 result = NULL;
4560 }
4561@@ -520,13 +561,43 @@
4562 }
4563
4564 /* Remove the lock. */
4565- __libc_lock_unlock (lock);
4566+ unlock_nsswitch;
4567
4568 return result;
4569 }
4570 libc_hidden_def (__nss_lookup_function)
4571
4572
4573+#else /* below if ! __OPTION_EGLIBC_NSSWITCH */
4574+
4575+
4576+int
4577+__nss_configure_lookup (const char *dbname, const char *service_line)
4578+{
4579+ /* We can't dynamically configure lookup without
4580+ OPTION_EGLIBC_NSSWITCH. */
4581+ __set_errno (EINVAL);
4582+ return -1;
4583+}
4584+
4585+
4586+void *
4587+__nss_lookup_function (service_user *ni, const char *fct_name)
4588+{
4589+ int i;
4590+ const known_function **known = ni->known.array;
4591+
4592+ for (i = 0; known[i]; i++)
4593+ if (strcmp (fct_name, known[i]->fct_name) == 0)
4594+ return known[i]->fct_ptr;
4595+
4596+ return NULL;
4597+}
4598+libc_hidden_def (__nss_lookup_function)
4599+#endif
4600+
4601+
4602+#if __OPTION_EGLIBC_NSSWITCH
4603 static name_database *
4604 internal_function
4605 nss_parse_file (const char *fname)
4606@@ -632,8 +703,10 @@
4607 + (line - name + 1));
4608 if (new_service == NULL)
4609 return result;
4610+ new_service->name = (char *) (new_service + 1);
4611
4612- *((char *) __mempcpy (new_service->name, name, line - name)) = '\0';
4613+ *((char *) __mempcpy ((char *) new_service->name, name, line - name))
4614+ = '\0';
4615
4616 /* Set default actions. */
4617 new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
4618@@ -642,7 +715,7 @@
4619 new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
4620 new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
4621 new_service->library = NULL;
4622- new_service->known = NULL;
4623+ new_service->known.tree = NULL;
4624 new_service->next = NULL;
4625
4626 while (isspace (line[0]))
4627@@ -778,9 +851,10 @@
4628 result = (name_database_entry *) malloc (sizeof (name_database_entry) + len);
4629 if (result == NULL)
4630 return NULL;
4631+ result->name = (char *) (result + 1);
4632
4633 /* Save the database name. */
4634- memcpy (result->name, name, len);
4635+ memcpy ((char *) result->name, name, len);
4636
4637 /* Parse the list of services. */
4638 result->service = nss_parse_service_list (line);
4639@@ -816,6 +890,7 @@
4640 return *currentp;
4641 }
4642 #endif
4643+#endif /* __OPTION_EGLIBC_NSSWITCH */
4644
4645
4646 #if defined SHARED && defined USE_NSCD
4647@@ -834,6 +909,7 @@
4648 }
4649
4650
4651+#if __OPTION_EGLIBC_INET
4652 /* Called by nscd and nscd alone. */
4653 void
4654 __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
4655@@ -857,8 +933,10 @@
4656 __nss_not_use_nscd_services = -1;
4657 __nss_not_use_nscd_netgroup = -1;
4658 }
4659+#endif /* __OPTION_EGLIBC_INET */
4660 #endif
4661
4662+#if __OPTION_EGLIBC_NSSWITCH
4663 static void
4664 free_database_entries (name_database_entry *entry)
4665 {
4666@@ -871,8 +949,8 @@
4667 {
4668 service_user *olds = service;
4669
4670- if (service->known != NULL)
4671- __tdestroy (service->known, free);
4672+ if (service->known.tree != NULL)
4673+ __tdestroy (service->known.tree, free);
4674
4675 service = service->next;
4676 free (olds);
4677@@ -926,3 +1004,4 @@
4678
4679 free (top);
4680 }
4681+#endif /* __OPTION_EGLIBC_NSSWITCH */
4682Index: git/nss/nsswitch.h
4683===================================================================
4684--- git.orig/nss/nsswitch.h 2014-08-29 20:00:53.012070587 -0700
4685+++ git/nss/nsswitch.h 2014-08-29 20:01:15.220070587 -0700
4686@@ -65,10 +65,20 @@
4687 lookup_actions actions[5];
4688 /* Link to the underlying library object. */
4689 service_library *library;
4690- /* Collection of known functions. */
4691- void *known;
4692+ /* Collection of known functions.
4693+
4694+ With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
4695+ 'tsearch'-style tree.
4696+
4697+ With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
4698+ pointers to known_function structures, NULL-terminated. */
4699+ union
4700+ {
4701+ void *tree;
4702+ const known_function **array;
4703+ } known;
4704 /* Name of the service (`files', `dns', `nis', ...). */
4705- char name[0];
4706+ const char *name;
4707 } service_user;
4708
4709 /* To access the action based on the status value use this macro. */
4710@@ -82,7 +92,7 @@
4711 /* List of service to be used. */
4712 service_user *service;
4713 /* Name of the database. */
4714- char name[0];
4715+ const char *name;
4716 } name_database_entry;
4717
4718
4719Index: git/posix/bug-regex1.c
4720===================================================================
4721--- git.orig/posix/bug-regex1.c 2014-08-29 20:00:53.184070587 -0700
4722+++ git/posix/bug-regex1.c 2014-08-29 20:01:15.220070587 -0700
4723@@ -4,6 +4,7 @@
4724 #include <string.h>
4725 #include <regex.h>
4726 #include <wchar.h>
4727+#include <gnu/option-groups.h>
4728
4729 int
4730 main (void)
4731@@ -17,7 +18,9 @@
4732 memset (&regex, '\0', sizeof (regex));
4733
4734 setlocale (LC_ALL, "de_DE.ISO-8859-1");
4735+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
4736 fwide (stdout, -1);
4737+#endif
4738
4739 re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_DEBUG);
4740
4741Index: git/posix/bug-regex6.c
4742===================================================================
4743--- git.orig/posix/bug-regex6.c 2014-08-29 20:00:53.204070587 -0700
4744+++ git/posix/bug-regex6.c 2014-08-29 20:01:15.220070587 -0700
4745@@ -22,6 +22,7 @@
4746 #include <string.h>
4747 #include <sys/types.h>
4748 #include <regex.h>
4749+#include <gnu/option-groups.h>
4750
4751
4752 int
4753@@ -30,7 +31,12 @@
4754 regex_t re;
4755 regmatch_t mat[10];
4756 int i, j, ret = 0;
4757- const char *locales[] = { "C", "de_DE.UTF-8" };
4758+ const char *locales[] = {
4759+ "C",
4760+#if __OPTION_EGLIBC_LOCALE_CODE
4761+ "de_DE.UTF-8"
4762+#endif
4763+ };
4764 const char *string = "http://www.regex.com/pattern/matching.html#intro";
4765 regmatch_t expect[10] = {
4766 { 0, 48 }, { 0, 5 }, { 0, 4 }, { 5, 20 }, { 7, 20 }, { 20, 42 },
4767Index: git/posix/fnmatch.c
4768===================================================================
4769--- git.orig/posix/fnmatch.c 2014-08-29 20:00:53.208070587 -0700
4770+++ git/posix/fnmatch.c 2014-08-29 20:01:15.220070587 -0700
4771@@ -30,6 +30,10 @@
4772 #include <ctype.h>
4773 #include <string.h>
4774
4775+#if defined _LIBC
4776+# include <gnu/option-groups.h>
4777+#endif
4778+
4779 #if defined STDC_HEADERS || defined _LIBC
4780 # include <stdlib.h>
4781 #endif
4782@@ -131,7 +135,7 @@
4783 # define ISWCTYPE(WC, WT) iswctype (WC, WT)
4784 # endif
4785
4786-# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
4787+# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || (_LIBC && __OPTION_EGLIBC_LOCALE_CODE)
4788 /* In this case we are implementing the multibyte character handling. */
4789 # define HANDLE_MULTIBYTE 1
4790 # endif
4791Index: git/posix/fnmatch_loop.c
4792===================================================================
4793--- git.orig/posix/fnmatch_loop.c 2014-08-29 20:00:53.220070587 -0700
4794+++ git/posix/fnmatch_loop.c 2014-08-29 20:01:15.220070587 -0700
4795@@ -15,6 +15,8 @@
4796 License along with the GNU C Library; if not, see
4797 <http://www.gnu.org/licenses/>. */
4798
4799+#include <gnu/option-groups.h>
4800+
4801 #include <stdint.h>
4802
4803 struct STRUCT
4804@@ -54,10 +56,15 @@
4805 const char *collseq = (const char *)
4806 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
4807 # else
4808+# if __OPTION_EGLIBC_LOCALE_CODE
4809 const UCHAR *collseq = (const UCHAR *)
4810 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
4811-# endif
4812-#endif
4813+# define COLLSEQ_BYTE_LOOKUP(ix) (collseq[(ix)])
4814+# else
4815+# define COLLSEQ_BYTE_LOOKUP(ix) (ix)
4816+# endif /* __OPTION_EGLIBC_LOCALE_CODE */
4817+# endif /* WIDE_CHAR_VERSION */
4818+#endif /* _LIBC */
4819
4820 while ((c = *p++) != L('\0'))
4821 {
4822@@ -277,7 +284,7 @@
4823 /* Leave room for the null. */
4824 CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
4825 size_t c1 = 0;
4826-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
4827+#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
4828 wctype_t wt;
4829 #endif
4830 const CHAR *startp = p;
4831@@ -307,7 +314,7 @@
4832 }
4833 str[c1] = L('\0');
4834
4835-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
4836+#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
4837 wt = IS_CHAR_CLASS (str);
4838 if (wt == 0)
4839 /* Invalid character class name. */
4840@@ -681,8 +688,10 @@
4841 else
4842 lcollseq = __collseq_table_lookup (collseq, cold);
4843 # else
4844- fcollseq = collseq[fn];
4845- lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
4846+ fcollseq = COLLSEQ_BYTE_LOOKUP (fn);
4847+ lcollseq = (is_seqval
4848+ ? cold
4849+ : COLLSEQ_BYTE_LOOKUP ((UCHAR) cold));
4850 # endif
4851
4852 is_seqval = 0;
4853@@ -858,7 +867,7 @@
4854 goto matched;
4855 }
4856 # else
4857- hcollseq = collseq[cend];
4858+ hcollseq = COLLSEQ_BYTE_LOOKUP (cend);
4859 # endif
4860 }
4861
4862Index: git/posix/glob.c
4863===================================================================
4864--- git.orig/posix/glob.c 2014-08-29 20:00:53.232070587 -0700
4865+++ git/posix/glob.c 2014-08-29 20:01:15.220070587 -0700
4866@@ -25,6 +25,9 @@
4867 #include <sys/types.h>
4868 #include <sys/stat.h>
4869 #include <stddef.h>
4870+#ifdef _LIBC
4871+# include <gnu/option-groups.h>
4872+#endif
4873
4874 /* Outcomment the following line for production quality code. */
4875 /* #define NDEBUG 1 */
4876@@ -607,6 +610,7 @@
4877 if (home_dir == NULL || home_dir[0] == '\0')
4878 home_dir = "c:/users/default"; /* poor default */
4879 # else
4880+# if ! _LIBC || __OPTION_EGLIBC_GETLOGIN
4881 if (home_dir == NULL || home_dir[0] == '\0')
4882 {
4883 int success;
4884@@ -623,19 +627,19 @@
4885 if (success)
4886 {
4887 struct passwd *p;
4888-# if defined HAVE_GETPWNAM_R || defined _LIBC
4889+# if defined HAVE_GETPWNAM_R || defined _LIBC
4890 long int pwbuflen = GETPW_R_SIZE_MAX ();
4891 char *pwtmpbuf;
4892 struct passwd pwbuf;
4893 int malloc_pwtmpbuf = 0;
4894 int save = errno;
4895
4896-# ifndef _LIBC
4897+# ifndef _LIBC
4898 if (pwbuflen == -1)
4899 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
4900 Try a moderate value. */
4901 pwbuflen = 1024;
4902-# endif
4903+# endif
4904 if (__libc_use_alloca (alloca_used + pwbuflen))
4905 pwtmpbuf = alloca_account (pwbuflen, alloca_used);
4906 else
4907@@ -682,9 +686,9 @@
4908 }
4909 __set_errno (save);
4910 }
4911-# else
4912+# else
4913 p = getpwnam (name);
4914-# endif
4915+# endif
4916 if (p != NULL)
4917 {
4918 if (!malloc_pwtmpbuf)
4919@@ -713,6 +717,7 @@
4920 }
4921 }
4922 }
4923+# endif /* ! _LIBC || __OPTION_EGLIBC_GETLOGIN */
4924 if (home_dir == NULL || home_dir[0] == '\0')
4925 {
4926 if (flags & GLOB_TILDE_CHECK)
4927Index: git/posix/Makefile
4928===================================================================
4929--- git.orig/posix/Makefile 2014-08-29 20:00:53.160070587 -0700
4930+++ git/posix/Makefile 2014-08-29 20:01:15.220070587 -0700
4931@@ -18,6 +18,8 @@
4932 #
4933 # Sub-makefile for POSIX portion of the library.
4934 #
4935+include ../option-groups.mak
4936+
4937 subdir := posix
4938
4939 include ../Makeconfig
4940@@ -43,13 +45,24 @@
4941 getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid \
4942 getresuid getresgid setresuid setresgid \
4943 pathconf sysconf fpathconf \
4944- glob glob64 fnmatch regex \
4945+ glob glob64 fnmatch \
4946 confstr \
4947 getopt getopt1 getopt_init \
4948 sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax \
4949 sched_primin sched_rr_gi sched_getaffinity sched_setaffinity \
4950- getaddrinfo gai_strerror wordexp \
4951 pread pwrite pread64 pwrite64 \
4952+ posix_madvise \
4953+ get_child_max sched_cpucount sched_cpualloc sched_cpufree
4954+
4955+routines-$(OPTION_EGLIBC_INET) += getaddrinfo gai_strerror
4956+
4957+ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
4958+routines-$(OPTION_POSIX_REGEXP) += regex
4959+else
4960+routines-$(OPTION_POSIX_REGEXP) += xregex
4961+endif
4962+
4963+routines-$(OPTION_EGLIBC_SPAWN) += \
4964 spawn_faction_init spawn_faction_destroy spawn_faction_addclose \
4965 spawn_faction_addopen spawn_faction_adddup2 \
4966 spawnattr_init spawnattr_destroy \
4967@@ -57,41 +70,53 @@
4968 spawnattr_getflags spawnattr_setflags \
4969 spawnattr_getpgroup spawnattr_setpgroup spawn spawnp spawni \
4970 spawnattr_getsigmask spawnattr_getschedpolicy spawnattr_getschedparam \
4971- spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
4972- posix_madvise \
4973- get_child_max sched_cpucount sched_cpualloc sched_cpufree
4974+ spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam
4975+routines-$(OPTION_EGLIBC_WORDEXP) += wordexp
4976
4977 aux := init-posix environ
4978-tests := tstgetopt testfnm runtests runptests \
4979+tests := tstgetopt testfnm runtests \
4980 tst-preadwrite tst-preadwrite64 test-vfork regexbug1 \
4981- tst-getlogin tst-mmap tst-getaddrinfo tst-truncate \
4982- tst-truncate64 tst-fork tst-fnmatch tst-regexloc tst-dir \
4983- tst-chmod bug-regex1 bug-regex2 bug-regex3 bug-regex4 \
4984- tst-gnuglob tst-regex bug-regex5 bug-regex6 bug-regex7 \
4985- bug-regex8 bug-regex9 bug-regex10 bug-regex11 bug-regex12 \
4986- bug-regex13 bug-regex14 bug-regex15 bug-regex16 \
4987- bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
4988- bug-regex21 bug-regex22 bug-regex23 bug-regex24 \
4989- bug-regex25 bug-regex26 bug-regex27 bug-regex28 \
4990- bug-regex29 bug-regex30 bug-regex31 bug-regex32 \
4991- bug-regex33 tst-nice tst-nanosleep tst-regex2 \
4992- transbug tst-rxspencer tst-pcre tst-boost \
4993- bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
4994- tst-getaddrinfo2 bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
4995+ tst-getlogin tst-mmap tst-truncate \
4996+ tst-truncate64 tst-fork tst-dir \
4997+ tst-chmod bug-regex2 bug-regex3 bug-regex4 \
4998+ tst-gnuglob bug-regex6 bug-regex7 \
4999+ bug-regex8 bug-regex9 bug-regex10 bug-regex12 \
5000+ bug-regex14 bug-regex15 \
5001+ bug-regex21 bug-regex24 \
5002+ bug-regex27 bug-regex28 bug-regex29 bug-regex30 \
5003+ bug-regex31 \
5004+ tst-nice tst-nanosleep \
5005+ transbug \
5006+ tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
5007+ bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
5008 tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \
5009 tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
5010 tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
5011- tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
5012- tst-rfc3484-3 \
5013- tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
5014+ tst-execvp3 tst-execvp4 \
5015+ tst-fnmatch2 tst-cpucount tst-cpuset \
5016 bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
5017 bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
5018 tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \
5019 tst-fnmatch3 bug-regex36
5020-xtests := bug-ga2
5021+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
5022+ += tst-fnmatch tst-regexloc bug-regex1 bug-regex5 \
5023+ bug-regex23 bug-regex25 bug-regex32 bug-regex33
5024+tests-$(OPTION_EGLIBC_INET) \
5025+ += tst-getaddrinfo bug-ga1 tst-getaddrinfo2 \
5026+ tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 tst-getaddrinfo3
5027+tests-$(OPTION_POSIX_REGEXP_GLIBC) \
5028+ += runptests bug-regex11 bug-regex13 bug-regex16 \
5029+ tst-regex2 tst-rxspencer tst-pcre tst-boost
5030+ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP_GLIBC))
5031+tests += tst-regex bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
5032+ bug-regex22 bug-regex26
5033+endif
5034+xtests-$(OPTION_EGLIBC_INET) += bug-ga2
5035 ifeq (yes,$(build-shared))
5036 test-srcs := globtest
5037-tests += wordexp-test tst-exec tst-spawn
5038+tests += tst-exec
5039+tests-$(OPTION_EGLIBC_SPAWN) += tst-spawn
5040+tests-$(OPTION_EGLIBC_WORDEXP) += wordexp-test
5041 endif
5042 tests-static = tst-exec-static tst-spawn-static
5043 tests += $(tests-static)
5044@@ -117,7 +142,10 @@
5045
5046 ifeq ($(run-built-tests),yes)
5047 ifeq (yes,$(build-shared))
5048-tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out
5049+tests-special += $(objpfx)globtest.out
5050+ifeq (y,$(OPTION_EGLIBC_WORDEXP))
5051+tests-special += $(objpfx)wordexp-tst.out
5052+endif
5053 endif
5054 endif
5055
5056@@ -125,12 +153,16 @@
5057 # XXX Please note that for now we ignore the result of this test.
5058 tests-special += $(objpfx)annexc.out
5059 ifeq ($(run-built-tests),yes)
5060-tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
5061+tests-special += $(objpfx)bug-regex2-mem.out \
5062 $(objpfx)bug-regex21-mem.out $(objpfx)bug-regex31-mem.out \
5063- $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
5064- $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
5065+ $(objpfx)tst-getconf.out \
5066 $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
5067 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
5068+ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
5069+tests-special += $(objpfx)bug-regex14-mem $(objpfx)tst-rxspencer-no-utf8-mem \
5070+ $(objpfx)tst-pcre-mem $(objpfx)tst-boost-mem
5071+endif
5072+
5073 xtests-special += $(objpfx)bug-ga2-mem.out
5074 endif
5075
5076@@ -143,6 +175,8 @@
5077 $(SHELL) $< $(common-objpfx) '$(test-via-rtld-prefix)' \
5078 '$(test-program-prefix)' '$(test-wrapper-env)'; \
5079 $(evaluate-test)
5080+LDLIBS-globtest += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
5081+
5082 $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test
5083 $(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \
5084 '$(run-program-env)' '$(test-program-prefix-after-env)'; \
5085@@ -205,7 +239,10 @@
5086 tst-chmod-ARGS = $(objdir)
5087 tst-vfork3-ARGS = --test-dir=$(objpfx)
5088
5089-tst-rxspencer-ARGS = --utf8 rxspencer/tests
5090+tst-rxspencer-ARGS = rxspencer/tests
5091+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
5092+tst-rxspencer-ARGS += --utf8
5093+endif
5094 tst-rxspencer-no-utf8-ARGS = rxspencer/tests
5095 tst-pcre-ARGS = PCRE.tests
5096 tst-boost-ARGS = BOOST.tests
5097Index: git/posix/regcomp.c
5098===================================================================
5099--- git.orig/posix/regcomp.c 2014-08-29 20:00:53.264070587 -0700
5100+++ git/posix/regcomp.c 2014-08-29 20:01:15.224070587 -0700
5101@@ -18,6 +18,7 @@
5102 <http://www.gnu.org/licenses/>. */
5103
5104 #include <stdint.h>
5105+#include <gnu/option-groups.h>
5106
5107 static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
5108 size_t length, reg_syntax_t syntax);
5109@@ -305,7 +306,7 @@
5110 {
5111 re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
5112 int node_cnt;
5113- int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
5114+ int icase = (dfa_mb_cur_max (dfa) == 1 && (bufp->syntax & RE_ICASE));
5115 for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
5116 {
5117 int node = init_state->nodes.elems[node_cnt];
5118@@ -315,9 +316,9 @@
5119 {
5120 re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
5121 #ifdef RE_ENABLE_I18N
5122- if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
5123+ if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
5124 {
5125- unsigned char *buf = alloca (dfa->mb_cur_max), *p;
5126+ unsigned char *buf = alloca (dfa_mb_cur_max (dfa)), *p;
5127 wchar_t wc;
5128 mbstate_t state;
5129
5130@@ -348,7 +349,11 @@
5131 re_set_fastmap (fastmap, icase, ch);
5132 }
5133 }
5134-#ifdef RE_ENABLE_I18N
5135+
5136+ /* When OPTION_EGLIBC_LOCALE_CODE is disabled, the current
5137+ locale is always C, which has no rules and no multi-byte
5138+ characters. */
5139+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
5140 else if (type == COMPLEX_BRACKET)
5141 {
5142 re_charset_t *cset = dfa->nodes[node].opr.mbcset;
5143@@ -376,7 +381,7 @@
5144 i.e. where we would not find an invalid sequence. This only
5145 applies to multibyte character sets; for single byte character
5146 sets, the SIMPLE_BRACKET again suffices. */
5147- if (dfa->mb_cur_max > 1
5148+ if (dfa_mb_cur_max (dfa) > 1
5149 && (cset->nchar_classes || cset->non_match || cset->nranges
5150 # ifdef _LIBC
5151 || cset->nequiv_classes
5152@@ -404,7 +409,7 @@
5153 memset (&state, '\0', sizeof (state));
5154 if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
5155 re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
5156- if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
5157+ if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
5158 {
5159 if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
5160 != (size_t) -1)
5161@@ -413,7 +418,7 @@
5162 }
5163 }
5164 }
5165-#endif /* RE_ENABLE_I18N */
5166+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
5167 else if (type == OP_PERIOD
5168 #ifdef RE_ENABLE_I18N
5169 || type == OP_UTF8_PERIOD
5170@@ -856,11 +861,15 @@
5171
5172 dfa->mb_cur_max = MB_CUR_MAX;
5173 #ifdef _LIBC
5174- if (dfa->mb_cur_max == 6
5175+ if (dfa_mb_cur_max (dfa) == 6
5176 && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
5177 dfa->is_utf8 = 1;
5178+# if __OPTION_EGLIBC_LOCALE_CODE
5179 dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
5180 != 0);
5181+# else
5182+ dfa->map_notascii = 0;
5183+# endif
5184 #else
5185 # ifdef HAVE_LANGINFO_CODESET
5186 codeset_name = nl_langinfo (CODESET);
5187@@ -886,7 +895,7 @@
5188 #endif
5189
5190 #ifdef RE_ENABLE_I18N
5191- if (dfa->mb_cur_max > 1)
5192+ if (dfa_mb_cur_max (dfa) > 1)
5193 {
5194 if (dfa->is_utf8)
5195 dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
5196@@ -1784,7 +1793,7 @@
5197 token->word_char = 0;
5198 #ifdef RE_ENABLE_I18N
5199 token->mb_partial = 0;
5200- if (input->mb_cur_max > 1 &&
5201+ if (string_mb_cur_max (input) > 1 &&
5202 !re_string_first_byte (input, re_string_cur_idx (input)))
5203 {
5204 token->type = CHARACTER;
5205@@ -1805,7 +1814,7 @@
5206 token->opr.c = c2;
5207 token->type = CHARACTER;
5208 #ifdef RE_ENABLE_I18N
5209- if (input->mb_cur_max > 1)
5210+ if (string_mb_cur_max (input) > 1)
5211 {
5212 wint_t wc = re_string_wchar_at (input,
5213 re_string_cur_idx (input) + 1);
5214@@ -1919,7 +1928,7 @@
5215
5216 token->type = CHARACTER;
5217 #ifdef RE_ENABLE_I18N
5218- if (input->mb_cur_max > 1)
5219+ if (string_mb_cur_max (input) > 1)
5220 {
5221 wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
5222 token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
5223@@ -2019,7 +2028,7 @@
5224 token->opr.c = c;
5225
5226 #ifdef RE_ENABLE_I18N
5227- if (input->mb_cur_max > 1 &&
5228+ if (string_mb_cur_max (input) > 1 &&
5229 !re_string_first_byte (input, re_string_cur_idx (input)))
5230 {
5231 token->type = CHARACTER;
5232@@ -2242,7 +2251,7 @@
5233 return NULL;
5234 }
5235 #ifdef RE_ENABLE_I18N
5236- if (dfa->mb_cur_max > 1)
5237+ if (dfa_mb_cur_max (dfa) > 1)
5238 {
5239 while (!re_string_eoi (regexp)
5240 && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
5241@@ -2380,7 +2389,7 @@
5242 *err = REG_ESPACE;
5243 return NULL;
5244 }
5245- if (dfa->mb_cur_max > 1)
5246+ if (dfa_mb_cur_max (dfa) > 1)
5247 dfa->has_mb_node = 1;
5248 break;
5249 case OP_WORD:
5250@@ -2686,7 +2695,7 @@
5251 However, for !_LIBC we have no collation elements: if the
5252 character set is single byte, the single byte character set
5253 that we build below suffices. parse_bracket_exp passes
5254- no MBCSET if dfa->mb_cur_max == 1. */
5255+ no MBCSET if dfa_mb_cur_max (dfa) == 1. */
5256 if (mbcset)
5257 {
5258 /* Check the space of the arrays. */
5259@@ -2782,7 +2791,13 @@
5260 reg_syntax_t syntax, reg_errcode_t *err)
5261 {
5262 #ifdef _LIBC
5263+#if __OPTION_EGLIBC_LOCALE_CODE
5264 const unsigned char *collseqmb;
5265+# define COLLSEQMB_LOOKUP(ix) (collseqmb[(ix)])
5266+#else
5267+# define COLLSEQMB_LOOKUP(ix) (ix)
5268+#endif
5269+
5270 const char *collseqwc;
5271 uint32_t nrules;
5272 int32_t table_size;
5273@@ -2830,18 +2845,20 @@
5274 if (MB_CUR_MAX == 1)
5275 */
5276 if (nrules == 0)
5277- return collseqmb[br_elem->opr.ch];
5278+ return COLLSEQMB_LOOKUP (br_elem->opr.ch);
5279 else
5280 {
5281 wint_t wc = __btowc (br_elem->opr.ch);
5282 return __collseq_table_lookup (collseqwc, wc);
5283 }
5284 }
5285+#if __OPTION_EGLIBC_LOCALE_CODE
5286 else if (br_elem->type == MB_CHAR)
5287 {
5288 if (nrules != 0)
5289 return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
5290 }
5291+#endif
5292 else if (br_elem->type == COLL_SYM)
5293 {
5294 size_t sym_name_len = strlen ((char *) br_elem->opr.name);
5295@@ -2872,11 +2889,11 @@
5296 {
5297 /* No valid character. Match it as a single byte
5298 character. */
5299- return collseqmb[br_elem->opr.name[0]];
5300+ return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
5301 }
5302 }
5303 else if (sym_name_len == 1)
5304- return collseqmb[br_elem->opr.name[0]];
5305+ return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
5306 }
5307 return UINT_MAX;
5308 }
5309@@ -2916,7 +2933,7 @@
5310 However, if we have no collation elements, and the character set
5311 is single byte, the single byte character set that we
5312 build below suffices. */
5313- if (nrules > 0 || dfa->mb_cur_max > 1)
5314+ if (nrules > 0 || dfa_mb_cur_max (dfa) > 1)
5315 {
5316 /* Check the space of the arrays. */
5317 if (BE (*range_alloc == mbcset->nranges, 0))
5318@@ -2953,7 +2970,7 @@
5319 if (MB_CUR_MAX == 1)
5320 */
5321 if (nrules == 0)
5322- ch_collseq = collseqmb[ch];
5323+ ch_collseq = COLLSEQMB_LOOKUP (ch);
5324 else
5325 ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
5326 if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
5327@@ -3031,7 +3048,10 @@
5328 re_bitset_ptr_t sbcset;
5329 #ifdef RE_ENABLE_I18N
5330 re_charset_t *mbcset;
5331- int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
5332+ int coll_sym_alloc = 0, range_alloc = 0;
5333+#if __OPTION_EGLIBC_LOCALE_CODE
5334+ int mbchar_alloc = 0;
5335+#endif
5336 int equiv_class_alloc = 0, char_class_alloc = 0;
5337 #endif /* not RE_ENABLE_I18N */
5338 int non_match = 0;
5339@@ -3039,9 +3059,15 @@
5340 int token_len;
5341 int first_round = 1;
5342 #ifdef _LIBC
5343+#if __OPTION_EGLIBC_LOCALE_CODE
5344 collseqmb = (const unsigned char *)
5345 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
5346 nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
5347+#else
5348+ /* This is true when OPTION_EGLIBC_LOCALE_CODE is disabled, but the
5349+ compiler can't figure that out. */
5350+ nrules = 0;
5351+#endif
5352 if (nrules)
5353 {
5354 /*
5355@@ -3169,7 +3195,7 @@
5356 #else
5357 # ifdef RE_ENABLE_I18N
5358 *err = build_range_exp (sbcset,
5359- dfa->mb_cur_max > 1 ? mbcset : NULL,
5360+ dfa_mb_cur_max (dfa) > 1 ? mbcset : NULL,
5361 &range_alloc, &start_elem, &end_elem);
5362 # else
5363 *err = build_range_exp (sbcset, &start_elem, &end_elem);
5364@@ -3185,7 +3211,7 @@
5365 case SB_CHAR:
5366 bitset_set (sbcset, start_elem.opr.ch);
5367 break;
5368-#ifdef RE_ENABLE_I18N
5369+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
5370 case MB_CHAR:
5371 /* Check whether the array has enough space. */
5372 if (BE (mbchar_alloc == mbcset->nmbchars, 0))
5373@@ -3203,7 +3229,7 @@
5374 }
5375 mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
5376 break;
5377-#endif /* RE_ENABLE_I18N */
5378+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
5379 case EQUIV_CLASS:
5380 *err = build_equiv_class (sbcset,
5381 #ifdef RE_ENABLE_I18N
5382@@ -3253,11 +3279,11 @@
5383
5384 #ifdef RE_ENABLE_I18N
5385 /* Ensure only single byte characters are set. */
5386- if (dfa->mb_cur_max > 1)
5387+ if (dfa_mb_cur_max (dfa) > 1)
5388 bitset_mask (sbcset, dfa->sb_char);
5389
5390 if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
5391- || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
5392+ || mbcset->nranges || (dfa_mb_cur_max (dfa) > 1 && (mbcset->nchar_classes
5393 || mbcset->non_match)))
5394 {
5395 bin_tree_t *mbc_tree;
5396@@ -3326,7 +3352,7 @@
5397 re_token_t *token, int token_len, re_dfa_t *dfa,
5398 reg_syntax_t syntax, int accept_hyphen)
5399 {
5400-#ifdef RE_ENABLE_I18N
5401+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
5402 int cur_char_size;
5403 cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
5404 if (cur_char_size > 1)
5405@@ -3336,7 +3362,7 @@
5406 re_string_skip_bytes (regexp, cur_char_size);
5407 return REG_NOERROR;
5408 }
5409-#endif /* RE_ENABLE_I18N */
5410+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
5411 re_string_skip_bytes (regexp, token_len); /* Skip a token. */
5412 if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
5413 || token->type == OP_OPEN_EQUIV_CLASS)
5414@@ -3416,7 +3442,9 @@
5415 build_equiv_class (bitset_t sbcset, const unsigned char *name)
5416 #endif /* not RE_ENABLE_I18N */
5417 {
5418-#ifdef _LIBC
5419+ /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C locale
5420+ is supported; it has no collation rules. */
5421+#if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
5422 uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
5423 if (nrules != 0)
5424 {
5425@@ -3488,7 +3516,7 @@
5426 mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
5427 }
5428 else
5429-#endif /* _LIBC */
5430+#endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
5431 {
5432 if (BE (strlen ((const char *) name) != 1, 0))
5433 return REG_ECOLLATE;
5434@@ -3522,7 +3550,7 @@
5435 && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
5436 name = "alpha";
5437
5438-#ifdef RE_ENABLE_I18N
5439+#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
5440 /* Check the space of the arrays. */
5441 if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
5442 {
5443@@ -3538,7 +3566,7 @@
5444 *char_class_alloc = new_char_class_alloc;
5445 }
5446 mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
5447-#endif /* RE_ENABLE_I18N */
5448+#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
5449
5450 #define BUILD_CHARCLASS_LOOP(ctype_func) \
5451 do { \
5452@@ -3649,7 +3677,7 @@
5453
5454 #ifdef RE_ENABLE_I18N
5455 /* Ensure only single byte characters are set. */
5456- if (dfa->mb_cur_max > 1)
5457+ if (dfa_mb_cur_max (dfa) > 1)
5458 bitset_mask (sbcset, dfa->sb_char);
5459 #endif
5460
5461@@ -3661,7 +3689,7 @@
5462 goto build_word_op_espace;
5463
5464 #ifdef RE_ENABLE_I18N
5465- if (dfa->mb_cur_max > 1)
5466+ if (dfa_mb_cur_max (dfa) > 1)
5467 {
5468 bin_tree_t *mbc_tree;
5469 /* Build a tree for complex bracket. */
5470Index: git/posix/regexec.c
5471===================================================================
5472--- git.orig/posix/regexec.c 2014-08-29 20:00:53.268070587 -0700
5473+++ git/posix/regexec.c 2014-08-29 20:01:15.224070587 -0700
5474@@ -18,6 +18,7 @@
5475 <http://www.gnu.org/licenses/>. */
5476
5477 #include <stdint.h>
5478+#include <gnu/option-groups.h>
5479
5480 static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
5481 int n) internal_function;
5482@@ -186,11 +187,11 @@
5483 static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
5484 const re_string_t *input, int idx)
5485 internal_function;
5486-# ifdef _LIBC
5487+# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
5488 static unsigned int find_collation_sequence_value (const unsigned char *mbs,
5489 size_t name_len)
5490 internal_function;
5491-# endif /* _LIBC */
5492+# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
5493 #endif /* RE_ENABLE_I18N */
5494 static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
5495 const re_dfastate_t *state,
5496@@ -255,25 +256,9 @@
5497 return err != REG_NOERROR;
5498 }
5499
5500-#ifdef _LIBC
5501-# include <shlib-compat.h>
5502-versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
5503-
5504-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
5505-__typeof__ (__regexec) __compat_regexec;
5506-
5507-int
5508-attribute_compat_text_section
5509-__compat_regexec (const regex_t *__restrict preg,
5510- const char *__restrict string, size_t nmatch,
5511- regmatch_t pmatch[], int eflags)
5512-{
5513- return regexec (preg, string, nmatch, pmatch,
5514- eflags & (REG_NOTBOL | REG_NOTEOL));
5515-}
5516-compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
5517-# endif
5518-#endif
5519+/* EGLIBC: The code that used to be here was move to a separate file
5520+ so that it can be shared with xregex.c. */
5521+#include "regexec-compat.c"
5522
5523 /* Entry points for GNU code. */
5524
5525@@ -728,7 +713,7 @@
5526 incr = (range < 0) ? -1 : 1;
5527 left_lim = (range < 0) ? start + range : start;
5528 right_lim = (range < 0) ? start : start + range;
5529- sb = dfa->mb_cur_max == 1;
5530+ sb = dfa_mb_cur_max (dfa) == 1;
5531 match_kind =
5532 (fastmap
5533 ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
5534@@ -3448,7 +3433,7 @@
5535 if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
5536 goto out_free;
5537
5538- if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
5539+ if (dest_states[i] != dest_states_word[i] && dfa_mb_cur_max (dfa) > 1)
5540 need_word_trtable = 1;
5541
5542 dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
5543@@ -3590,7 +3575,7 @@
5544 else if (type == OP_PERIOD)
5545 {
5546 #ifdef RE_ENABLE_I18N
5547- if (dfa->mb_cur_max > 1)
5548+ if (dfa_mb_cur_max (dfa) > 1)
5549 bitset_merge (accepts, dfa->sb_char);
5550 else
5551 #endif
5552@@ -3641,7 +3626,7 @@
5553 continue;
5554 }
5555 #ifdef RE_ENABLE_I18N
5556- if (dfa->mb_cur_max > 1)
5557+ if (dfa_mb_cur_max (dfa) > 1)
5558 for (j = 0; j < BITSET_WORDS; ++j)
5559 any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
5560 else
5561@@ -3660,7 +3645,7 @@
5562 continue;
5563 }
5564 #ifdef RE_ENABLE_I18N
5565- if (dfa->mb_cur_max > 1)
5566+ if (dfa_mb_cur_max (dfa) > 1)
5567 for (j = 0; j < BITSET_WORDS; ++j)
5568 any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
5569 else
5570@@ -3832,12 +3817,6 @@
5571 if (node->type == COMPLEX_BRACKET)
5572 {
5573 const re_charset_t *cset = node->opr.mbcset;
5574-# ifdef _LIBC
5575- const unsigned char *pin
5576- = ((const unsigned char *) re_string_get_buffer (input) + str_idx);
5577- int j;
5578- uint32_t nrules;
5579-# endif /* _LIBC */
5580 int match_len = 0;
5581 wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
5582 ? re_string_wchar_at (input, str_idx) : 0);
5583@@ -3849,6 +3828,7 @@
5584 match_len = char_len;
5585 goto check_node_accept_bytes_match;
5586 }
5587+#if __OPTION_EGLIBC_LOCALE_CODE
5588 /* match with character_class? */
5589 for (i = 0; i < cset->nchar_classes; ++i)
5590 {
5591@@ -3859,8 +3839,16 @@
5592 goto check_node_accept_bytes_match;
5593 }
5594 }
5595+#endif
5596+
5597+ /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C
5598+ locale is supported; it has no collation rules. */
5599+# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
5600+ const unsigned char *pin
5601+ = ((const unsigned char *) re_string_get_buffer (input) + str_idx);
5602+ int j;
5603+ uint32_t nrules;
5604
5605-# ifdef _LIBC
5606 nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
5607 if (nrules != 0)
5608 {
5609@@ -3953,8 +3941,12 @@
5610 }
5611 }
5612 else
5613-# endif /* _LIBC */
5614+# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
5615 {
5616+ /* In the _LIBC version, if OPTION_EGLIBC_LOCALE_CODE is
5617+ disabled, there can be no multibyte range endpoints, and
5618+ cset->nranges is always zero. */
5619+#if __OPTION_EGLIBC_LOCALE_CODE
5620 /* match with range expression? */
5621 #if __GNUC__ >= 2
5622 wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
5623@@ -3973,6 +3965,7 @@
5624 goto check_node_accept_bytes_match;
5625 }
5626 }
5627+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
5628 }
5629 check_node_accept_bytes_match:
5630 if (!cset->non_match)
5631@@ -3988,7 +3981,7 @@
5632 return 0;
5633 }
5634
5635-# ifdef _LIBC
5636+# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
5637 static unsigned int
5638 internal_function
5639 find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
5640@@ -4046,7 +4039,7 @@
5641 return UINT_MAX;
5642 }
5643 }
5644-# endif /* _LIBC */
5645+# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
5646 #endif /* RE_ENABLE_I18N */
5647
5648 /* Check whether the node accepts the byte which is IDX-th
5649@@ -4137,7 +4130,7 @@
5650 if (pstr->icase)
5651 {
5652 #ifdef RE_ENABLE_I18N
5653- if (pstr->mb_cur_max > 1)
5654+ if (string_mb_cur_max (pstr) > 1)
5655 {
5656 ret = build_wcs_upper_buffer (pstr);
5657 if (BE (ret != REG_NOERROR, 0))
5658@@ -4150,7 +4143,7 @@
5659 else
5660 {
5661 #ifdef RE_ENABLE_I18N
5662- if (pstr->mb_cur_max > 1)
5663+ if (string_mb_cur_max (pstr) > 1)
5664 build_wcs_buffer (pstr);
5665 else
5666 #endif /* RE_ENABLE_I18N */
5667Index: git/posix/regexec-compat.c
5668===================================================================
5669--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5670+++ git/posix/regexec-compat.c 2014-08-29 20:01:15.224070587 -0700
5671@@ -0,0 +1,39 @@
5672+/* Extended regular expression matching and search library.
5673+ Copyright (C) 2008 Free Software Foundation, Inc.
5674+ This file is part of the GNU C Library.
5675+ Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
5676+
5677+ The GNU C Library is free software; you can redistribute it and/or
5678+ modify it under the terms of the GNU Lesser General Public
5679+ License as published by the Free Software Foundation; either
5680+ version 2.1 of the License, or (at your option) any later version.
5681+
5682+ The GNU C Library is distributed in the hope that it will be useful,
5683+ but WITHOUT ANY WARRANTY; without even the implied warranty of
5684+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5685+ Lesser General Public License for more details.
5686+
5687+ You should have received a copy of the GNU Lesser General Public
5688+ License along with the GNU C Library; if not, write to the Free
5689+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
5690+ 02111-1307 USA. */
5691+
5692+#ifdef _LIBC
5693+# include <shlib-compat.h>
5694+versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
5695+
5696+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
5697+__typeof__ (__regexec) __compat_regexec;
5698+
5699+int
5700+attribute_compat_text_section
5701+__compat_regexec (const regex_t *__restrict preg,
5702+ const char *__restrict string, size_t nmatch,
5703+ regmatch_t pmatch[], int eflags)
5704+{
5705+ return regexec (preg, string, nmatch, pmatch,
5706+ eflags & (REG_NOTBOL | REG_NOTEOL));
5707+}
5708+compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
5709+# endif
5710+#endif
5711Index: git/posix/regex.h
5712===================================================================
5713--- git.orig/posix/regex.h 2014-08-29 20:00:53.264070587 -0700
5714+++ git/posix/regex.h 2014-08-29 20:01:15.224070587 -0700
5715@@ -21,6 +21,7 @@
5716 #define _REGEX_H 1
5717
5718 #include <sys/types.h>
5719+#include <gnu/option-groups.h>
5720
5721 /* Allow the use in C++ code. */
5722 #ifdef __cplusplus
5723@@ -156,6 +157,8 @@
5724 treated as 'a\{1'. */
5725 # define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
5726
5727+/* EGLIBC: Old regex implementation does not support these. */
5728+# if __OPTION_POSIX_REGEXP_GLIBC
5729 /* If this bit is set, then ignore case when matching.
5730 If not set, then case is significant. */
5731 # define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
5732@@ -172,6 +175,7 @@
5733 /* If this bit is set, then no_sub will be set to 1 during
5734 re_compile_pattern. */
5735 # define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
5736+# endif /* __OPTION_POSIX_REGEXP_GLIBC */
5737 #endif
5738
5739 /* This global variable defines the particular regexp syntax to use (for
5740@@ -231,8 +235,13 @@
5741 (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
5742 | RE_INTERVALS | RE_NO_EMPTY_RANGES)
5743
5744+#if __OPTION_POSIX_REGEXP_GLIBC
5745 #define RE_SYNTAX_POSIX_BASIC \
5746 (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
5747+#else
5748+#define RE_SYNTAX_POSIX_BASIC \
5749+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
5750+#endif
5751
5752 /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
5753 RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
5754@@ -298,9 +307,11 @@
5755 /* Like REG_NOTBOL, except for the end-of-line. */
5756 #define REG_NOTEOL (1 << 1)
5757
5758+#if __OPTION_POSIX_REGEXP_GLIBC
5759 /* Use PMATCH[0] to delimit the start and end of the search in the
5760 buffer. */
5761 #define REG_STARTEND (1 << 2)
5762+#endif
5763
5764
5765 /* If any error codes are removed, changed, or added, update the
5766Index: git/posix/regex_internal.c
5767===================================================================
5768--- git.orig/posix/regex_internal.c 2014-08-29 20:00:53.264070587 -0700
5769+++ git/posix/regex_internal.c 2014-08-29 20:01:15.224070587 -0700
5770@@ -43,8 +43,8 @@
5771 int init_buf_len;
5772
5773 /* Ensure at least one character fits into the buffers. */
5774- if (init_len < dfa->mb_cur_max)
5775- init_len = dfa->mb_cur_max;
5776+ if (init_len < dfa_mb_cur_max (dfa))
5777+ init_len = dfa_mb_cur_max (dfa);
5778 init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
5779 re_string_construct_common (str, len, pstr, trans, icase, dfa);
5780
5781@@ -55,7 +55,7 @@
5782 pstr->word_char = dfa->word_char;
5783 pstr->word_ops_used = dfa->word_ops_used;
5784 pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
5785- pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
5786+ pstr->valid_len = (pstr->mbs_allocated || dfa_mb_cur_max (dfa) > 1) ? 0 : len;
5787 pstr->valid_raw_len = pstr->valid_len;
5788 return REG_NOERROR;
5789 }
5790@@ -82,7 +82,7 @@
5791 if (icase)
5792 {
5793 #ifdef RE_ENABLE_I18N
5794- if (dfa->mb_cur_max > 1)
5795+ if (dfa_mb_cur_max (dfa) > 1)
5796 {
5797 while (1)
5798 {
5799@@ -91,7 +91,7 @@
5800 return ret;
5801 if (pstr->valid_raw_len >= len)
5802 break;
5803- if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
5804+ if (pstr->bufs_len > pstr->valid_len + dfa_mb_cur_max (dfa))
5805 break;
5806 ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
5807 if (BE (ret != REG_NOERROR, 0))
5808@@ -105,7 +105,7 @@
5809 else
5810 {
5811 #ifdef RE_ENABLE_I18N
5812- if (dfa->mb_cur_max > 1)
5813+ if (dfa_mb_cur_max (dfa) > 1)
5814 build_wcs_buffer (pstr);
5815 else
5816 #endif /* RE_ENABLE_I18N */
5817@@ -130,7 +130,7 @@
5818 re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
5819 {
5820 #ifdef RE_ENABLE_I18N
5821- if (pstr->mb_cur_max > 1)
5822+ if (string_mb_cur_max (pstr) > 1)
5823 {
5824 wint_t *new_wcs;
5825
5826@@ -177,7 +177,7 @@
5827 pstr->trans = trans;
5828 pstr->icase = icase ? 1 : 0;
5829 pstr->mbs_allocated = (trans != NULL || icase);
5830- pstr->mb_cur_max = dfa->mb_cur_max;
5831+ pstr->mb_cur_max = dfa_mb_cur_max (dfa);
5832 pstr->is_utf8 = dfa->is_utf8;
5833 pstr->map_notascii = dfa->map_notascii;
5834 pstr->stop = pstr->len;
5835@@ -203,7 +203,7 @@
5836 {
5837 #ifdef _LIBC
5838 unsigned char buf[MB_LEN_MAX];
5839- assert (MB_LEN_MAX >= pstr->mb_cur_max);
5840+ assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
5841 #else
5842 unsigned char buf[64];
5843 #endif
5844@@ -226,7 +226,7 @@
5845 {
5846 int i, ch;
5847
5848- for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
5849+ for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
5850 {
5851 ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
5852 buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
5853@@ -275,7 +275,7 @@
5854 size_t mbclen;
5855 #ifdef _LIBC
5856 char buf[MB_LEN_MAX];
5857- assert (MB_LEN_MAX >= pstr->mb_cur_max);
5858+ assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
5859 #else
5860 char buf[64];
5861 #endif
5862@@ -369,7 +369,7 @@
5863 {
5864 int i, ch;
5865
5866- for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
5867+ for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
5868 {
5869 ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
5870 buf[i] = pstr->trans[ch];
5871@@ -567,8 +567,9 @@
5872 }
5873
5874 /* This function re-construct the buffers.
5875- Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
5876- convert to upper case in case of REG_ICASE, apply translation. */
5877+ Concretely, convert to wide character in case of
5878+ string_mb_cur_max (pstr) > 1, convert to upper case in case of
5879+ REG_ICASE, apply translation. */
5880
5881 static reg_errcode_t
5882 internal_function __attribute_warn_unused_result__
5883@@ -579,7 +580,7 @@
5884 {
5885 /* Reset buffer. */
5886 #ifdef RE_ENABLE_I18N
5887- if (pstr->mb_cur_max > 1)
5888+ if (string_mb_cur_max (pstr) > 1)
5889 memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
5890 #endif /* RE_ENABLE_I18N */
5891 pstr->len = pstr->raw_len;
5892@@ -670,7 +671,7 @@
5893 pstr->tip_context = re_string_context_at (pstr, offset - 1,
5894 eflags);
5895 #ifdef RE_ENABLE_I18N
5896- if (pstr->mb_cur_max > 1)
5897+ if (string_mb_cur_max (pstr) > 1)
5898 memmove (pstr->wcs, pstr->wcs + offset,
5899 (pstr->valid_len - offset) * sizeof (wint_t));
5900 #endif /* RE_ENABLE_I18N */
5901@@ -699,7 +700,7 @@
5902 #endif
5903 pstr->valid_len = 0;
5904 #ifdef RE_ENABLE_I18N
5905- if (pstr->mb_cur_max > 1)
5906+ if (string_mb_cur_max (pstr) > 1)
5907 {
5908 int wcs_idx;
5909 wint_t wc = WEOF;
5910@@ -711,7 +712,7 @@
5911 /* Special case UTF-8. Multi-byte chars start with any
5912 byte other than 0x80 - 0xbf. */
5913 raw = pstr->raw_mbs + pstr->raw_mbs_idx;
5914- end = raw + (offset - pstr->mb_cur_max);
5915+ end = raw + (offset - string_mb_cur_max (pstr));
5916 if (end < pstr->raw_mbs)
5917 end = pstr->raw_mbs;
5918 p = raw + offset - 1;
5919@@ -803,7 +804,7 @@
5920
5921 /* Then build the buffers. */
5922 #ifdef RE_ENABLE_I18N
5923- if (pstr->mb_cur_max > 1)
5924+ if (string_mb_cur_max (pstr) > 1)
5925 {
5926 if (pstr->icase)
5927 {
5928@@ -841,7 +842,7 @@
5929 return re_string_peek_byte (pstr, idx);
5930
5931 #ifdef RE_ENABLE_I18N
5932- if (pstr->mb_cur_max > 1
5933+ if (string_mb_cur_max (pstr) > 1
5934 && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
5935 return re_string_peek_byte (pstr, idx);
5936 #endif
5937@@ -930,7 +931,7 @@
5938 return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
5939 : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
5940 #ifdef RE_ENABLE_I18N
5941- if (input->mb_cur_max > 1)
5942+ if (string_mb_cur_max (input) > 1)
5943 {
5944 wint_t wc;
5945 int wc_idx = idx;
5946@@ -1444,7 +1445,7 @@
5947 dfa->nodes[dfa->nodes_len].constraint = 0;
5948 #ifdef RE_ENABLE_I18N
5949 dfa->nodes[dfa->nodes_len].accept_mb =
5950- (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
5951+ (type == OP_PERIOD && dfa_mb_cur_max (dfa) > 1) || type == COMPLEX_BRACKET;
5952 #endif
5953 dfa->nexts[dfa->nodes_len] = -1;
5954 re_node_set_init_empty (dfa->edests + dfa->nodes_len);
5955Index: git/posix/regex_internal.h
5956===================================================================
5957--- git.orig/posix/regex_internal.h 2014-08-29 20:00:53.264070587 -0700
5958+++ git/posix/regex_internal.h 2014-08-29 20:01:15.224070587 -0700
5959@@ -26,6 +26,10 @@
5960 #include <stdlib.h>
5961 #include <string.h>
5962
5963+#if defined _LIBC
5964+# include <gnu/option-groups.h>
5965+#endif
5966+
5967 #if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
5968 # include <langinfo.h>
5969 #endif
5970@@ -370,6 +374,13 @@
5971 };
5972 typedef struct re_string_t re_string_t;
5973
5974+/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
5975+ help the compiler make use of that fact. */
5976+#if __OPTION_EGLIBC_LOCALE_CODE
5977+# define string_mb_cur_max(str) ((str)->mb_cur_max + 0)
5978+#else
5979+# define string_mb_cur_max(str) (1)
5980+#endif
5981
5982 struct re_dfa_t;
5983 typedef struct re_dfa_t re_dfa_t;
5984@@ -655,6 +666,14 @@
5985 __libc_lock_define (, lock)
5986 };
5987
5988+/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
5989+ help the compiler make use of that fact. */
5990+#if __OPTION_EGLIBC_LOCALE_CODE
5991+# define dfa_mb_cur_max(dfa) ((dfa)->mb_cur_max + 0)
5992+#else
5993+# define dfa_mb_cur_max(dfa) (1)
5994+#endif
5995+
5996 #define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
5997 #define re_node_set_remove(set,id) \
5998 (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
5999@@ -715,7 +734,7 @@
6000 re_string_char_size_at (const re_string_t *pstr, int idx)
6001 {
6002 int byte_idx;
6003- if (pstr->mb_cur_max == 1)
6004+ if (string_mb_cur_max (pstr) == 1)
6005 return 1;
6006 for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
6007 if (pstr->wcs[idx + byte_idx] != WEOF)
6008@@ -727,7 +746,7 @@
6009 internal_function __attribute__ ((pure, unused))
6010 re_string_wchar_at (const re_string_t *pstr, int idx)
6011 {
6012- if (pstr->mb_cur_max == 1)
6013+ if (string_mb_cur_max (pstr) == 1)
6014 return (wint_t) pstr->mbs[idx];
6015 return (wint_t) pstr->wcs[idx];
6016 }
6017Index: git/posix/xregex.c
6018===================================================================
6019--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6020+++ git/posix/xregex.c 2014-08-29 20:01:15.228070587 -0700
6021@@ -0,0 +1,8212 @@
6022+/* Extended regular expression matching and search library,
6023+ version 0.12.
6024+ (Implements POSIX draft P1003.2/D11.2, except for some of the
6025+ internationalization features.)
6026+
6027+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
6028+ 2002, 2005 Free Software Foundation, Inc.
6029+ This file is part of the GNU C Library.
6030+
6031+ The GNU C Library is free software; you can redistribute it and/or
6032+ modify it under the terms of the GNU Lesser General Public
6033+ License as published by the Free Software Foundation; either
6034+ version 2.1 of the License, or (at your option) any later version.
6035+
6036+ The GNU C Library is distributed in the hope that it will be useful,
6037+ but WITHOUT ANY WARRANTY; without even the implied warranty of
6038+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6039+ Lesser General Public License for more details.
6040+
6041+ You should have received a copy of the GNU Lesser General Public
6042+ License along with the GNU C Library; if not, write to the Free
6043+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
6044+ 02110-1301 USA. */
6045+
6046+/* AIX requires this to be the first thing in the file. */
6047+#if defined _AIX && !defined __GNUC__ && !defined REGEX_MALLOC
6048+ #pragma alloca
6049+#endif
6050+
6051+#undef _GNU_SOURCE
6052+#define _GNU_SOURCE
6053+
6054+#ifndef INSIDE_RECURSION
6055+# ifdef HAVE_CONFIG_H
6056+# include <config.h>
6057+# endif
6058+#endif
6059+
6060+/*#include <ansidecl.h>*/
6061+
6062+#ifndef INSIDE_RECURSION
6063+
6064+# if defined STDC_HEADERS && !defined emacs
6065+# include <stddef.h>
6066+# else
6067+/* We need this for `regex.h', and perhaps for the Emacs include files. */
6068+# include <sys/types.h>
6069+# endif
6070+
6071+# define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC)
6072+
6073+/* For platform which support the ISO C amendement 1 functionality we
6074+ support user defined character classes. */
6075+# if WIDE_CHAR_SUPPORT
6076+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
6077+# include <wchar.h>
6078+# include <wctype.h>
6079+# endif
6080+
6081+# ifdef _LIBC
6082+/* We have to keep the namespace clean. */
6083+# define regfree(preg) __regfree (preg)
6084+# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
6085+# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
6086+# define regerror(errcode, preg, errbuf, errbuf_size) \
6087+ __regerror(errcode, preg, errbuf, errbuf_size)
6088+# define re_set_registers(bu, re, nu, st, en) \
6089+ __re_set_registers (bu, re, nu, st, en)
6090+# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
6091+ __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
6092+# define re_match(bufp, string, size, pos, regs) \
6093+ __re_match (bufp, string, size, pos, regs)
6094+# define re_search(bufp, string, size, startpos, range, regs) \
6095+ __re_search (bufp, string, size, startpos, range, regs)
6096+# define re_compile_pattern(pattern, length, bufp) \
6097+ __re_compile_pattern (pattern, length, bufp)
6098+# define re_set_syntax(syntax) __re_set_syntax (syntax)
6099+# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
6100+ __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
6101+# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
6102+
6103+# define btowc __btowc
6104+
6105+/* We are also using some library internals. */
6106+# include <locale/localeinfo.h>
6107+# include <locale/elem-hash.h>
6108+# include <langinfo.h>
6109+# include <locale/coll-lookup.h>
6110+# endif
6111+
6112+/* This is for other GNU distributions with internationalized messages. */
6113+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
6114+# include <libintl.h>
6115+# ifdef _LIBC
6116+# undef gettext
6117+# define gettext(msgid) __dcgettext ("libc", msgid, LC_MESSAGES)
6118+# endif
6119+# else
6120+# define gettext(msgid) (msgid)
6121+# endif
6122+
6123+# ifndef gettext_noop
6124+/* This define is so xgettext can find the internationalizable
6125+ strings. */
6126+# define gettext_noop(String) String
6127+# endif
6128+
6129+/* The `emacs' switch turns on certain matching commands
6130+ that make sense only in Emacs. */
6131+# ifdef emacs
6132+
6133+# include "lisp.h"
6134+# include "buffer.h"
6135+# include "syntax.h"
6136+
6137+# else /* not emacs */
6138+
6139+/* If we are not linking with Emacs proper,
6140+ we can't use the relocating allocator
6141+ even if config.h says that we can. */
6142+# undef REL_ALLOC
6143+
6144+# if defined STDC_HEADERS || defined _LIBC
6145+# include <stdlib.h>
6146+# else
6147+char *malloc ();
6148+char *realloc ();
6149+# endif
6150+
6151+/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
6152+ If nothing else has been done, use the method below. */
6153+# ifdef INHIBIT_STRING_HEADER
6154+# if !(defined HAVE_BZERO && defined HAVE_BCOPY)
6155+# if !defined bzero && !defined bcopy
6156+# undef INHIBIT_STRING_HEADER
6157+# endif
6158+# endif
6159+# endif
6160+
6161+/* This is the normal way of making sure we have a bcopy and a bzero.
6162+ This is used in most programs--a few other programs avoid this
6163+ by defining INHIBIT_STRING_HEADER. */
6164+# ifndef INHIBIT_STRING_HEADER
6165+# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC
6166+# include <string.h>
6167+# ifndef bzero
6168+# ifndef _LIBC
6169+# define bzero(s, n) (memset (s, '\0', n), (s))
6170+# else
6171+# define bzero(s, n) __bzero (s, n)
6172+# endif
6173+# endif
6174+# else
6175+# include <strings.h>
6176+# ifndef memcmp
6177+# define memcmp(s1, s2, n) bcmp (s1, s2, n)
6178+# endif
6179+# ifndef memcpy
6180+# define memcpy(d, s, n) (bcopy (s, d, n), (d))
6181+# endif
6182+# endif
6183+# endif
6184+
6185+/* Define the syntax stuff for \<, \>, etc. */
6186+
6187+/* This must be nonzero for the wordchar and notwordchar pattern
6188+ commands in re_match_2. */
6189+# ifndef Sword
6190+# define Sword 1
6191+# endif
6192+
6193+# ifdef SWITCH_ENUM_BUG
6194+# define SWITCH_ENUM_CAST(x) ((int)(x))
6195+# else
6196+# define SWITCH_ENUM_CAST(x) (x)
6197+# endif
6198+
6199+# endif /* not emacs */
6200+
6201+# if defined _LIBC || HAVE_LIMITS_H
6202+# include <limits.h>
6203+# endif
6204+
6205+# ifndef MB_LEN_MAX
6206+# define MB_LEN_MAX 1
6207+# endif
6208+
6209+/* Get the interface, including the syntax bits. */
6210+# include "regex.h"
6211+
6212+/* isalpha etc. are used for the character classes. */
6213+# include <ctype.h>
6214+
6215+/* Jim Meyering writes:
6216+
6217+ "... Some ctype macros are valid only for character codes that
6218+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
6219+ using /bin/cc or gcc but without giving an ansi option). So, all
6220+ ctype uses should be through macros like ISPRINT... If
6221+ STDC_HEADERS is defined, then autoconf has verified that the ctype
6222+ macros don't need to be guarded with references to isascii. ...
6223+ Defining isascii to 1 should let any compiler worth its salt
6224+ eliminate the && through constant folding."
6225+ Solaris defines some of these symbols so we must undefine them first. */
6226+
6227+# undef ISASCII
6228+# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
6229+# define ISASCII(c) 1
6230+# else
6231+# define ISASCII(c) isascii(c)
6232+# endif
6233+
6234+# ifdef isblank
6235+# define ISBLANK(c) (ISASCII (c) && isblank (c))
6236+# else
6237+# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
6238+# endif
6239+# ifdef isgraph
6240+# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
6241+# else
6242+# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
6243+# endif
6244+
6245+# undef ISPRINT
6246+# define ISPRINT(c) (ISASCII (c) && isprint (c))
6247+# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
6248+# define ISALNUM(c) (ISASCII (c) && isalnum (c))
6249+# define ISALPHA(c) (ISASCII (c) && isalpha (c))
6250+# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
6251+# define ISLOWER(c) (ISASCII (c) && islower (c))
6252+# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
6253+# define ISSPACE(c) (ISASCII (c) && isspace (c))
6254+# define ISUPPER(c) (ISASCII (c) && isupper (c))
6255+# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
6256+
6257+# ifdef _tolower
6258+# define TOLOWER(c) _tolower(c)
6259+# else
6260+# define TOLOWER(c) tolower(c)
6261+# endif
6262+
6263+# ifndef NULL
6264+# define NULL (void *)0
6265+# endif
6266+
6267+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
6268+ since ours (we hope) works properly with all combinations of
6269+ machines, compilers, `char' and `unsigned char' argument types.
6270+ (Per Bothner suggested the basic approach.) */
6271+# undef SIGN_EXTEND_CHAR
6272+# if __STDC__
6273+# define SIGN_EXTEND_CHAR(c) ((signed char) (c))
6274+# else /* not __STDC__ */
6275+/* As in Harbison and Steele. */
6276+# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
6277+# endif
6278+
6279+# ifndef emacs
6280+/* How many characters in the character set. */
6281+# define CHAR_SET_SIZE 256
6282+
6283+# ifdef SYNTAX_TABLE
6284+
6285+extern char *re_syntax_table;
6286+
6287+# else /* not SYNTAX_TABLE */
6288+
6289+static char re_syntax_table[CHAR_SET_SIZE];
6290+
6291+static void init_syntax_once (void);
6292+
6293+static void
6294+init_syntax_once (void)
6295+{
6296+ register int c;
6297+ static int done = 0;
6298+
6299+ if (done)
6300+ return;
6301+ bzero (re_syntax_table, sizeof re_syntax_table);
6302+
6303+ for (c = 0; c < CHAR_SET_SIZE; ++c)
6304+ if (ISALNUM (c))
6305+ re_syntax_table[c] = Sword;
6306+
6307+ re_syntax_table['_'] = Sword;
6308+
6309+ done = 1;
6310+}
6311+
6312+# endif /* not SYNTAX_TABLE */
6313+
6314+# define SYNTAX(c) re_syntax_table[(unsigned char) (c)]
6315+
6316+# endif /* emacs */
6317+
6318+/* Integer type for pointers. */
6319+# if !defined _LIBC && !defined HAVE_UINTPTR_T
6320+typedef unsigned long int uintptr_t;
6321+# endif
6322+
6323+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
6324+ use `alloca' instead of `malloc'. This is because using malloc in
6325+ re_search* or re_match* could cause memory leaks when C-g is used in
6326+ Emacs; also, malloc is slower and causes storage fragmentation. On
6327+ the other hand, malloc is more portable, and easier to debug.
6328+
6329+ Because we sometimes use alloca, some routines have to be macros,
6330+ not functions -- `alloca'-allocated space disappears at the end of the
6331+ function it is called in. */
6332+
6333+# ifdef REGEX_MALLOC
6334+
6335+# define REGEX_ALLOCATE malloc
6336+# define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
6337+# define REGEX_FREE free
6338+
6339+# else /* not REGEX_MALLOC */
6340+
6341+/* Emacs already defines alloca, sometimes. */
6342+# ifndef alloca
6343+
6344+/* Make alloca work the best possible way. */
6345+# ifdef __GNUC__
6346+# define alloca __builtin_alloca
6347+# else /* not __GNUC__ */
6348+# if HAVE_ALLOCA_H
6349+# include <alloca.h>
6350+# endif /* HAVE_ALLOCA_H */
6351+# endif /* not __GNUC__ */
6352+
6353+# endif /* not alloca */
6354+
6355+# define REGEX_ALLOCATE alloca
6356+
6357+/* Assumes a `char *destination' variable. */
6358+# define REGEX_REALLOCATE(source, osize, nsize) \
6359+ (destination = (char *) alloca (nsize), \
6360+ memcpy (destination, source, osize))
6361+
6362+/* No need to do anything to free, after alloca. */
6363+# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */
6364+
6365+# endif /* not REGEX_MALLOC */
6366+
6367+/* Define how to allocate the failure stack. */
6368+
6369+# if defined REL_ALLOC && defined REGEX_MALLOC
6370+
6371+# define REGEX_ALLOCATE_STACK(size) \
6372+ r_alloc (&failure_stack_ptr, (size))
6373+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
6374+ r_re_alloc (&failure_stack_ptr, (nsize))
6375+# define REGEX_FREE_STACK(ptr) \
6376+ r_alloc_free (&failure_stack_ptr)
6377+
6378+# else /* not using relocating allocator */
6379+
6380+# ifdef REGEX_MALLOC
6381+
6382+# define REGEX_ALLOCATE_STACK malloc
6383+# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
6384+# define REGEX_FREE_STACK free
6385+
6386+# else /* not REGEX_MALLOC */
6387+
6388+# define REGEX_ALLOCATE_STACK alloca
6389+
6390+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
6391+ REGEX_REALLOCATE (source, osize, nsize)
6392+/* No need to explicitly free anything. */
6393+# define REGEX_FREE_STACK(arg)
6394+
6395+# endif /* not REGEX_MALLOC */
6396+# endif /* not using relocating allocator */
6397+
6398+
6399+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
6400+ `string1' or just past its end. This works if PTR is NULL, which is
6401+ a good thing. */
6402+# define FIRST_STRING_P(ptr) \
6403+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
6404+
6405+/* (Re)Allocate N items of type T using malloc, or fail. */
6406+# define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
6407+# define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
6408+# define RETALLOC_IF(addr, n, t) \
6409+ if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
6410+# define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
6411+
6412+# define BYTEWIDTH 8 /* In bits. */
6413+
6414+# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
6415+
6416+# undef MAX
6417+# undef MIN
6418+# define MAX(a, b) ((a) > (b) ? (a) : (b))
6419+# define MIN(a, b) ((a) < (b) ? (a) : (b))
6420+
6421+typedef char boolean;
6422+# define false 0
6423+# define true 1
6424+
6425+static reg_errcode_t byte_regex_compile (const char *pattern, size_t size,
6426+ reg_syntax_t syntax,
6427+ struct re_pattern_buffer *bufp);
6428+
6429+static int byte_re_match_2_internal (struct re_pattern_buffer *bufp,
6430+ const char *string1, int size1,
6431+ const char *string2, int size2,
6432+ int pos,
6433+ struct re_registers *regs,
6434+ int stop);
6435+static int byte_re_search_2 (struct re_pattern_buffer *bufp,
6436+ const char *string1, int size1,
6437+ const char *string2, int size2,
6438+ int startpos, int range,
6439+ struct re_registers *regs, int stop);
6440+static int byte_re_compile_fastmap (struct re_pattern_buffer *bufp);
6441+
6442+#ifdef MBS_SUPPORT
6443+static reg_errcode_t wcs_regex_compile (const char *pattern, size_t size,
6444+ reg_syntax_t syntax,
6445+ struct re_pattern_buffer *bufp);
6446+
6447+
6448+static int wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
6449+ const char *cstring1, int csize1,
6450+ const char *cstring2, int csize2,
6451+ int pos,
6452+ struct re_registers *regs,
6453+ int stop,
6454+ wchar_t *string1, int size1,
6455+ wchar_t *string2, int size2,
6456+ int *mbs_offset1, int *mbs_offset2);
6457+static int wcs_re_search_2 (struct re_pattern_buffer *bufp,
6458+ const char *string1, int size1,
6459+ const char *string2, int size2,
6460+ int startpos, int range,
6461+ struct re_registers *regs, int stop);
6462+static int wcs_re_compile_fastmap (struct re_pattern_buffer *bufp);
6463+#endif
6464+
6465+/* These are the command codes that appear in compiled regular
6466+ expressions. Some opcodes are followed by argument bytes. A
6467+ command code can specify any interpretation whatsoever for its
6468+ arguments. Zero bytes may appear in the compiled regular expression. */
6469+
6470+typedef enum
6471+{
6472+ no_op = 0,
6473+
6474+ /* Succeed right away--no more backtracking. */
6475+ succeed,
6476+
6477+ /* Followed by one byte giving n, then by n literal bytes. */
6478+ exactn,
6479+
6480+# ifdef MBS_SUPPORT
6481+ /* Same as exactn, but contains binary data. */
6482+ exactn_bin,
6483+# endif
6484+
6485+ /* Matches any (more or less) character. */
6486+ anychar,
6487+
6488+ /* Matches any one char belonging to specified set. First
6489+ following byte is number of bitmap bytes. Then come bytes
6490+ for a bitmap saying which chars are in. Bits in each byte
6491+ are ordered low-bit-first. A character is in the set if its
6492+ bit is 1. A character too large to have a bit in the map is
6493+ automatically not in the set. */
6494+ /* ifdef MBS_SUPPORT, following element is length of character
6495+ classes, length of collating symbols, length of equivalence
6496+ classes, length of character ranges, and length of characters.
6497+ Next, character class element, collating symbols elements,
6498+ equivalence class elements, range elements, and character
6499+ elements follow.
6500+ See regex_compile function. */
6501+ charset,
6502+
6503+ /* Same parameters as charset, but match any character that is
6504+ not one of those specified. */
6505+ charset_not,
6506+
6507+ /* Start remembering the text that is matched, for storing in a
6508+ register. Followed by one byte with the register number, in
6509+ the range 0 to one less than the pattern buffer's re_nsub
6510+ field. Then followed by one byte with the number of groups
6511+ inner to this one. (This last has to be part of the
6512+ start_memory only because we need it in the on_failure_jump
6513+ of re_match_2.) */
6514+ start_memory,
6515+
6516+ /* Stop remembering the text that is matched and store it in a
6517+ memory register. Followed by one byte with the register
6518+ number, in the range 0 to one less than `re_nsub' in the
6519+ pattern buffer, and one byte with the number of inner groups,
6520+ just like `start_memory'. (We need the number of inner
6521+ groups here because we don't have any easy way of finding the
6522+ corresponding start_memory when we're at a stop_memory.) */
6523+ stop_memory,
6524+
6525+ /* Match a duplicate of something remembered. Followed by one
6526+ byte containing the register number. */
6527+ duplicate,
6528+
6529+ /* Fail unless at beginning of line. */
6530+ begline,
6531+
6532+ /* Fail unless at end of line. */
6533+ endline,
6534+
6535+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
6536+ of string to be matched (if not). */
6537+ begbuf,
6538+
6539+ /* Analogously, for end of buffer/string. */
6540+ endbuf,
6541+
6542+ /* Followed by two byte relative address to which to jump. */
6543+ jump,
6544+
6545+ /* Same as jump, but marks the end of an alternative. */
6546+ jump_past_alt,
6547+
6548+ /* Followed by two-byte relative address of place to resume at
6549+ in case of failure. */
6550+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6551+ on_failure_jump,
6552+
6553+ /* Like on_failure_jump, but pushes a placeholder instead of the
6554+ current string position when executed. */
6555+ on_failure_keep_string_jump,
6556+
6557+ /* Throw away latest failure point and then jump to following
6558+ two-byte relative address. */
6559+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6560+ pop_failure_jump,
6561+
6562+ /* Change to pop_failure_jump if know won't have to backtrack to
6563+ match; otherwise change to jump. This is used to jump
6564+ back to the beginning of a repeat. If what follows this jump
6565+ clearly won't match what the repeat does, such that we can be
6566+ sure that there is no use backtracking out of repetitions
6567+ already matched, then we change it to a pop_failure_jump.
6568+ Followed by two-byte address. */
6569+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6570+ maybe_pop_jump,
6571+
6572+ /* Jump to following two-byte address, and push a dummy failure
6573+ point. This failure point will be thrown away if an attempt
6574+ is made to use it for a failure. A `+' construct makes this
6575+ before the first repeat. Also used as an intermediary kind
6576+ of jump when compiling an alternative. */
6577+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6578+ dummy_failure_jump,
6579+
6580+ /* Push a dummy failure point and continue. Used at the end of
6581+ alternatives. */
6582+ push_dummy_failure,
6583+
6584+ /* Followed by two-byte relative address and two-byte number n.
6585+ After matching N times, jump to the address upon failure. */
6586+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6587+ succeed_n,
6588+
6589+ /* Followed by two-byte relative address, and two-byte number n.
6590+ Jump to the address N times, then fail. */
6591+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6592+ jump_n,
6593+
6594+ /* Set the following two-byte relative address to the
6595+ subsequent two-byte number. The address *includes* the two
6596+ bytes of number. */
6597+ /* ifdef MBS_SUPPORT, the size of address is 1. */
6598+ set_number_at,
6599+
6600+ wordchar, /* Matches any word-constituent character. */
6601+ notwordchar, /* Matches any char that is not a word-constituent. */
6602+
6603+ wordbeg, /* Succeeds if at word beginning. */
6604+ wordend, /* Succeeds if at word end. */
6605+
6606+ wordbound, /* Succeeds if at a word boundary. */
6607+ notwordbound /* Succeeds if not at a word boundary. */
6608+
6609+# ifdef emacs
6610+ ,before_dot, /* Succeeds if before point. */
6611+ at_dot, /* Succeeds if at point. */
6612+ after_dot, /* Succeeds if after point. */
6613+
6614+ /* Matches any character whose syntax is specified. Followed by
6615+ a byte which contains a syntax code, e.g., Sword. */
6616+ syntaxspec,
6617+
6618+ /* Matches any character whose syntax is not that specified. */
6619+ notsyntaxspec
6620+# endif /* emacs */
6621+} re_opcode_t;
6622+#endif /* not INSIDE_RECURSION */
6623+
6624+
6625+#ifdef BYTE
6626+# define CHAR_T char
6627+# define UCHAR_T unsigned char
6628+# define COMPILED_BUFFER_VAR bufp->buffer
6629+# define OFFSET_ADDRESS_SIZE 2
6630+# define PREFIX(name) byte_##name
6631+# define ARG_PREFIX(name) name
6632+# define PUT_CHAR(c) putchar (c)
6633+#else
6634+# ifdef WCHAR
6635+# define CHAR_T wchar_t
6636+# define UCHAR_T wchar_t
6637+# define COMPILED_BUFFER_VAR wc_buffer
6638+# define OFFSET_ADDRESS_SIZE 1 /* the size which STORE_NUMBER macro use */
6639+# define CHAR_CLASS_SIZE ((__alignof__(wctype_t)+sizeof(wctype_t))/sizeof(CHAR_T)+1)
6640+# define PREFIX(name) wcs_##name
6641+# define ARG_PREFIX(name) c##name
6642+/* Should we use wide stream?? */
6643+# define PUT_CHAR(c) printf ("%C", c);
6644+# define TRUE 1
6645+# define FALSE 0
6646+# else
6647+# ifdef MBS_SUPPORT
6648+# define WCHAR
6649+# define INSIDE_RECURSION
6650+# include "xregex.c"
6651+# undef INSIDE_RECURSION
6652+# endif
6653+# define BYTE
6654+# define INSIDE_RECURSION
6655+# include "xregex.c"
6656+# undef INSIDE_RECURSION
6657+# endif
6658+#endif
6659+
6660+#ifdef INSIDE_RECURSION
6661+/* Common operations on the compiled pattern. */
6662+
6663+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
6664+/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */
6665+
6666+# ifdef WCHAR
6667+# define STORE_NUMBER(destination, number) \
6668+ do { \
6669+ *(destination) = (UCHAR_T)(number); \
6670+ } while (0)
6671+# else /* BYTE */
6672+# define STORE_NUMBER(destination, number) \
6673+ do { \
6674+ (destination)[0] = (number) & 0377; \
6675+ (destination)[1] = (number) >> 8; \
6676+ } while (0)
6677+# endif /* WCHAR */
6678+
6679+/* Same as STORE_NUMBER, except increment DESTINATION to
6680+ the byte after where the number is stored. Therefore, DESTINATION
6681+ must be an lvalue. */
6682+/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */
6683+
6684+# define STORE_NUMBER_AND_INCR(destination, number) \
6685+ do { \
6686+ STORE_NUMBER (destination, number); \
6687+ (destination) += OFFSET_ADDRESS_SIZE; \
6688+ } while (0)
6689+
6690+/* Put into DESTINATION a number stored in two contiguous bytes starting
6691+ at SOURCE. */
6692+/* ifdef MBS_SUPPORT, we store NUMBER in 1 element. */
6693+
6694+# ifdef WCHAR
6695+# define EXTRACT_NUMBER(destination, source) \
6696+ do { \
6697+ (destination) = *(source); \
6698+ } while (0)
6699+# else /* BYTE */
6700+# define EXTRACT_NUMBER(destination, source) \
6701+ do { \
6702+ (destination) = *(source) & 0377; \
6703+ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
6704+ } while (0)
6705+# endif
6706+
6707+# ifdef DEBUG
6708+static void PREFIX(extract_number) (int *dest, UCHAR_T *source);
6709+static void
6710+PREFIX(extract_number) (int *dest, UCHAR_T *source)
6711+{
6712+# ifdef WCHAR
6713+ *dest = *source;
6714+# else /* BYTE */
6715+ int temp = SIGN_EXTEND_CHAR (*(source + 1));
6716+ *dest = *source & 0377;
6717+ *dest += temp << 8;
6718+# endif
6719+}
6720+
6721+# ifndef EXTRACT_MACROS /* To debug the macros. */
6722+# undef EXTRACT_NUMBER
6723+# define EXTRACT_NUMBER(dest, src) PREFIX(extract_number) (&dest, src)
6724+# endif /* not EXTRACT_MACROS */
6725+
6726+# endif /* DEBUG */
6727+
6728+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
6729+ SOURCE must be an lvalue. */
6730+
6731+# define EXTRACT_NUMBER_AND_INCR(destination, source) \
6732+ do { \
6733+ EXTRACT_NUMBER (destination, source); \
6734+ (source) += OFFSET_ADDRESS_SIZE; \
6735+ } while (0)
6736+
6737+# ifdef DEBUG
6738+static void PREFIX(extract_number_and_incr) (int *destination,
6739+ UCHAR_T **source);
6740+static void
6741+PREFIX(extract_number_and_incr) (int *destination, UCHAR_T **source)
6742+{
6743+ PREFIX(extract_number) (destination, *source);
6744+ *source += OFFSET_ADDRESS_SIZE;
6745+}
6746+
6747+# ifndef EXTRACT_MACROS
6748+# undef EXTRACT_NUMBER_AND_INCR
6749+# define EXTRACT_NUMBER_AND_INCR(dest, src) \
6750+ PREFIX(extract_number_and_incr) (&dest, &src)
6751+# endif /* not EXTRACT_MACROS */
6752+
6753+# endif /* DEBUG */
6754+
6755+
6756+
6757+/* If DEBUG is defined, Regex prints many voluminous messages about what
6758+ it is doing (if the variable `debug' is nonzero). If linked with the
6759+ main program in `iregex.c', you can enter patterns and strings
6760+ interactively. And if linked with the main program in `main.c' and
6761+ the other test files, you can run the already-written tests. */
6762+
6763+# ifdef DEBUG
6764+
6765+# ifndef DEFINED_ONCE
6766+
6767+/* We use standard I/O for debugging. */
6768+# include <stdio.h>
6769+
6770+/* It is useful to test things that ``must'' be true when debugging. */
6771+# include <assert.h>
6772+
6773+static int debug;
6774+
6775+# define DEBUG_STATEMENT(e) e
6776+# define DEBUG_PRINT1(x) if (debug) printf (x)
6777+# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
6778+# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
6779+# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
6780+# endif /* not DEFINED_ONCE */
6781+
6782+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
6783+ if (debug) PREFIX(print_partial_compiled_pattern) (s, e)
6784+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
6785+ if (debug) PREFIX(print_double_string) (w, s1, sz1, s2, sz2)
6786+
6787+
6788+/* Print the fastmap in human-readable form. */
6789+
6790+# ifndef DEFINED_ONCE
6791+void
6792+print_fastmap (char *fastmap)
6793+{
6794+ unsigned was_a_range = 0;
6795+ unsigned i = 0;
6796+
6797+ while (i < (1 << BYTEWIDTH))
6798+ {
6799+ if (fastmap[i++])
6800+ {
6801+ was_a_range = 0;
6802+ putchar (i - 1);
6803+ while (i < (1 << BYTEWIDTH) && fastmap[i])
6804+ {
6805+ was_a_range = 1;
6806+ i++;
6807+ }
6808+ if (was_a_range)
6809+ {
6810+ printf ("-");
6811+ putchar (i - 1);
6812+ }
6813+ }
6814+ }
6815+ putchar ('\n');
6816+}
6817+# endif /* not DEFINED_ONCE */
6818+
6819+
6820+/* Print a compiled pattern string in human-readable form, starting at
6821+ the START pointer into it and ending just before the pointer END. */
6822+
6823+void
6824+PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end)
6825+{
6826+ int mcnt, mcnt2;
6827+ UCHAR_T *p1;
6828+ UCHAR_T *p = start;
6829+ UCHAR_T *pend = end;
6830+
6831+ if (start == NULL)
6832+ {
6833+ printf ("(null)\n");
6834+ return;
6835+ }
6836+
6837+ /* Loop over pattern commands. */
6838+ while (p < pend)
6839+ {
6840+# ifdef _LIBC
6841+ printf ("%td:\t", p - start);
6842+# else
6843+ printf ("%ld:\t", (long int) (p - start));
6844+# endif
6845+
6846+ switch ((re_opcode_t) *p++)
6847+ {
6848+ case no_op:
6849+ printf ("/no_op");
6850+ break;
6851+
6852+ case exactn:
6853+ mcnt = *p++;
6854+ printf ("/exactn/%d", mcnt);
6855+ do
6856+ {
6857+ putchar ('/');
6858+ PUT_CHAR (*p++);
6859+ }
6860+ while (--mcnt);
6861+ break;
6862+
6863+# ifdef MBS_SUPPORT
6864+ case exactn_bin:
6865+ mcnt = *p++;
6866+ printf ("/exactn_bin/%d", mcnt);
6867+ do
6868+ {
6869+ printf("/%lx", (long int) *p++);
6870+ }
6871+ while (--mcnt);
6872+ break;
6873+# endif /* MBS_SUPPORT */
6874+
6875+ case start_memory:
6876+ mcnt = *p++;
6877+ printf ("/start_memory/%d/%ld", mcnt, (long int) *p++);
6878+ break;
6879+
6880+ case stop_memory:
6881+ mcnt = *p++;
6882+ printf ("/stop_memory/%d/%ld", mcnt, (long int) *p++);
6883+ break;
6884+
6885+ case duplicate:
6886+ printf ("/duplicate/%ld", (long int) *p++);
6887+ break;
6888+
6889+ case anychar:
6890+ printf ("/anychar");
6891+ break;
6892+
6893+ case charset:
6894+ case charset_not:
6895+ {
6896+# ifdef WCHAR
6897+ int i, length;
6898+ wchar_t *workp = p;
6899+ printf ("/charset [%s",
6900+ (re_opcode_t) *(workp - 1) == charset_not ? "^" : "");
6901+ p += 5;
6902+ length = *workp++; /* the length of char_classes */
6903+ for (i=0 ; i<length ; i++)
6904+ printf("[:%lx:]", (long int) *p++);
6905+ length = *workp++; /* the length of collating_symbol */
6906+ for (i=0 ; i<length ;)
6907+ {
6908+ printf("[.");
6909+ while(*p != 0)
6910+ PUT_CHAR((i++,*p++));
6911+ i++,p++;
6912+ printf(".]");
6913+ }
6914+ length = *workp++; /* the length of equivalence_class */
6915+ for (i=0 ; i<length ;)
6916+ {
6917+ printf("[=");
6918+ while(*p != 0)
6919+ PUT_CHAR((i++,*p++));
6920+ i++,p++;
6921+ printf("=]");
6922+ }
6923+ length = *workp++; /* the length of char_range */
6924+ for (i=0 ; i<length ; i++)
6925+ {
6926+ wchar_t range_start = *p++;
6927+ wchar_t range_end = *p++;
6928+ printf("%C-%C", range_start, range_end);
6929+ }
6930+ length = *workp++; /* the length of char */
6931+ for (i=0 ; i<length ; i++)
6932+ printf("%C", *p++);
6933+ putchar (']');
6934+# else
6935+ register int c, last = -100;
6936+ register int in_range = 0;
6937+
6938+ printf ("/charset [%s",
6939+ (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
6940+
6941+ assert (p + *p < pend);
6942+
6943+ for (c = 0; c < 256; c++)
6944+ if (c / 8 < *p
6945+ && (p[1 + (c/8)] & (1 << (c % 8))))
6946+ {
6947+ /* Are we starting a range? */
6948+ if (last + 1 == c && ! in_range)
6949+ {
6950+ putchar ('-');
6951+ in_range = 1;
6952+ }
6953+ /* Have we broken a range? */
6954+ else if (last + 1 != c && in_range)
6955+ {
6956+ putchar (last);
6957+ in_range = 0;
6958+ }
6959+
6960+ if (! in_range)
6961+ putchar (c);
6962+
6963+ last = c;
6964+ }
6965+
6966+ if (in_range)
6967+ putchar (last);
6968+
6969+ putchar (']');
6970+
6971+ p += 1 + *p;
6972+# endif /* WCHAR */
6973+ }
6974+ break;
6975+
6976+ case begline:
6977+ printf ("/begline");
6978+ break;
6979+
6980+ case endline:
6981+ printf ("/endline");
6982+ break;
6983+
6984+ case on_failure_jump:
6985+ PREFIX(extract_number_and_incr) (&mcnt, &p);
6986+# ifdef _LIBC
6987+ printf ("/on_failure_jump to %td", p + mcnt - start);
6988+# else
6989+ printf ("/on_failure_jump to %ld", (long int) (p + mcnt - start));
6990+# endif
6991+ break;
6992+
6993+ case on_failure_keep_string_jump:
6994+ PREFIX(extract_number_and_incr) (&mcnt, &p);
6995+# ifdef _LIBC
6996+ printf ("/on_failure_keep_string_jump to %td", p + mcnt - start);
6997+# else
6998+ printf ("/on_failure_keep_string_jump to %ld",
6999+ (long int) (p + mcnt - start));
7000+# endif
7001+ break;
7002+
7003+ case dummy_failure_jump:
7004+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7005+# ifdef _LIBC
7006+ printf ("/dummy_failure_jump to %td", p + mcnt - start);
7007+# else
7008+ printf ("/dummy_failure_jump to %ld", (long int) (p + mcnt - start));
7009+# endif
7010+ break;
7011+
7012+ case push_dummy_failure:
7013+ printf ("/push_dummy_failure");
7014+ break;
7015+
7016+ case maybe_pop_jump:
7017+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7018+# ifdef _LIBC
7019+ printf ("/maybe_pop_jump to %td", p + mcnt - start);
7020+# else
7021+ printf ("/maybe_pop_jump to %ld", (long int) (p + mcnt - start));
7022+# endif
7023+ break;
7024+
7025+ case pop_failure_jump:
7026+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7027+# ifdef _LIBC
7028+ printf ("/pop_failure_jump to %td", p + mcnt - start);
7029+# else
7030+ printf ("/pop_failure_jump to %ld", (long int) (p + mcnt - start));
7031+# endif
7032+ break;
7033+
7034+ case jump_past_alt:
7035+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7036+# ifdef _LIBC
7037+ printf ("/jump_past_alt to %td", p + mcnt - start);
7038+# else
7039+ printf ("/jump_past_alt to %ld", (long int) (p + mcnt - start));
7040+# endif
7041+ break;
7042+
7043+ case jump:
7044+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7045+# ifdef _LIBC
7046+ printf ("/jump to %td", p + mcnt - start);
7047+# else
7048+ printf ("/jump to %ld", (long int) (p + mcnt - start));
7049+# endif
7050+ break;
7051+
7052+ case succeed_n:
7053+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7054+ p1 = p + mcnt;
7055+ PREFIX(extract_number_and_incr) (&mcnt2, &p);
7056+# ifdef _LIBC
7057+ printf ("/succeed_n to %td, %d times", p1 - start, mcnt2);
7058+# else
7059+ printf ("/succeed_n to %ld, %d times",
7060+ (long int) (p1 - start), mcnt2);
7061+# endif
7062+ break;
7063+
7064+ case jump_n:
7065+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7066+ p1 = p + mcnt;
7067+ PREFIX(extract_number_and_incr) (&mcnt2, &p);
7068+ printf ("/jump_n to %d, %d times", p1 - start, mcnt2);
7069+ break;
7070+
7071+ case set_number_at:
7072+ PREFIX(extract_number_and_incr) (&mcnt, &p);
7073+ p1 = p + mcnt;
7074+ PREFIX(extract_number_and_incr) (&mcnt2, &p);
7075+# ifdef _LIBC
7076+ printf ("/set_number_at location %td to %d", p1 - start, mcnt2);
7077+# else
7078+ printf ("/set_number_at location %ld to %d",
7079+ (long int) (p1 - start), mcnt2);
7080+# endif
7081+ break;
7082+
7083+ case wordbound:
7084+ printf ("/wordbound");
7085+ break;
7086+
7087+ case notwordbound:
7088+ printf ("/notwordbound");
7089+ break;
7090+
7091+ case wordbeg:
7092+ printf ("/wordbeg");
7093+ break;
7094+
7095+ case wordend:
7096+ printf ("/wordend");
7097+ break;
7098+
7099+# ifdef emacs
7100+ case before_dot:
7101+ printf ("/before_dot");
7102+ break;
7103+
7104+ case at_dot:
7105+ printf ("/at_dot");
7106+ break;
7107+
7108+ case after_dot:
7109+ printf ("/after_dot");
7110+ break;
7111+
7112+ case syntaxspec:
7113+ printf ("/syntaxspec");
7114+ mcnt = *p++;
7115+ printf ("/%d", mcnt);
7116+ break;
7117+
7118+ case notsyntaxspec:
7119+ printf ("/notsyntaxspec");
7120+ mcnt = *p++;
7121+ printf ("/%d", mcnt);
7122+ break;
7123+# endif /* emacs */
7124+
7125+ case wordchar:
7126+ printf ("/wordchar");
7127+ break;
7128+
7129+ case notwordchar:
7130+ printf ("/notwordchar");
7131+ break;
7132+
7133+ case begbuf:
7134+ printf ("/begbuf");
7135+ break;
7136+
7137+ case endbuf:
7138+ printf ("/endbuf");
7139+ break;
7140+
7141+ default:
7142+ printf ("?%ld", (long int) *(p-1));
7143+ }
7144+
7145+ putchar ('\n');
7146+ }
7147+
7148+# ifdef _LIBC
7149+ printf ("%td:\tend of pattern.\n", p - start);
7150+# else
7151+ printf ("%ld:\tend of pattern.\n", (long int) (p - start));
7152+# endif
7153+}
7154+
7155+
7156+void
7157+PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp)
7158+{
7159+ UCHAR_T *buffer = (UCHAR_T*) bufp->buffer;
7160+
7161+ PREFIX(print_partial_compiled_pattern) (buffer, buffer
7162+ + bufp->used / sizeof(UCHAR_T));
7163+ printf ("%ld bytes used/%ld bytes allocated.\n",
7164+ bufp->used, bufp->allocated);
7165+
7166+ if (bufp->fastmap_accurate && bufp->fastmap)
7167+ {
7168+ printf ("fastmap: ");
7169+ print_fastmap (bufp->fastmap);
7170+ }
7171+
7172+# ifdef _LIBC
7173+ printf ("re_nsub: %Zd\t", bufp->re_nsub);
7174+# else
7175+ printf ("re_nsub: %ld\t", (long int) bufp->re_nsub);
7176+# endif
7177+ printf ("regs_alloc: %d\t", bufp->regs_allocated);
7178+ printf ("can_be_null: %d\t", bufp->can_be_null);
7179+ printf ("newline_anchor: %d\n", bufp->newline_anchor);
7180+ printf ("no_sub: %d\t", bufp->no_sub);
7181+ printf ("not_bol: %d\t", bufp->not_bol);
7182+ printf ("not_eol: %d\t", bufp->not_eol);
7183+ printf ("syntax: %lx\n", bufp->syntax);
7184+ /* Perhaps we should print the translate table? */
7185+}
7186+
7187+
7188+void
7189+PREFIX(print_double_string) (const CHAR_T *where, const CHAR_T *string1,
7190+ int size1, const CHAR_T *string2, int size2)
7191+{
7192+ int this_char;
7193+
7194+ if (where == NULL)
7195+ printf ("(null)");
7196+ else
7197+ {
7198+ int cnt;
7199+
7200+ if (FIRST_STRING_P (where))
7201+ {
7202+ for (this_char = where - string1; this_char < size1; this_char++)
7203+ PUT_CHAR (string1[this_char]);
7204+
7205+ where = string2;
7206+ }
7207+
7208+ cnt = 0;
7209+ for (this_char = where - string2; this_char < size2; this_char++)
7210+ {
7211+ PUT_CHAR (string2[this_char]);
7212+ if (++cnt > 100)
7213+ {
7214+ fputs ("...", stdout);
7215+ break;
7216+ }
7217+ }
7218+ }
7219+}
7220+
7221+# ifndef DEFINED_ONCE
7222+void
7223+printchar (int c)
7224+{
7225+ putc (c, stderr);
7226+}
7227+# endif
7228+
7229+# else /* not DEBUG */
7230+
7231+# ifndef DEFINED_ONCE
7232+# undef assert
7233+# define assert(e)
7234+
7235+# define DEBUG_STATEMENT(e)
7236+# define DEBUG_PRINT1(x)
7237+# define DEBUG_PRINT2(x1, x2)
7238+# define DEBUG_PRINT3(x1, x2, x3)
7239+# define DEBUG_PRINT4(x1, x2, x3, x4)
7240+# endif /* not DEFINED_ONCE */
7241+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
7242+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
7243+
7244+# endif /* not DEBUG */
7245+
7246+
7247+
7248+# ifdef WCHAR
7249+/* This convert a multibyte string to a wide character string.
7250+ And write their correspondances to offset_buffer(see below)
7251+ and write whether each wchar_t is binary data to is_binary.
7252+ This assume invalid multibyte sequences as binary data.
7253+ We assume offset_buffer and is_binary is already allocated
7254+ enough space. */
7255+
7256+static size_t convert_mbs_to_wcs (CHAR_T *dest, const unsigned char* src,
7257+ size_t len, int *offset_buffer,
7258+ char *is_binary);
7259+static size_t
7260+convert_mbs_to_wcs (CHAR_T *dest, const unsigned char*src, size_t len,
7261+ int *offset_buffer, char *is_binary)
7262+ /* It hold correspondances between src(char string) and
7263+ dest(wchar_t string) for optimization.
7264+ e.g. src = "xxxyzz"
7265+ dest = {'X', 'Y', 'Z'}
7266+ (each "xxx", "y" and "zz" represent one multibyte character
7267+ corresponding to 'X', 'Y' and 'Z'.)
7268+ offset_buffer = {0, 0+3("xxx"), 0+3+1("y"), 0+3+1+2("zz")}
7269+ = {0, 3, 4, 6}
7270+ */
7271+{
7272+ wchar_t *pdest = dest;
7273+ const unsigned char *psrc = src;
7274+ size_t wc_count = 0;
7275+
7276+ mbstate_t mbs;
7277+ int i, consumed;
7278+ size_t mb_remain = len;
7279+ size_t mb_count = 0;
7280+
7281+ /* Initialize the conversion state. */
7282+ memset (&mbs, 0, sizeof (mbstate_t));
7283+
7284+ offset_buffer[0] = 0;
7285+ for( ; mb_remain > 0 ; ++wc_count, ++pdest, mb_remain -= consumed,
7286+ psrc += consumed)
7287+ {
7288+#ifdef _LIBC
7289+ consumed = __mbrtowc (pdest, psrc, mb_remain, &mbs);
7290+#else
7291+ consumed = mbrtowc (pdest, psrc, mb_remain, &mbs);
7292+#endif
7293+
7294+ if (consumed <= 0)
7295+ /* failed to convert. maybe src contains binary data.
7296+ So we consume 1 byte manualy. */
7297+ {
7298+ *pdest = *psrc;
7299+ consumed = 1;
7300+ is_binary[wc_count] = TRUE;
7301+ }
7302+ else
7303+ is_binary[wc_count] = FALSE;
7304+ /* In sjis encoding, we use yen sign as escape character in
7305+ place of reverse solidus. So we convert 0x5c(yen sign in
7306+ sjis) to not 0xa5(yen sign in UCS2) but 0x5c(reverse
7307+ solidus in UCS2). */
7308+ if (consumed == 1 && (int) *psrc == 0x5c && (int) *pdest == 0xa5)
7309+ *pdest = (wchar_t) *psrc;
7310+
7311+ offset_buffer[wc_count + 1] = mb_count += consumed;
7312+ }
7313+
7314+ /* Fill remain of the buffer with sentinel. */
7315+ for (i = wc_count + 1 ; i <= len ; i++)
7316+ offset_buffer[i] = mb_count + 1;
7317+
7318+ return wc_count;
7319+}
7320+
7321+# endif /* WCHAR */
7322+
7323+#else /* not INSIDE_RECURSION */
7324+
7325+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
7326+ also be assigned to arbitrarily: each pattern buffer stores its own
7327+ syntax, so it can be changed between regex compilations. */
7328+/* This has no initializer because initialized variables in Emacs
7329+ become read-only after dumping. */
7330+reg_syntax_t re_syntax_options;
7331+
7332+
7333+/* Specify the precise syntax of regexps for compilation. This provides
7334+ for compatibility for various utilities which historically have
7335+ different, incompatible syntaxes.
7336+
7337+ The argument SYNTAX is a bit mask comprised of the various bits
7338+ defined in regex.h. We return the old syntax. */
7339+
7340+reg_syntax_t
7341+re_set_syntax (reg_syntax_t syntax)
7342+{
7343+ reg_syntax_t ret = re_syntax_options;
7344+
7345+ re_syntax_options = syntax;
7346+# ifdef DEBUG
7347+ if (syntax & RE_DEBUG)
7348+ debug = 1;
7349+ else if (debug) /* was on but now is not */
7350+ debug = 0;
7351+# endif /* DEBUG */
7352+ return ret;
7353+}
7354+# ifdef _LIBC
7355+weak_alias (__re_set_syntax, re_set_syntax)
7356+# endif
7357+
7358+/* This table gives an error message for each of the error codes listed
7359+ in regex.h. Obviously the order here has to be same as there.
7360+ POSIX doesn't require that we do anything for REG_NOERROR,
7361+ but why not be nice? */
7362+
7363+static const char *re_error_msgid[] =
7364+ {
7365+ gettext_noop ("Success"), /* REG_NOERROR */
7366+ gettext_noop ("No match"), /* REG_NOMATCH */
7367+ gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
7368+ gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
7369+ gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
7370+ gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
7371+ gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
7372+ gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */
7373+ gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
7374+ gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
7375+ gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
7376+ gettext_noop ("Invalid range end"), /* REG_ERANGE */
7377+ gettext_noop ("Memory exhausted"), /* REG_ESPACE */
7378+ gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
7379+ gettext_noop ("Premature end of regular expression"), /* REG_EEND */
7380+ gettext_noop ("Regular expression too big"), /* REG_ESIZE */
7381+ gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
7382+ };
7383+
7384+#endif /* INSIDE_RECURSION */
7385+
7386+#ifndef DEFINED_ONCE
7387+/* Avoiding alloca during matching, to placate r_alloc. */
7388+
7389+/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
7390+ searching and matching functions should not call alloca. On some
7391+ systems, alloca is implemented in terms of malloc, and if we're
7392+ using the relocating allocator routines, then malloc could cause a
7393+ relocation, which might (if the strings being searched are in the
7394+ ralloc heap) shift the data out from underneath the regexp
7395+ routines.
7396+
7397+ Here's another reason to avoid allocation: Emacs
7398+ processes input from X in a signal handler; processing X input may
7399+ call malloc; if input arrives while a matching routine is calling
7400+ malloc, then we're scrod. But Emacs can't just block input while
7401+ calling matching routines; then we don't notice interrupts when
7402+ they come in. So, Emacs blocks input around all regexp calls
7403+ except the matching calls, which it leaves unprotected, in the
7404+ faith that they will not malloc. */
7405+
7406+/* Normally, this is fine. */
7407+# define MATCH_MAY_ALLOCATE
7408+
7409+/* When using GNU C, we are not REALLY using the C alloca, no matter
7410+ what config.h may say. So don't take precautions for it. */
7411+# ifdef __GNUC__
7412+# undef C_ALLOCA
7413+# endif
7414+
7415+/* The match routines may not allocate if (1) they would do it with malloc
7416+ and (2) it's not safe for them to use malloc.
7417+ Note that if REL_ALLOC is defined, matching would not use malloc for the
7418+ failure stack, but we would still use it for the register vectors;
7419+ so REL_ALLOC should not affect this. */
7420+# if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs
7421+# undef MATCH_MAY_ALLOCATE
7422+# endif
7423+#endif /* not DEFINED_ONCE */
7424+
7425+#ifdef INSIDE_RECURSION
7426+/* Failure stack declarations and macros; both re_compile_fastmap and
7427+ re_match_2 use a failure stack. These have to be macros because of
7428+ REGEX_ALLOCATE_STACK. */
7429+
7430+
7431+/* Number of failure points for which to initially allocate space
7432+ when matching. If this number is exceeded, we allocate more
7433+ space, so it is not a hard limit. */
7434+# ifndef INIT_FAILURE_ALLOC
7435+# define INIT_FAILURE_ALLOC 5
7436+# endif
7437+
7438+/* Roughly the maximum number of failure points on the stack. Would be
7439+ exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
7440+ This is a variable only so users of regex can assign to it; we never
7441+ change it ourselves. */
7442+
7443+
7444+# ifndef DEFINED_ONCE
7445+
7446+# ifdef INT_IS_16BIT
7447+# define RE_M_F_TYPE long int
7448+# else
7449+# define RE_M_F_TYPE int
7450+# endif /* INT_IS_16BIT */
7451+
7452+# ifdef MATCH_MAY_ALLOCATE
7453+/* 4400 was enough to cause a crash on Alpha OSF/1,
7454+ whose default stack limit is 2mb. */
7455+# define RE_M_F_DEFAULT 4000
7456+# else
7457+# define RE_M_F_DEFAULT 2000
7458+# endif /* MATCH_MAY_ALLOCATE */
7459+
7460+# include <shlib-compat.h>
7461+
7462+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
7463+link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
7464+RE_M_F_TYPE re_max_failures = RE_M_F_DEFAULT;
7465+# else
7466+RE_M_F_TYPE re_max_failures attribute_hidden = RE_M_F_DEFAULT;
7467+# endif /* SHLIB_COMPAT */
7468+
7469+# undef RE_M_F_TYPE
7470+# undef RE_M_F_DEFAULT
7471+
7472+# endif /* DEFINED_ONCE */
7473+
7474+# ifdef INT_IS_16BIT
7475+
7476+union PREFIX(fail_stack_elt)
7477+{
7478+ UCHAR_T *pointer;
7479+ long int integer;
7480+};
7481+
7482+typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
7483+
7484+typedef struct
7485+{
7486+ PREFIX(fail_stack_elt_t) *stack;
7487+ unsigned long int size;
7488+ unsigned long int avail; /* Offset of next open position. */
7489+} PREFIX(fail_stack_type);
7490+
7491+# else /* not INT_IS_16BIT */
7492+
7493+union PREFIX(fail_stack_elt)
7494+{
7495+ UCHAR_T *pointer;
7496+ int integer;
7497+};
7498+
7499+typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
7500+
7501+typedef struct
7502+{
7503+ PREFIX(fail_stack_elt_t) *stack;
7504+ unsigned size;
7505+ unsigned avail; /* Offset of next open position. */
7506+} PREFIX(fail_stack_type);
7507+
7508+# endif /* INT_IS_16BIT */
7509+
7510+# ifndef DEFINED_ONCE
7511+# define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
7512+# define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
7513+# define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
7514+# endif
7515+
7516+
7517+/* Define macros to initialize and free the failure stack.
7518+ Do `return -2' if the alloc fails. */
7519+
7520+# ifdef MATCH_MAY_ALLOCATE
7521+# define INIT_FAIL_STACK() \
7522+ do { \
7523+ fail_stack.stack = (PREFIX(fail_stack_elt_t) *) \
7524+ REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (PREFIX(fail_stack_elt_t))); \
7525+ \
7526+ if (fail_stack.stack == NULL) \
7527+ return -2; \
7528+ \
7529+ fail_stack.size = INIT_FAILURE_ALLOC; \
7530+ fail_stack.avail = 0; \
7531+ } while (0)
7532+
7533+# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack)
7534+# else
7535+# define INIT_FAIL_STACK() \
7536+ do { \
7537+ fail_stack.avail = 0; \
7538+ } while (0)
7539+
7540+# define RESET_FAIL_STACK()
7541+# endif
7542+
7543+
7544+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
7545+
7546+ Return 1 if succeeds, and 0 if either ran out of memory
7547+ allocating space for it or it was already too large.
7548+
7549+ REGEX_REALLOCATE_STACK requires `destination' be declared. */
7550+
7551+# define DOUBLE_FAIL_STACK(fail_stack) \
7552+ ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \
7553+ ? 0 \
7554+ : ((fail_stack).stack = (PREFIX(fail_stack_elt_t) *) \
7555+ REGEX_REALLOCATE_STACK ((fail_stack).stack, \
7556+ (fail_stack).size * sizeof (PREFIX(fail_stack_elt_t)), \
7557+ ((fail_stack).size << 1) * sizeof (PREFIX(fail_stack_elt_t))),\
7558+ \
7559+ (fail_stack).stack == NULL \
7560+ ? 0 \
7561+ : ((fail_stack).size <<= 1, \
7562+ 1)))
7563+
7564+
7565+/* Push pointer POINTER on FAIL_STACK.
7566+ Return 1 if was able to do so and 0 if ran out of memory allocating
7567+ space to do so. */
7568+# define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \
7569+ ((FAIL_STACK_FULL () \
7570+ && !DOUBLE_FAIL_STACK (FAIL_STACK)) \
7571+ ? 0 \
7572+ : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \
7573+ 1))
7574+
7575+/* Push a pointer value onto the failure stack.
7576+ Assumes the variable `fail_stack'. Probably should only
7577+ be called from within `PUSH_FAILURE_POINT'. */
7578+# define PUSH_FAILURE_POINTER(item) \
7579+ fail_stack.stack[fail_stack.avail++].pointer = (UCHAR_T *) (item)
7580+
7581+/* This pushes an integer-valued item onto the failure stack.
7582+ Assumes the variable `fail_stack'. Probably should only
7583+ be called from within `PUSH_FAILURE_POINT'. */
7584+# define PUSH_FAILURE_INT(item) \
7585+ fail_stack.stack[fail_stack.avail++].integer = (item)
7586+
7587+/* Push a fail_stack_elt_t value onto the failure stack.
7588+ Assumes the variable `fail_stack'. Probably should only
7589+ be called from within `PUSH_FAILURE_POINT'. */
7590+# define PUSH_FAILURE_ELT(item) \
7591+ fail_stack.stack[fail_stack.avail++] = (item)
7592+
7593+/* These three POP... operations complement the three PUSH... operations.
7594+ All assume that `fail_stack' is nonempty. */
7595+# define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
7596+# define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
7597+# define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
7598+
7599+/* Used to omit pushing failure point id's when we're not debugging. */
7600+# ifdef DEBUG
7601+# define DEBUG_PUSH PUSH_FAILURE_INT
7602+# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
7603+# else
7604+# define DEBUG_PUSH(item)
7605+# define DEBUG_POP(item_addr)
7606+# endif
7607+
7608+
7609+/* Push the information about the state we will need
7610+ if we ever fail back to it.
7611+
7612+ Requires variables fail_stack, regstart, regend, reg_info, and
7613+ num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination'
7614+ be declared.
7615+
7616+ Does `return FAILURE_CODE' if runs out of memory. */
7617+
7618+# define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
7619+ do { \
7620+ char *destination; \
7621+ /* Must be int, so when we don't save any registers, the arithmetic \
7622+ of 0 + -1 isn't done as unsigned. */ \
7623+ /* Can't be int, since there is not a shred of a guarantee that int \
7624+ is wide enough to hold a value of something to which pointer can \
7625+ be assigned */ \
7626+ active_reg_t this_reg; \
7627+ \
7628+ DEBUG_STATEMENT (failure_id++); \
7629+ DEBUG_STATEMENT (nfailure_points_pushed++); \
7630+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
7631+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
7632+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
7633+ \
7634+ DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \
7635+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
7636+ \
7637+ /* Ensure we have enough space allocated for what we will push. */ \
7638+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
7639+ { \
7640+ if (!DOUBLE_FAIL_STACK (fail_stack)) \
7641+ return failure_code; \
7642+ \
7643+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
7644+ (fail_stack).size); \
7645+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
7646+ } \
7647+ \
7648+ /* Push the info, starting with the registers. */ \
7649+ DEBUG_PRINT1 ("\n"); \
7650+ \
7651+ if (1) \
7652+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
7653+ this_reg++) \
7654+ { \
7655+ DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \
7656+ DEBUG_STATEMENT (num_regs_pushed++); \
7657+ \
7658+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
7659+ PUSH_FAILURE_POINTER (regstart[this_reg]); \
7660+ \
7661+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
7662+ PUSH_FAILURE_POINTER (regend[this_reg]); \
7663+ \
7664+ DEBUG_PRINT2 (" info: %p\n ", \
7665+ reg_info[this_reg].word.pointer); \
7666+ DEBUG_PRINT2 (" match_null=%d", \
7667+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
7668+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
7669+ DEBUG_PRINT2 (" matched_something=%d", \
7670+ MATCHED_SOMETHING (reg_info[this_reg])); \
7671+ DEBUG_PRINT2 (" ever_matched=%d", \
7672+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
7673+ DEBUG_PRINT1 ("\n"); \
7674+ PUSH_FAILURE_ELT (reg_info[this_reg].word); \
7675+ } \
7676+ \
7677+ DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\
7678+ PUSH_FAILURE_INT (lowest_active_reg); \
7679+ \
7680+ DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\
7681+ PUSH_FAILURE_INT (highest_active_reg); \
7682+ \
7683+ DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \
7684+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
7685+ PUSH_FAILURE_POINTER (pattern_place); \
7686+ \
7687+ DEBUG_PRINT2 (" Pushing string %p: `", string_place); \
7688+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
7689+ size2); \
7690+ DEBUG_PRINT1 ("'\n"); \
7691+ PUSH_FAILURE_POINTER (string_place); \
7692+ \
7693+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
7694+ DEBUG_PUSH (failure_id); \
7695+ } while (0)
7696+
7697+# ifndef DEFINED_ONCE
7698+/* This is the number of items that are pushed and popped on the stack
7699+ for each register. */
7700+# define NUM_REG_ITEMS 3
7701+
7702+/* Individual items aside from the registers. */
7703+# ifdef DEBUG
7704+# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
7705+# else
7706+# define NUM_NONREG_ITEMS 4
7707+# endif
7708+
7709+/* We push at most this many items on the stack. */
7710+/* We used to use (num_regs - 1), which is the number of registers
7711+ this regexp will save; but that was changed to 5
7712+ to avoid stack overflow for a regexp with lots of parens. */
7713+# define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
7714+
7715+/* We actually push this many items. */
7716+# define NUM_FAILURE_ITEMS \
7717+ (((0 \
7718+ ? 0 : highest_active_reg - lowest_active_reg + 1) \
7719+ * NUM_REG_ITEMS) \
7720+ + NUM_NONREG_ITEMS)
7721+
7722+/* How many items can still be added to the stack without overflowing it. */
7723+# define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
7724+# endif /* not DEFINED_ONCE */
7725+
7726+
7727+/* Pops what PUSH_FAIL_STACK pushes.
7728+
7729+ We restore into the parameters, all of which should be lvalues:
7730+ STR -- the saved data position.
7731+ PAT -- the saved pattern position.
7732+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
7733+ REGSTART, REGEND -- arrays of string positions.
7734+ REG_INFO -- array of information about each subexpression.
7735+
7736+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
7737+ `pend', `string1', `size1', `string2', and `size2'. */
7738+# define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
7739+{ \
7740+ DEBUG_STATEMENT (unsigned failure_id;) \
7741+ active_reg_t this_reg; \
7742+ const UCHAR_T *string_temp; \
7743+ \
7744+ assert (!FAIL_STACK_EMPTY ()); \
7745+ \
7746+ /* Remove failure points and point to how many regs pushed. */ \
7747+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
7748+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
7749+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
7750+ \
7751+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
7752+ \
7753+ DEBUG_POP (&failure_id); \
7754+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
7755+ \
7756+ /* If the saved string location is NULL, it came from an \
7757+ on_failure_keep_string_jump opcode, and we want to throw away the \
7758+ saved NULL, thus retaining our current position in the string. */ \
7759+ string_temp = POP_FAILURE_POINTER (); \
7760+ if (string_temp != NULL) \
7761+ str = (const CHAR_T *) string_temp; \
7762+ \
7763+ DEBUG_PRINT2 (" Popping string %p: `", str); \
7764+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
7765+ DEBUG_PRINT1 ("'\n"); \
7766+ \
7767+ pat = (UCHAR_T *) POP_FAILURE_POINTER (); \
7768+ DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \
7769+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
7770+ \
7771+ /* Restore register info. */ \
7772+ high_reg = (active_reg_t) POP_FAILURE_INT (); \
7773+ DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \
7774+ \
7775+ low_reg = (active_reg_t) POP_FAILURE_INT (); \
7776+ DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \
7777+ \
7778+ if (1) \
7779+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
7780+ { \
7781+ DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \
7782+ \
7783+ reg_info[this_reg].word = POP_FAILURE_ELT (); \
7784+ DEBUG_PRINT2 (" info: %p\n", \
7785+ reg_info[this_reg].word.pointer); \
7786+ \
7787+ regend[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER (); \
7788+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
7789+ \
7790+ regstart[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER (); \
7791+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
7792+ } \
7793+ else \
7794+ { \
7795+ for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
7796+ { \
7797+ reg_info[this_reg].word.integer = 0; \
7798+ regend[this_reg] = 0; \
7799+ regstart[this_reg] = 0; \
7800+ } \
7801+ highest_active_reg = high_reg; \
7802+ } \
7803+ \
7804+ set_regs_matched_done = 0; \
7805+ DEBUG_STATEMENT (nfailure_points_popped++); \
7806+} /* POP_FAILURE_POINT */
7807+
7808+/* Structure for per-register (a.k.a. per-group) information.
7809+ Other register information, such as the
7810+ starting and ending positions (which are addresses), and the list of
7811+ inner groups (which is a bits list) are maintained in separate
7812+ variables.
7813+
7814+ We are making a (strictly speaking) nonportable assumption here: that
7815+ the compiler will pack our bit fields into something that fits into
7816+ the type of `word', i.e., is something that fits into one item on the
7817+ failure stack. */
7818+
7819+
7820+/* Declarations and macros for re_match_2. */
7821+
7822+typedef union
7823+{
7824+ PREFIX(fail_stack_elt_t) word;
7825+ struct
7826+ {
7827+ /* This field is one if this group can match the empty string,
7828+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
7829+# define MATCH_NULL_UNSET_VALUE 3
7830+ unsigned match_null_string_p : 2;
7831+ unsigned is_active : 1;
7832+ unsigned matched_something : 1;
7833+ unsigned ever_matched_something : 1;
7834+ } bits;
7835+} PREFIX(register_info_type);
7836+
7837+# ifndef DEFINED_ONCE
7838+# define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
7839+# define IS_ACTIVE(R) ((R).bits.is_active)
7840+# define MATCHED_SOMETHING(R) ((R).bits.matched_something)
7841+# define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
7842+
7843+
7844+/* Call this when have matched a real character; it sets `matched' flags
7845+ for the subexpressions which we are currently inside. Also records
7846+ that those subexprs have matched. */
7847+# define SET_REGS_MATCHED() \
7848+ do \
7849+ { \
7850+ if (!set_regs_matched_done) \
7851+ { \
7852+ active_reg_t r; \
7853+ set_regs_matched_done = 1; \
7854+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
7855+ { \
7856+ MATCHED_SOMETHING (reg_info[r]) \
7857+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
7858+ = 1; \
7859+ } \
7860+ } \
7861+ } \
7862+ while (0)
7863+# endif /* not DEFINED_ONCE */
7864+
7865+/* Registers are set to a sentinel when they haven't yet matched. */
7866+static CHAR_T PREFIX(reg_unset_dummy);
7867+# define REG_UNSET_VALUE (&PREFIX(reg_unset_dummy))
7868+# define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
7869+
7870+/* Subroutine declarations and macros for regex_compile. */
7871+static void PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg);
7872+static void PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc,
7873+ int arg1, int arg2);
7874+static void PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc,
7875+ int arg, UCHAR_T *end);
7876+static void PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc,
7877+ int arg1, int arg2, UCHAR_T *end);
7878+static boolean PREFIX(at_begline_loc_p) (const CHAR_T *pattern,
7879+ const CHAR_T *p,
7880+ reg_syntax_t syntax);
7881+static boolean PREFIX(at_endline_loc_p) (const CHAR_T *p,
7882+ const CHAR_T *pend,
7883+ reg_syntax_t syntax);
7884+# ifdef WCHAR
7885+static reg_errcode_t wcs_compile_range (CHAR_T range_start,
7886+ const CHAR_T **p_ptr,
7887+ const CHAR_T *pend,
7888+ char *translate,
7889+ reg_syntax_t syntax,
7890+ UCHAR_T *b,
7891+ CHAR_T *char_set);
7892+static void insert_space (int num, CHAR_T *loc, CHAR_T *end);
7893+# else /* BYTE */
7894+static reg_errcode_t byte_compile_range (unsigned int range_start,
7895+ const char **p_ptr,
7896+ const char *pend,
7897+ RE_TRANSLATE_TYPE translate,
7898+ reg_syntax_t syntax,
7899+ unsigned char *b);
7900+# endif /* WCHAR */
7901+
7902+/* Fetch the next character in the uncompiled pattern---translating it
7903+ if necessary. Also cast from a signed character in the constant
7904+ string passed to us by the user to an unsigned char that we can use
7905+ as an array index (in, e.g., `translate'). */
7906+/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
7907+ because it is impossible to allocate 4GB array for some encodings
7908+ which have 4 byte character_set like UCS4. */
7909+# ifndef PATFETCH
7910+# ifdef WCHAR
7911+# define PATFETCH(c) \
7912+ do {if (p == pend) return REG_EEND; \
7913+ c = (UCHAR_T) *p++; \
7914+ if (translate && (c <= 0xff)) c = (UCHAR_T) translate[c]; \
7915+ } while (0)
7916+# else /* BYTE */
7917+# define PATFETCH(c) \
7918+ do {if (p == pend) return REG_EEND; \
7919+ c = (unsigned char) *p++; \
7920+ if (translate) c = (unsigned char) translate[c]; \
7921+ } while (0)
7922+# endif /* WCHAR */
7923+# endif
7924+
7925+/* Fetch the next character in the uncompiled pattern, with no
7926+ translation. */
7927+# define PATFETCH_RAW(c) \
7928+ do {if (p == pend) return REG_EEND; \
7929+ c = (UCHAR_T) *p++; \
7930+ } while (0)
7931+
7932+/* Go backwards one character in the pattern. */
7933+# define PATUNFETCH p--
7934+
7935+
7936+/* If `translate' is non-null, return translate[D], else just D. We
7937+ cast the subscript to translate because some data is declared as
7938+ `char *', to avoid warnings when a string constant is passed. But
7939+ when we use a character as a subscript we must make it unsigned. */
7940+/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
7941+ because it is impossible to allocate 4GB array for some encodings
7942+ which have 4 byte character_set like UCS4. */
7943+
7944+# ifndef TRANSLATE
7945+# ifdef WCHAR
7946+# define TRANSLATE(d) \
7947+ ((translate && ((UCHAR_T) (d)) <= 0xff) \
7948+ ? (char) translate[(unsigned char) (d)] : (d))
7949+# else /* BYTE */
7950+# define TRANSLATE(d) \
7951+ (translate ? (char) translate[(unsigned char) (d)] : (char) (d))
7952+# endif /* WCHAR */
7953+# endif
7954+
7955+
7956+/* Macros for outputting the compiled pattern into `buffer'. */
7957+
7958+/* If the buffer isn't allocated when it comes in, use this. */
7959+# define INIT_BUF_SIZE (32 * sizeof(UCHAR_T))
7960+
7961+/* Make sure we have at least N more bytes of space in buffer. */
7962+# ifdef WCHAR
7963+# define GET_BUFFER_SPACE(n) \
7964+ while (((unsigned long)b - (unsigned long)COMPILED_BUFFER_VAR \
7965+ + (n)*sizeof(CHAR_T)) > bufp->allocated) \
7966+ EXTEND_BUFFER ()
7967+# else /* BYTE */
7968+# define GET_BUFFER_SPACE(n) \
7969+ while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \
7970+ EXTEND_BUFFER ()
7971+# endif /* WCHAR */
7972+
7973+/* Make sure we have one more byte of buffer space and then add C to it. */
7974+# define BUF_PUSH(c) \
7975+ do { \
7976+ GET_BUFFER_SPACE (1); \
7977+ *b++ = (UCHAR_T) (c); \
7978+ } while (0)
7979+
7980+
7981+/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
7982+# define BUF_PUSH_2(c1, c2) \
7983+ do { \
7984+ GET_BUFFER_SPACE (2); \
7985+ *b++ = (UCHAR_T) (c1); \
7986+ *b++ = (UCHAR_T) (c2); \
7987+ } while (0)
7988+
7989+
7990+/* As with BUF_PUSH_2, except for three bytes. */
7991+# define BUF_PUSH_3(c1, c2, c3) \
7992+ do { \
7993+ GET_BUFFER_SPACE (3); \
7994+ *b++ = (UCHAR_T) (c1); \
7995+ *b++ = (UCHAR_T) (c2); \
7996+ *b++ = (UCHAR_T) (c3); \
7997+ } while (0)
7998+
7999+/* Store a jump with opcode OP at LOC to location TO. We store a
8000+ relative address offset by the three bytes the jump itself occupies. */
8001+# define STORE_JUMP(op, loc, to) \
8002+ PREFIX(store_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)))
8003+
8004+/* Likewise, for a two-argument jump. */
8005+# define STORE_JUMP2(op, loc, to, arg) \
8006+ PREFIX(store_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), arg)
8007+
8008+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
8009+# define INSERT_JUMP(op, loc, to) \
8010+ PREFIX(insert_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), b)
8011+
8012+/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
8013+# define INSERT_JUMP2(op, loc, to, arg) \
8014+ PREFIX(insert_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)),\
8015+ arg, b)
8016+
8017+/* This is not an arbitrary limit: the arguments which represent offsets
8018+ into the pattern are two bytes long. So if 2^16 bytes turns out to
8019+ be too small, many things would have to change. */
8020+/* Any other compiler which, like MSC, has allocation limit below 2^16
8021+ bytes will have to use approach similar to what was done below for
8022+ MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up
8023+ reallocating to 0 bytes. Such thing is not going to work too well.
8024+ You have been warned!! */
8025+# ifndef DEFINED_ONCE
8026+# if defined _MSC_VER && !defined WIN32
8027+/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
8028+ The REALLOC define eliminates a flurry of conversion warnings,
8029+ but is not required. */
8030+# define MAX_BUF_SIZE 65500L
8031+# define REALLOC(p,s) realloc ((p), (size_t) (s))
8032+# else
8033+# define MAX_BUF_SIZE (1L << 16)
8034+# define REALLOC(p,s) realloc ((p), (s))
8035+# endif
8036+
8037+/* Extend the buffer by twice its current size via realloc and
8038+ reset the pointers that pointed into the old block to point to the
8039+ correct places in the new one. If extending the buffer results in it
8040+ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
8041+# if __BOUNDED_POINTERS__
8042+# define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated)
8043+# define MOVE_BUFFER_POINTER(P) \
8044+ (__ptrlow (P) += incr, SET_HIGH_BOUND (P), __ptrvalue (P) += incr)
8045+# define ELSE_EXTEND_BUFFER_HIGH_BOUND \
8046+ else \
8047+ { \
8048+ SET_HIGH_BOUND (b); \
8049+ SET_HIGH_BOUND (begalt); \
8050+ if (fixup_alt_jump) \
8051+ SET_HIGH_BOUND (fixup_alt_jump); \
8052+ if (laststart) \
8053+ SET_HIGH_BOUND (laststart); \
8054+ if (pending_exact) \
8055+ SET_HIGH_BOUND (pending_exact); \
8056+ }
8057+# else
8058+# define MOVE_BUFFER_POINTER(P) (P) += incr
8059+# define ELSE_EXTEND_BUFFER_HIGH_BOUND
8060+# endif
8061+# endif /* not DEFINED_ONCE */
8062+
8063+# ifdef WCHAR
8064+# define EXTEND_BUFFER() \
8065+ do { \
8066+ UCHAR_T *old_buffer = COMPILED_BUFFER_VAR; \
8067+ int wchar_count; \
8068+ if (bufp->allocated + sizeof(UCHAR_T) > MAX_BUF_SIZE) \
8069+ return REG_ESIZE; \
8070+ bufp->allocated <<= 1; \
8071+ if (bufp->allocated > MAX_BUF_SIZE) \
8072+ bufp->allocated = MAX_BUF_SIZE; \
8073+ /* How many characters the new buffer can have? */ \
8074+ wchar_count = bufp->allocated / sizeof(UCHAR_T); \
8075+ if (wchar_count == 0) wchar_count = 1; \
8076+ /* Truncate the buffer to CHAR_T align. */ \
8077+ bufp->allocated = wchar_count * sizeof(UCHAR_T); \
8078+ RETALLOC (COMPILED_BUFFER_VAR, wchar_count, UCHAR_T); \
8079+ bufp->buffer = (char*)COMPILED_BUFFER_VAR; \
8080+ if (COMPILED_BUFFER_VAR == NULL) \
8081+ return REG_ESPACE; \
8082+ /* If the buffer moved, move all the pointers into it. */ \
8083+ if (old_buffer != COMPILED_BUFFER_VAR) \
8084+ { \
8085+ int incr = COMPILED_BUFFER_VAR - old_buffer; \
8086+ MOVE_BUFFER_POINTER (b); \
8087+ MOVE_BUFFER_POINTER (begalt); \
8088+ if (fixup_alt_jump) \
8089+ MOVE_BUFFER_POINTER (fixup_alt_jump); \
8090+ if (laststart) \
8091+ MOVE_BUFFER_POINTER (laststart); \
8092+ if (pending_exact) \
8093+ MOVE_BUFFER_POINTER (pending_exact); \
8094+ } \
8095+ ELSE_EXTEND_BUFFER_HIGH_BOUND \
8096+ } while (0)
8097+# else /* BYTE */
8098+# define EXTEND_BUFFER() \
8099+ do { \
8100+ UCHAR_T *old_buffer = COMPILED_BUFFER_VAR; \
8101+ if (bufp->allocated == MAX_BUF_SIZE) \
8102+ return REG_ESIZE; \
8103+ bufp->allocated <<= 1; \
8104+ if (bufp->allocated > MAX_BUF_SIZE) \
8105+ bufp->allocated = MAX_BUF_SIZE; \
8106+ bufp->buffer = (UCHAR_T *) REALLOC (COMPILED_BUFFER_VAR, \
8107+ bufp->allocated); \
8108+ if (COMPILED_BUFFER_VAR == NULL) \
8109+ return REG_ESPACE; \
8110+ /* If the buffer moved, move all the pointers into it. */ \
8111+ if (old_buffer != COMPILED_BUFFER_VAR) \
8112+ { \
8113+ int incr = COMPILED_BUFFER_VAR - old_buffer; \
8114+ MOVE_BUFFER_POINTER (b); \
8115+ MOVE_BUFFER_POINTER (begalt); \
8116+ if (fixup_alt_jump) \
8117+ MOVE_BUFFER_POINTER (fixup_alt_jump); \
8118+ if (laststart) \
8119+ MOVE_BUFFER_POINTER (laststart); \
8120+ if (pending_exact) \
8121+ MOVE_BUFFER_POINTER (pending_exact); \
8122+ } \
8123+ ELSE_EXTEND_BUFFER_HIGH_BOUND \
8124+ } while (0)
8125+# endif /* WCHAR */
8126+
8127+# ifndef DEFINED_ONCE
8128+/* Since we have one byte reserved for the register number argument to
8129+ {start,stop}_memory, the maximum number of groups we can report
8130+ things about is what fits in that byte. */
8131+# define MAX_REGNUM 255
8132+
8133+/* But patterns can have more than `MAX_REGNUM' registers. We just
8134+ ignore the excess. */
8135+typedef unsigned regnum_t;
8136+
8137+
8138+/* Macros for the compile stack. */
8139+
8140+/* Since offsets can go either forwards or backwards, this type needs to
8141+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
8142+/* int may be not enough when sizeof(int) == 2. */
8143+typedef long pattern_offset_t;
8144+
8145+typedef struct
8146+{
8147+ pattern_offset_t begalt_offset;
8148+ pattern_offset_t fixup_alt_jump;
8149+ pattern_offset_t inner_group_offset;
8150+ pattern_offset_t laststart_offset;
8151+ regnum_t regnum;
8152+} compile_stack_elt_t;
8153+
8154+
8155+typedef struct
8156+{
8157+ compile_stack_elt_t *stack;
8158+ unsigned size;
8159+ unsigned avail; /* Offset of next open position. */
8160+} compile_stack_type;
8161+
8162+
8163+# define INIT_COMPILE_STACK_SIZE 32
8164+
8165+# define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
8166+# define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
8167+
8168+/* The next available element. */
8169+# define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
8170+
8171+# endif /* not DEFINED_ONCE */
8172+
8173+/* Set the bit for character C in a list. */
8174+# ifndef DEFINED_ONCE
8175+# define SET_LIST_BIT(c) \
8176+ (b[((unsigned char) (c)) / BYTEWIDTH] \
8177+ |= 1 << (((unsigned char) c) % BYTEWIDTH))
8178+# endif /* DEFINED_ONCE */
8179+
8180+/* Get the next unsigned number in the uncompiled pattern. */
8181+# define GET_UNSIGNED_NUMBER(num) \
8182+ { \
8183+ while (p != pend) \
8184+ { \
8185+ PATFETCH (c); \
8186+ if (c < '0' || c > '9') \
8187+ break; \
8188+ if (num <= RE_DUP_MAX) \
8189+ { \
8190+ if (num < 0) \
8191+ num = 0; \
8192+ num = num * 10 + c - '0'; \
8193+ } \
8194+ } \
8195+ }
8196+
8197+# ifndef DEFINED_ONCE
8198+# if WIDE_CHAR_SUPPORT
8199+/* The GNU C library provides support for user-defined character classes
8200+ and the functions from ISO C amendement 1. */
8201+# ifdef CHARCLASS_NAME_MAX
8202+# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
8203+# else
8204+/* This shouldn't happen but some implementation might still have this
8205+ problem. Use a reasonable default value. */
8206+# define CHAR_CLASS_MAX_LENGTH 256
8207+# endif
8208+
8209+# ifdef _LIBC
8210+# define IS_CHAR_CLASS(string) __wctype (string)
8211+# else
8212+# define IS_CHAR_CLASS(string) wctype (string)
8213+# endif
8214+# else
8215+# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
8216+
8217+# define IS_CHAR_CLASS(string) \
8218+ (STREQ (string, "alpha") || STREQ (string, "upper") \
8219+ || STREQ (string, "lower") || STREQ (string, "digit") \
8220+ || STREQ (string, "alnum") || STREQ (string, "xdigit") \
8221+ || STREQ (string, "space") || STREQ (string, "print") \
8222+ || STREQ (string, "punct") || STREQ (string, "graph") \
8223+ || STREQ (string, "cntrl") || STREQ (string, "blank"))
8224+# endif
8225+# endif /* DEFINED_ONCE */
8226+
8227+# ifndef MATCH_MAY_ALLOCATE
8228+
8229+/* If we cannot allocate large objects within re_match_2_internal,
8230+ we make the fail stack and register vectors global.
8231+ The fail stack, we grow to the maximum size when a regexp
8232+ is compiled.
8233+ The register vectors, we adjust in size each time we
8234+ compile a regexp, according to the number of registers it needs. */
8235+
8236+static PREFIX(fail_stack_type) fail_stack;
8237+
8238+/* Size with which the following vectors are currently allocated.
8239+ That is so we can make them bigger as needed,
8240+ but never make them smaller. */
8241+# ifdef DEFINED_ONCE
8242+static int regs_allocated_size;
8243+
8244+static const char ** regstart, ** regend;
8245+static const char ** old_regstart, ** old_regend;
8246+static const char **best_regstart, **best_regend;
8247+static const char **reg_dummy;
8248+# endif /* DEFINED_ONCE */
8249+
8250+static PREFIX(register_info_type) *PREFIX(reg_info);
8251+static PREFIX(register_info_type) *PREFIX(reg_info_dummy);
8252+
8253+/* Make the register vectors big enough for NUM_REGS registers,
8254+ but don't make them smaller. */
8255+
8256+static void
8257+PREFIX(regex_grow_registers) (int num_regs)
8258+{
8259+ if (num_regs > regs_allocated_size)
8260+ {
8261+ RETALLOC_IF (regstart, num_regs, const char *);
8262+ RETALLOC_IF (regend, num_regs, const char *);
8263+ RETALLOC_IF (old_regstart, num_regs, const char *);
8264+ RETALLOC_IF (old_regend, num_regs, const char *);
8265+ RETALLOC_IF (best_regstart, num_regs, const char *);
8266+ RETALLOC_IF (best_regend, num_regs, const char *);
8267+ RETALLOC_IF (PREFIX(reg_info), num_regs, PREFIX(register_info_type));
8268+ RETALLOC_IF (reg_dummy, num_regs, const char *);
8269+ RETALLOC_IF (PREFIX(reg_info_dummy), num_regs, PREFIX(register_info_type));
8270+
8271+ regs_allocated_size = num_regs;
8272+ }
8273+}
8274+
8275+# endif /* not MATCH_MAY_ALLOCATE */
8276+
8277+# ifndef DEFINED_ONCE
8278+static boolean group_in_compile_stack (compile_stack_type compile_stack,
8279+ regnum_t regnum);
8280+# endif /* not DEFINED_ONCE */
8281+
8282+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
8283+ Returns one of error codes defined in `regex.h', or zero for success.
8284+
8285+ Assumes the `allocated' (and perhaps `buffer') and `translate'
8286+ fields are set in BUFP on entry.
8287+
8288+ If it succeeds, results are put in BUFP (if it returns an error, the
8289+ contents of BUFP are undefined):
8290+ `buffer' is the compiled pattern;
8291+ `syntax' is set to SYNTAX;
8292+ `used' is set to the length of the compiled pattern;
8293+ `fastmap_accurate' is zero;
8294+ `re_nsub' is the number of subexpressions in PATTERN;
8295+ `not_bol' and `not_eol' are zero;
8296+
8297+ The `fastmap' and `newline_anchor' fields are neither
8298+ examined nor set. */
8299+
8300+/* Return, freeing storage we allocated. */
8301+# ifdef WCHAR
8302+# define FREE_STACK_RETURN(value) \
8303+ return (free(pattern), free(mbs_offset), free(is_binary), free (compile_stack.stack), value)
8304+# else
8305+# define FREE_STACK_RETURN(value) \
8306+ return (free (compile_stack.stack), value)
8307+# endif /* WCHAR */
8308+
8309+static reg_errcode_t
8310+PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
8311+ size_t ARG_PREFIX(size), reg_syntax_t syntax,
8312+ struct re_pattern_buffer *bufp)
8313+{
8314+ /* We fetch characters from PATTERN here. Even though PATTERN is
8315+ `char *' (i.e., signed), we declare these variables as unsigned, so
8316+ they can be reliably used as array indices. */
8317+ register UCHAR_T c, c1;
8318+
8319+#ifdef WCHAR
8320+ /* A temporary space to keep wchar_t pattern and compiled pattern. */
8321+ CHAR_T *pattern, *COMPILED_BUFFER_VAR;
8322+ size_t size;
8323+ /* offset buffer for optimization. See convert_mbs_to_wc. */
8324+ int *mbs_offset = NULL;
8325+ /* It hold whether each wchar_t is binary data or not. */
8326+ char *is_binary = NULL;
8327+ /* A flag whether exactn is handling binary data or not. */
8328+ char is_exactn_bin = FALSE;
8329+#endif /* WCHAR */
8330+
8331+ /* A random temporary spot in PATTERN. */
8332+ const CHAR_T *p1;
8333+
8334+ /* Points to the end of the buffer, where we should append. */
8335+ register UCHAR_T *b;
8336+
8337+ /* Keeps track of unclosed groups. */
8338+ compile_stack_type compile_stack;
8339+
8340+ /* Points to the current (ending) position in the pattern. */
8341+#ifdef WCHAR
8342+ const CHAR_T *p;
8343+ const CHAR_T *pend;
8344+#else /* BYTE */
8345+ const CHAR_T *p = pattern;
8346+ const CHAR_T *pend = pattern + size;
8347+#endif /* WCHAR */
8348+
8349+ /* How to translate the characters in the pattern. */
8350+ RE_TRANSLATE_TYPE translate = bufp->translate;
8351+
8352+ /* Address of the count-byte of the most recently inserted `exactn'
8353+ command. This makes it possible to tell if a new exact-match
8354+ character can be added to that command or if the character requires
8355+ a new `exactn' command. */
8356+ UCHAR_T *pending_exact = 0;
8357+
8358+ /* Address of start of the most recently finished expression.
8359+ This tells, e.g., postfix * where to find the start of its
8360+ operand. Reset at the beginning of groups and alternatives. */
8361+ UCHAR_T *laststart = 0;
8362+
8363+ /* Address of beginning of regexp, or inside of last group. */
8364+ UCHAR_T *begalt;
8365+
8366+ /* Address of the place where a forward jump should go to the end of
8367+ the containing expression. Each alternative of an `or' -- except the
8368+ last -- ends with a forward jump of this sort. */
8369+ UCHAR_T *fixup_alt_jump = 0;
8370+
8371+ /* Counts open-groups as they are encountered. Remembered for the
8372+ matching close-group on the compile stack, so the same register
8373+ number is put in the stop_memory as the start_memory. */
8374+ regnum_t regnum = 0;
8375+
8376+#ifdef WCHAR
8377+ /* Initialize the wchar_t PATTERN and offset_buffer. */
8378+ p = pend = pattern = TALLOC(csize + 1, CHAR_T);
8379+ mbs_offset = TALLOC(csize + 1, int);
8380+ is_binary = TALLOC(csize + 1, char);
8381+ if (pattern == NULL || mbs_offset == NULL || is_binary == NULL)
8382+ {
8383+ free(pattern);
8384+ free(mbs_offset);
8385+ free(is_binary);
8386+ return REG_ESPACE;
8387+ }
8388+ pattern[csize] = L'\0'; /* sentinel */
8389+ size = convert_mbs_to_wcs(pattern, cpattern, csize, mbs_offset, is_binary);
8390+ pend = p + size;
8391+ if (size < 0)
8392+ {
8393+ free(pattern);
8394+ free(mbs_offset);
8395+ free(is_binary);
8396+ return REG_BADPAT;
8397+ }
8398+#endif
8399+
8400+#ifdef DEBUG
8401+ DEBUG_PRINT1 ("\nCompiling pattern: ");
8402+ if (debug)
8403+ {
8404+ unsigned debug_count;
8405+
8406+ for (debug_count = 0; debug_count < size; debug_count++)
8407+ PUT_CHAR (pattern[debug_count]);
8408+ putchar ('\n');
8409+ }
8410+#endif /* DEBUG */
8411+
8412+ /* Initialize the compile stack. */
8413+ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
8414+ if (compile_stack.stack == NULL)
8415+ {
8416+#ifdef WCHAR
8417+ free(pattern);
8418+ free(mbs_offset);
8419+ free(is_binary);
8420+#endif
8421+ return REG_ESPACE;
8422+ }
8423+
8424+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
8425+ compile_stack.avail = 0;
8426+
8427+ /* Initialize the pattern buffer. */
8428+ bufp->syntax = syntax;
8429+ bufp->fastmap_accurate = 0;
8430+ bufp->not_bol = bufp->not_eol = 0;
8431+
8432+ /* Set `used' to zero, so that if we return an error, the pattern
8433+ printer (for debugging) will think there's no pattern. We reset it
8434+ at the end. */
8435+ bufp->used = 0;
8436+
8437+ /* Always count groups, whether or not bufp->no_sub is set. */
8438+ bufp->re_nsub = 0;
8439+
8440+#if !defined emacs && !defined SYNTAX_TABLE
8441+ /* Initialize the syntax table. */
8442+ init_syntax_once ();
8443+#endif
8444+
8445+ if (bufp->allocated == 0)
8446+ {
8447+ if (bufp->buffer)
8448+ { /* If zero allocated, but buffer is non-null, try to realloc
8449+ enough space. This loses if buffer's address is bogus, but
8450+ that is the user's responsibility. */
8451+#ifdef WCHAR
8452+ /* Free bufp->buffer and allocate an array for wchar_t pattern
8453+ buffer. */
8454+ free(bufp->buffer);
8455+ COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE/sizeof(UCHAR_T),
8456+ UCHAR_T);
8457+#else
8458+ RETALLOC (COMPILED_BUFFER_VAR, INIT_BUF_SIZE, UCHAR_T);
8459+#endif /* WCHAR */
8460+ }
8461+ else
8462+ { /* Caller did not allocate a buffer. Do it for them. */
8463+ COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE / sizeof(UCHAR_T),
8464+ UCHAR_T);
8465+ }
8466+
8467+ if (!COMPILED_BUFFER_VAR) FREE_STACK_RETURN (REG_ESPACE);
8468+#ifdef WCHAR
8469+ bufp->buffer = (char*)COMPILED_BUFFER_VAR;
8470+#endif /* WCHAR */
8471+ bufp->allocated = INIT_BUF_SIZE;
8472+ }
8473+#ifdef WCHAR
8474+ else
8475+ COMPILED_BUFFER_VAR = (UCHAR_T*) bufp->buffer;
8476+#endif
8477+
8478+ begalt = b = COMPILED_BUFFER_VAR;
8479+
8480+ /* Loop through the uncompiled pattern until we're at the end. */
8481+ while (p != pend)
8482+ {
8483+ PATFETCH (c);
8484+
8485+ switch (c)
8486+ {
8487+ case '^':
8488+ {
8489+ if ( /* If at start of pattern, it's an operator. */
8490+ p == pattern + 1
8491+ /* If context independent, it's an operator. */
8492+ || syntax & RE_CONTEXT_INDEP_ANCHORS
8493+ /* Otherwise, depends on what's come before. */
8494+ || PREFIX(at_begline_loc_p) (pattern, p, syntax))
8495+ BUF_PUSH (begline);
8496+ else
8497+ goto normal_char;
8498+ }
8499+ break;
8500+
8501+
8502+ case '$':
8503+ {
8504+ if ( /* If at end of pattern, it's an operator. */
8505+ p == pend
8506+ /* If context independent, it's an operator. */
8507+ || syntax & RE_CONTEXT_INDEP_ANCHORS
8508+ /* Otherwise, depends on what's next. */
8509+ || PREFIX(at_endline_loc_p) (p, pend, syntax))
8510+ BUF_PUSH (endline);
8511+ else
8512+ goto normal_char;
8513+ }
8514+ break;
8515+
8516+
8517+ case '+':
8518+ case '?':
8519+ if ((syntax & RE_BK_PLUS_QM)
8520+ || (syntax & RE_LIMITED_OPS))
8521+ goto normal_char;
8522+ handle_plus:
8523+ case '*':
8524+ /* If there is no previous pattern... */
8525+ if (!laststart)
8526+ {
8527+ if (syntax & RE_CONTEXT_INVALID_OPS)
8528+ FREE_STACK_RETURN (REG_BADRPT);
8529+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
8530+ goto normal_char;
8531+ }
8532+
8533+ {
8534+ /* Are we optimizing this jump? */
8535+ boolean keep_string_p = false;
8536+
8537+ /* 1 means zero (many) matches is allowed. */
8538+ char zero_times_ok = 0, many_times_ok = 0;
8539+
8540+ /* If there is a sequence of repetition chars, collapse it
8541+ down to just one (the right one). We can't combine
8542+ interval operators with these because of, e.g., `a{2}*',
8543+ which should only match an even number of `a's. */
8544+
8545+ for (;;)
8546+ {
8547+ zero_times_ok |= c != '+';
8548+ many_times_ok |= c != '?';
8549+
8550+ if (p == pend)
8551+ break;
8552+
8553+ PATFETCH (c);
8554+
8555+ if (c == '*'
8556+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
8557+ ;
8558+
8559+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
8560+ {
8561+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
8562+
8563+ PATFETCH (c1);
8564+ if (!(c1 == '+' || c1 == '?'))
8565+ {
8566+ PATUNFETCH;
8567+ PATUNFETCH;
8568+ break;
8569+ }
8570+
8571+ c = c1;
8572+ }
8573+ else
8574+ {
8575+ PATUNFETCH;
8576+ break;
8577+ }
8578+
8579+ /* If we get here, we found another repeat character. */
8580+ }
8581+
8582+ /* Star, etc. applied to an empty pattern is equivalent
8583+ to an empty pattern. */
8584+ if (!laststart)
8585+ break;
8586+
8587+ /* Now we know whether or not zero matches is allowed
8588+ and also whether or not two or more matches is allowed. */
8589+ if (many_times_ok)
8590+ { /* More than one repetition is allowed, so put in at the
8591+ end a backward relative jump from `b' to before the next
8592+ jump we're going to put in below (which jumps from
8593+ laststart to after this jump).
8594+
8595+ But if we are at the `*' in the exact sequence `.*\n',
8596+ insert an unconditional jump backwards to the .,
8597+ instead of the beginning of the loop. This way we only
8598+ push a failure point once, instead of every time
8599+ through the loop. */
8600+ assert (p - 1 > pattern);
8601+
8602+ /* Allocate the space for the jump. */
8603+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
8604+
8605+ /* We know we are not at the first character of the pattern,
8606+ because laststart was nonzero. And we've already
8607+ incremented `p', by the way, to be the character after
8608+ the `*'. Do we have to do something analogous here
8609+ for null bytes, because of RE_DOT_NOT_NULL? */
8610+ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
8611+ && zero_times_ok
8612+ && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
8613+ && !(syntax & RE_DOT_NEWLINE))
8614+ { /* We have .*\n. */
8615+ STORE_JUMP (jump, b, laststart);
8616+ keep_string_p = true;
8617+ }
8618+ else
8619+ /* Anything else. */
8620+ STORE_JUMP (maybe_pop_jump, b, laststart -
8621+ (1 + OFFSET_ADDRESS_SIZE));
8622+
8623+ /* We've added more stuff to the buffer. */
8624+ b += 1 + OFFSET_ADDRESS_SIZE;
8625+ }
8626+
8627+ /* On failure, jump from laststart to b + 3, which will be the
8628+ end of the buffer after this jump is inserted. */
8629+ /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE' instead of
8630+ 'b + 3'. */
8631+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
8632+ INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
8633+ : on_failure_jump,
8634+ laststart, b + 1 + OFFSET_ADDRESS_SIZE);
8635+ pending_exact = 0;
8636+ b += 1 + OFFSET_ADDRESS_SIZE;
8637+
8638+ if (!zero_times_ok)
8639+ {
8640+ /* At least one repetition is required, so insert a
8641+ `dummy_failure_jump' before the initial
8642+ `on_failure_jump' instruction of the loop. This
8643+ effects a skip over that instruction the first time
8644+ we hit that loop. */
8645+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
8646+ INSERT_JUMP (dummy_failure_jump, laststart, laststart +
8647+ 2 + 2 * OFFSET_ADDRESS_SIZE);
8648+ b += 1 + OFFSET_ADDRESS_SIZE;
8649+ }
8650+ }
8651+ break;
8652+
8653+
8654+ case '.':
8655+ laststart = b;
8656+ BUF_PUSH (anychar);
8657+ break;
8658+
8659+
8660+ case '[':
8661+ {
8662+ boolean had_char_class = false;
8663+#ifdef WCHAR
8664+ CHAR_T range_start = 0xffffffff;
8665+#else
8666+ unsigned int range_start = 0xffffffff;
8667+#endif
8668+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
8669+
8670+#ifdef WCHAR
8671+ /* We assume a charset(_not) structure as a wchar_t array.
8672+ charset[0] = (re_opcode_t) charset(_not)
8673+ charset[1] = l (= length of char_classes)
8674+ charset[2] = m (= length of collating_symbols)
8675+ charset[3] = n (= length of equivalence_classes)
8676+ charset[4] = o (= length of char_ranges)
8677+ charset[5] = p (= length of chars)
8678+
8679+ charset[6] = char_class (wctype_t)
8680+ charset[6+CHAR_CLASS_SIZE] = char_class (wctype_t)
8681+ ...
8682+ charset[l+5] = char_class (wctype_t)
8683+
8684+ charset[l+6] = collating_symbol (wchar_t)
8685+ ...
8686+ charset[l+m+5] = collating_symbol (wchar_t)
8687+ ifdef _LIBC we use the index if
8688+ _NL_COLLATE_SYMB_EXTRAMB instead of
8689+ wchar_t string.
8690+
8691+ charset[l+m+6] = equivalence_classes (wchar_t)
8692+ ...
8693+ charset[l+m+n+5] = equivalence_classes (wchar_t)
8694+ ifdef _LIBC we use the index in
8695+ _NL_COLLATE_WEIGHT instead of
8696+ wchar_t string.
8697+
8698+ charset[l+m+n+6] = range_start
8699+ charset[l+m+n+7] = range_end
8700+ ...
8701+ charset[l+m+n+2o+4] = range_start
8702+ charset[l+m+n+2o+5] = range_end
8703+ ifdef _LIBC we use the value looked up
8704+ in _NL_COLLATE_COLLSEQ instead of
8705+ wchar_t character.
8706+
8707+ charset[l+m+n+2o+6] = char
8708+ ...
8709+ charset[l+m+n+2o+p+5] = char
8710+
8711+ */
8712+
8713+ /* We need at least 6 spaces: the opcode, the length of
8714+ char_classes, the length of collating_symbols, the length of
8715+ equivalence_classes, the length of char_ranges, the length of
8716+ chars. */
8717+ GET_BUFFER_SPACE (6);
8718+
8719+ /* Save b as laststart. And We use laststart as the pointer
8720+ to the first element of the charset here.
8721+ In other words, laststart[i] indicates charset[i]. */
8722+ laststart = b;
8723+
8724+ /* We test `*p == '^' twice, instead of using an if
8725+ statement, so we only need one BUF_PUSH. */
8726+ BUF_PUSH (*p == '^' ? charset_not : charset);
8727+ if (*p == '^')
8728+ p++;
8729+
8730+ /* Push the length of char_classes, the length of
8731+ collating_symbols, the length of equivalence_classes, the
8732+ length of char_ranges and the length of chars. */
8733+ BUF_PUSH_3 (0, 0, 0);
8734+ BUF_PUSH_2 (0, 0);
8735+
8736+ /* Remember the first position in the bracket expression. */
8737+ p1 = p;
8738+
8739+ /* charset_not matches newline according to a syntax bit. */
8740+ if ((re_opcode_t) b[-6] == charset_not
8741+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
8742+ {
8743+ BUF_PUSH('\n');
8744+ laststart[5]++; /* Update the length of characters */
8745+ }
8746+
8747+ /* Read in characters and ranges, setting map bits. */
8748+ for (;;)
8749+ {
8750+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
8751+
8752+ PATFETCH (c);
8753+
8754+ /* \ might escape characters inside [...] and [^...]. */
8755+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
8756+ {
8757+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
8758+
8759+ PATFETCH (c1);
8760+ BUF_PUSH(c1);
8761+ laststart[5]++; /* Update the length of chars */
8762+ range_start = c1;
8763+ continue;
8764+ }
8765+
8766+ /* Could be the end of the bracket expression. If it's
8767+ not (i.e., when the bracket expression is `[]' so
8768+ far), the ']' character bit gets set way below. */
8769+ if (c == ']' && p != p1 + 1)
8770+ break;
8771+
8772+ /* Look ahead to see if it's a range when the last thing
8773+ was a character class. */
8774+ if (had_char_class && c == '-' && *p != ']')
8775+ FREE_STACK_RETURN (REG_ERANGE);
8776+
8777+ /* Look ahead to see if it's a range when the last thing
8778+ was a character: if this is a hyphen not at the
8779+ beginning or the end of a list, then it's the range
8780+ operator. */
8781+ if (c == '-'
8782+ && !(p - 2 >= pattern && p[-2] == '[')
8783+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
8784+ && *p != ']')
8785+ {
8786+ reg_errcode_t ret;
8787+ /* Allocate the space for range_start and range_end. */
8788+ GET_BUFFER_SPACE (2);
8789+ /* Update the pointer to indicate end of buffer. */
8790+ b += 2;
8791+ ret = wcs_compile_range (range_start, &p, pend, translate,
8792+ syntax, b, laststart);
8793+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
8794+ range_start = 0xffffffff;
8795+ }
8796+ else if (p[0] == '-' && p[1] != ']')
8797+ { /* This handles ranges made up of characters only. */
8798+ reg_errcode_t ret;
8799+
8800+ /* Move past the `-'. */
8801+ PATFETCH (c1);
8802+ /* Allocate the space for range_start and range_end. */
8803+ GET_BUFFER_SPACE (2);
8804+ /* Update the pointer to indicate end of buffer. */
8805+ b += 2;
8806+ ret = wcs_compile_range (c, &p, pend, translate, syntax, b,
8807+ laststart);
8808+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
8809+ range_start = 0xffffffff;
8810+ }
8811+
8812+ /* See if we're at the beginning of a possible character
8813+ class. */
8814+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
8815+ { /* Leave room for the null. */
8816+ char str[CHAR_CLASS_MAX_LENGTH + 1];
8817+
8818+ PATFETCH (c);
8819+ c1 = 0;
8820+
8821+ /* If pattern is `[[:'. */
8822+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
8823+
8824+ for (;;)
8825+ {
8826+ PATFETCH (c);
8827+ if ((c == ':' && *p == ']') || p == pend)
8828+ break;
8829+ if (c1 < CHAR_CLASS_MAX_LENGTH)
8830+ str[c1++] = c;
8831+ else
8832+ /* This is in any case an invalid class name. */
8833+ str[0] = '\0';
8834+ }
8835+ str[c1] = '\0';
8836+
8837+ /* If isn't a word bracketed by `[:' and `:]':
8838+ undo the ending character, the letters, and leave
8839+ the leading `:' and `[' (but store them as character). */
8840+ if (c == ':' && *p == ']')
8841+ {
8842+ wctype_t wt;
8843+ uintptr_t alignedp;
8844+
8845+ /* Query the character class as wctype_t. */
8846+ wt = IS_CHAR_CLASS (str);
8847+ if (wt == 0)
8848+ FREE_STACK_RETURN (REG_ECTYPE);
8849+
8850+ /* Throw away the ] at the end of the character
8851+ class. */
8852+ PATFETCH (c);
8853+
8854+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
8855+
8856+ /* Allocate the space for character class. */
8857+ GET_BUFFER_SPACE(CHAR_CLASS_SIZE);
8858+ /* Update the pointer to indicate end of buffer. */
8859+ b += CHAR_CLASS_SIZE;
8860+ /* Move data which follow character classes
8861+ not to violate the data. */
8862+ insert_space(CHAR_CLASS_SIZE,
8863+ laststart + 6 + laststart[1],
8864+ b - 1);
8865+ alignedp = ((uintptr_t)(laststart + 6 + laststart[1])
8866+ + __alignof__(wctype_t) - 1)
8867+ & ~(uintptr_t)(__alignof__(wctype_t) - 1);
8868+ /* Store the character class. */
8869+ *((wctype_t*)alignedp) = wt;
8870+ /* Update length of char_classes */
8871+ laststart[1] += CHAR_CLASS_SIZE;
8872+
8873+ had_char_class = true;
8874+ }
8875+ else
8876+ {
8877+ c1++;
8878+ while (c1--)
8879+ PATUNFETCH;
8880+ BUF_PUSH ('[');
8881+ BUF_PUSH (':');
8882+ laststart[5] += 2; /* Update the length of characters */
8883+ range_start = ':';
8884+ had_char_class = false;
8885+ }
8886+ }
8887+ else if (syntax & RE_CHAR_CLASSES && c == '[' && (*p == '='
8888+ || *p == '.'))
8889+ {
8890+ CHAR_T str[128]; /* Should be large enough. */
8891+ CHAR_T delim = *p; /* '=' or '.' */
8892+# ifdef _LIBC
8893+ uint32_t nrules =
8894+ _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
8895+# endif
8896+ PATFETCH (c);
8897+ c1 = 0;
8898+
8899+ /* If pattern is `[[=' or '[[.'. */
8900+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
8901+
8902+ for (;;)
8903+ {
8904+ PATFETCH (c);
8905+ if ((c == delim && *p == ']') || p == pend)
8906+ break;
8907+ if (c1 < sizeof (str) - 1)
8908+ str[c1++] = c;
8909+ else
8910+ /* This is in any case an invalid class name. */
8911+ str[0] = '\0';
8912+ }
8913+ str[c1] = '\0';
8914+
8915+ if (c == delim && *p == ']' && str[0] != '\0')
8916+ {
8917+ unsigned int i, offset;
8918+ /* If we have no collation data we use the default
8919+ collation in which each character is in a class
8920+ by itself. It also means that ASCII is the
8921+ character set and therefore we cannot have character
8922+ with more than one byte in the multibyte
8923+ representation. */
8924+
8925+ /* If not defined _LIBC, we push the name and
8926+ `\0' for the sake of matching performance. */
8927+ int datasize = c1 + 1;
8928+
8929+# ifdef _LIBC
8930+ int32_t idx = 0;
8931+ if (nrules == 0)
8932+# endif
8933+ {
8934+ if (c1 != 1)
8935+ FREE_STACK_RETURN (REG_ECOLLATE);
8936+ }
8937+# ifdef _LIBC
8938+ else
8939+ {
8940+ const int32_t *table;
8941+ const int32_t *weights;
8942+ const int32_t *extra;
8943+ const int32_t *indirect;
8944+ wint_t *cp;
8945+
8946+ /* This #include defines a local function! */
8947+# include <locale/weightwc.h>
8948+
8949+ if(delim == '=')
8950+ {
8951+ /* We push the index for equivalence class. */
8952+ cp = (wint_t*)str;
8953+
8954+ table = (const int32_t *)
8955+ _NL_CURRENT (LC_COLLATE,
8956+ _NL_COLLATE_TABLEWC);
8957+ weights = (const int32_t *)
8958+ _NL_CURRENT (LC_COLLATE,
8959+ _NL_COLLATE_WEIGHTWC);
8960+ extra = (const int32_t *)
8961+ _NL_CURRENT (LC_COLLATE,
8962+ _NL_COLLATE_EXTRAWC);
8963+ indirect = (const int32_t *)
8964+ _NL_CURRENT (LC_COLLATE,
8965+ _NL_COLLATE_INDIRECTWC);
8966+
8967+ idx = findidx ((const wint_t**)&cp, c1);
8968+ if (idx == 0 || cp < (wint_t*) str + c1)
8969+ /* This is no valid character. */
8970+ FREE_STACK_RETURN (REG_ECOLLATE);
8971+
8972+ str[0] = (wchar_t)idx;
8973+ }
8974+ else /* delim == '.' */
8975+ {
8976+ /* We push collation sequence value
8977+ for collating symbol. */
8978+ int32_t table_size;
8979+ const int32_t *symb_table;
8980+ const unsigned char *extra;
8981+ int32_t idx;
8982+ int32_t elem;
8983+ int32_t second;
8984+ int32_t hash;
8985+ char char_str[c1];
8986+
8987+ /* We have to convert the name to a single-byte
8988+ string. This is possible since the names
8989+ consist of ASCII characters and the internal
8990+ representation is UCS4. */
8991+ for (i = 0; i < c1; ++i)
8992+ char_str[i] = str[i];
8993+
8994+ table_size =
8995+ _NL_CURRENT_WORD (LC_COLLATE,
8996+ _NL_COLLATE_SYMB_HASH_SIZEMB);
8997+ symb_table = (const int32_t *)
8998+ _NL_CURRENT (LC_COLLATE,
8999+ _NL_COLLATE_SYMB_TABLEMB);
9000+ extra = (const unsigned char *)
9001+ _NL_CURRENT (LC_COLLATE,
9002+ _NL_COLLATE_SYMB_EXTRAMB);
9003+
9004+ /* Locate the character in the hashing table. */
9005+ hash = elem_hash (char_str, c1);
9006+
9007+ idx = 0;
9008+ elem = hash % table_size;
9009+ second = hash % (table_size - 2);
9010+ while (symb_table[2 * elem] != 0)
9011+ {
9012+ /* First compare the hashing value. */
9013+ if (symb_table[2 * elem] == hash
9014+ && c1 == extra[symb_table[2 * elem + 1]]
9015+ && memcmp (char_str,
9016+ &extra[symb_table[2 * elem + 1]
9017+ + 1], c1) == 0)
9018+ {
9019+ /* Yep, this is the entry. */
9020+ idx = symb_table[2 * elem + 1];
9021+ idx += 1 + extra[idx];
9022+ break;
9023+ }
9024+
9025+ /* Next entry. */
9026+ elem += second;
9027+ }
9028+
9029+ if (symb_table[2 * elem] != 0)
9030+ {
9031+ /* Compute the index of the byte sequence
9032+ in the table. */
9033+ idx += 1 + extra[idx];
9034+ /* Adjust for the alignment. */
9035+ idx = (idx + 3) & ~3;
9036+
9037+ str[0] = (wchar_t) idx + 4;
9038+ }
9039+ else if (symb_table[2 * elem] == 0 && c1 == 1)
9040+ {
9041+ /* No valid character. Match it as a
9042+ single byte character. */
9043+ had_char_class = false;
9044+ BUF_PUSH(str[0]);
9045+ /* Update the length of characters */
9046+ laststart[5]++;
9047+ range_start = str[0];
9048+
9049+ /* Throw away the ] at the end of the
9050+ collating symbol. */
9051+ PATFETCH (c);
9052+ /* exit from the switch block. */
9053+ continue;
9054+ }
9055+ else
9056+ FREE_STACK_RETURN (REG_ECOLLATE);
9057+ }
9058+ datasize = 1;
9059+ }
9060+# endif
9061+ /* Throw away the ] at the end of the equivalence
9062+ class (or collating symbol). */
9063+ PATFETCH (c);
9064+
9065+ /* Allocate the space for the equivalence class
9066+ (or collating symbol) (and '\0' if needed). */
9067+ GET_BUFFER_SPACE(datasize);
9068+ /* Update the pointer to indicate end of buffer. */
9069+ b += datasize;
9070+
9071+ if (delim == '=')
9072+ { /* equivalence class */
9073+ /* Calculate the offset of char_ranges,
9074+ which is next to equivalence_classes. */
9075+ offset = laststart[1] + laststart[2]
9076+ + laststart[3] +6;
9077+ /* Insert space. */
9078+ insert_space(datasize, laststart + offset, b - 1);
9079+
9080+ /* Write the equivalence_class and \0. */
9081+ for (i = 0 ; i < datasize ; i++)
9082+ laststart[offset + i] = str[i];
9083+
9084+ /* Update the length of equivalence_classes. */
9085+ laststart[3] += datasize;
9086+ had_char_class = true;
9087+ }
9088+ else /* delim == '.' */
9089+ { /* collating symbol */
9090+ /* Calculate the offset of the equivalence_classes,
9091+ which is next to collating_symbols. */
9092+ offset = laststart[1] + laststart[2] + 6;
9093+ /* Insert space and write the collationg_symbol
9094+ and \0. */
9095+ insert_space(datasize, laststart + offset, b-1);
9096+ for (i = 0 ; i < datasize ; i++)
9097+ laststart[offset + i] = str[i];
9098+
9099+ /* In re_match_2_internal if range_start < -1, we
9100+ assume -range_start is the offset of the
9101+ collating symbol which is specified as
9102+ the character of the range start. So we assign
9103+ -(laststart[1] + laststart[2] + 6) to
9104+ range_start. */
9105+ range_start = -(laststart[1] + laststart[2] + 6);
9106+ /* Update the length of collating_symbol. */
9107+ laststart[2] += datasize;
9108+ had_char_class = false;
9109+ }
9110+ }
9111+ else
9112+ {
9113+ c1++;
9114+ while (c1--)
9115+ PATUNFETCH;
9116+ BUF_PUSH ('[');
9117+ BUF_PUSH (delim);
9118+ laststart[5] += 2; /* Update the length of characters */
9119+ range_start = delim;
9120+ had_char_class = false;
9121+ }
9122+ }
9123+ else
9124+ {
9125+ had_char_class = false;
9126+ BUF_PUSH(c);
9127+ laststart[5]++; /* Update the length of characters */
9128+ range_start = c;
9129+ }
9130+ }
9131+
9132+#else /* BYTE */
9133+ /* Ensure that we have enough space to push a charset: the
9134+ opcode, the length count, and the bitset; 34 bytes in all. */
9135+ GET_BUFFER_SPACE (34);
9136+
9137+ laststart = b;
9138+
9139+ /* We test `*p == '^' twice, instead of using an if
9140+ statement, so we only need one BUF_PUSH. */
9141+ BUF_PUSH (*p == '^' ? charset_not : charset);
9142+ if (*p == '^')
9143+ p++;
9144+
9145+ /* Remember the first position in the bracket expression. */
9146+ p1 = p;
9147+
9148+ /* Push the number of bytes in the bitmap. */
9149+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
9150+
9151+ /* Clear the whole map. */
9152+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
9153+
9154+ /* charset_not matches newline according to a syntax bit. */
9155+ if ((re_opcode_t) b[-2] == charset_not
9156+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
9157+ SET_LIST_BIT ('\n');
9158+
9159+ /* Read in characters and ranges, setting map bits. */
9160+ for (;;)
9161+ {
9162+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9163+
9164+ PATFETCH (c);
9165+
9166+ /* \ might escape characters inside [...] and [^...]. */
9167+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
9168+ {
9169+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
9170+
9171+ PATFETCH (c1);
9172+ SET_LIST_BIT (c1);
9173+ range_start = c1;
9174+ continue;
9175+ }
9176+
9177+ /* Could be the end of the bracket expression. If it's
9178+ not (i.e., when the bracket expression is `[]' so
9179+ far), the ']' character bit gets set way below. */
9180+ if (c == ']' && p != p1 + 1)
9181+ break;
9182+
9183+ /* Look ahead to see if it's a range when the last thing
9184+ was a character class. */
9185+ if (had_char_class && c == '-' && *p != ']')
9186+ FREE_STACK_RETURN (REG_ERANGE);
9187+
9188+ /* Look ahead to see if it's a range when the last thing
9189+ was a character: if this is a hyphen not at the
9190+ beginning or the end of a list, then it's the range
9191+ operator. */
9192+ if (c == '-'
9193+ && !(p - 2 >= pattern && p[-2] == '[')
9194+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
9195+ && *p != ']')
9196+ {
9197+ reg_errcode_t ret
9198+ = byte_compile_range (range_start, &p, pend, translate,
9199+ syntax, b);
9200+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
9201+ range_start = 0xffffffff;
9202+ }
9203+
9204+ else if (p[0] == '-' && p[1] != ']')
9205+ { /* This handles ranges made up of characters only. */
9206+ reg_errcode_t ret;
9207+
9208+ /* Move past the `-'. */
9209+ PATFETCH (c1);
9210+
9211+ ret = byte_compile_range (c, &p, pend, translate, syntax, b);
9212+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
9213+ range_start = 0xffffffff;
9214+ }
9215+
9216+ /* See if we're at the beginning of a possible character
9217+ class. */
9218+
9219+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
9220+ { /* Leave room for the null. */
9221+ char str[CHAR_CLASS_MAX_LENGTH + 1];
9222+
9223+ PATFETCH (c);
9224+ c1 = 0;
9225+
9226+ /* If pattern is `[[:'. */
9227+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9228+
9229+ for (;;)
9230+ {
9231+ PATFETCH (c);
9232+ if ((c == ':' && *p == ']') || p == pend)
9233+ break;
9234+ if (((int) c1) < CHAR_CLASS_MAX_LENGTH)
9235+ str[c1++] = c;
9236+ else
9237+ /* This is in any case an invalid class name. */
9238+ str[0] = '\0';
9239+ }
9240+ str[c1] = '\0';
9241+
9242+ /* If isn't a word bracketed by `[:' and `:]':
9243+ undo the ending character, the letters, and leave
9244+ the leading `:' and `[' (but set bits for them). */
9245+ if (c == ':' && *p == ']')
9246+ {
9247+# if WIDE_CHAR_SUPPORT
9248+ boolean is_lower = STREQ (str, "lower");
9249+ boolean is_upper = STREQ (str, "upper");
9250+ wctype_t wt;
9251+ int ch;
9252+
9253+ wt = IS_CHAR_CLASS (str);
9254+ if (wt == 0)
9255+ FREE_STACK_RETURN (REG_ECTYPE);
9256+
9257+ /* Throw away the ] at the end of the character
9258+ class. */
9259+ PATFETCH (c);
9260+
9261+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9262+
9263+ for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
9264+ {
9265+# ifdef _LIBC
9266+ if (__iswctype (__btowc (ch), wt))
9267+ SET_LIST_BIT (ch);
9268+# else
9269+ if (iswctype (btowc (ch), wt))
9270+ SET_LIST_BIT (ch);
9271+# endif
9272+
9273+ if (translate && (is_upper || is_lower)
9274+ && (ISUPPER (ch) || ISLOWER (ch)))
9275+ SET_LIST_BIT (ch);
9276+ }
9277+
9278+ had_char_class = true;
9279+# else
9280+ int ch;
9281+ boolean is_alnum = STREQ (str, "alnum");
9282+ boolean is_alpha = STREQ (str, "alpha");
9283+ boolean is_blank = STREQ (str, "blank");
9284+ boolean is_cntrl = STREQ (str, "cntrl");
9285+ boolean is_digit = STREQ (str, "digit");
9286+ boolean is_graph = STREQ (str, "graph");
9287+ boolean is_lower = STREQ (str, "lower");
9288+ boolean is_print = STREQ (str, "print");
9289+ boolean is_punct = STREQ (str, "punct");
9290+ boolean is_space = STREQ (str, "space");
9291+ boolean is_upper = STREQ (str, "upper");
9292+ boolean is_xdigit = STREQ (str, "xdigit");
9293+
9294+ if (!IS_CHAR_CLASS (str))
9295+ FREE_STACK_RETURN (REG_ECTYPE);
9296+
9297+ /* Throw away the ] at the end of the character
9298+ class. */
9299+ PATFETCH (c);
9300+
9301+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9302+
9303+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
9304+ {
9305+ /* This was split into 3 if's to
9306+ avoid an arbitrary limit in some compiler. */
9307+ if ( (is_alnum && ISALNUM (ch))
9308+ || (is_alpha && ISALPHA (ch))
9309+ || (is_blank && ISBLANK (ch))
9310+ || (is_cntrl && ISCNTRL (ch)))
9311+ SET_LIST_BIT (ch);
9312+ if ( (is_digit && ISDIGIT (ch))
9313+ || (is_graph && ISGRAPH (ch))
9314+ || (is_lower && ISLOWER (ch))
9315+ || (is_print && ISPRINT (ch)))
9316+ SET_LIST_BIT (ch);
9317+ if ( (is_punct && ISPUNCT (ch))
9318+ || (is_space && ISSPACE (ch))
9319+ || (is_upper && ISUPPER (ch))
9320+ || (is_xdigit && ISXDIGIT (ch)))
9321+ SET_LIST_BIT (ch);
9322+ if ( translate && (is_upper || is_lower)
9323+ && (ISUPPER (ch) || ISLOWER (ch)))
9324+ SET_LIST_BIT (ch);
9325+ }
9326+ had_char_class = true;
9327+# endif /* libc || wctype.h */
9328+ }
9329+ else
9330+ {
9331+ c1++;
9332+ while (c1--)
9333+ PATUNFETCH;
9334+ SET_LIST_BIT ('[');
9335+ SET_LIST_BIT (':');
9336+ range_start = ':';
9337+ had_char_class = false;
9338+ }
9339+ }
9340+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '=')
9341+ {
9342+ unsigned char str[MB_LEN_MAX + 1];
9343+# ifdef _LIBC
9344+ uint32_t nrules =
9345+ _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
9346+# endif
9347+
9348+ PATFETCH (c);
9349+ c1 = 0;
9350+
9351+ /* If pattern is `[[='. */
9352+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9353+
9354+ for (;;)
9355+ {
9356+ PATFETCH (c);
9357+ if ((c == '=' && *p == ']') || p == pend)
9358+ break;
9359+ if (c1 < MB_LEN_MAX)
9360+ str[c1++] = c;
9361+ else
9362+ /* This is in any case an invalid class name. */
9363+ str[0] = '\0';
9364+ }
9365+ str[c1] = '\0';
9366+
9367+ if (c == '=' && *p == ']' && str[0] != '\0')
9368+ {
9369+ /* If we have no collation data we use the default
9370+ collation in which each character is in a class
9371+ by itself. It also means that ASCII is the
9372+ character set and therefore we cannot have character
9373+ with more than one byte in the multibyte
9374+ representation. */
9375+# ifdef _LIBC
9376+ if (nrules == 0)
9377+# endif
9378+ {
9379+ if (c1 != 1)
9380+ FREE_STACK_RETURN (REG_ECOLLATE);
9381+
9382+ /* Throw away the ] at the end of the equivalence
9383+ class. */
9384+ PATFETCH (c);
9385+
9386+ /* Set the bit for the character. */
9387+ SET_LIST_BIT (str[0]);
9388+ }
9389+# ifdef _LIBC
9390+ else
9391+ {
9392+ /* Try to match the byte sequence in `str' against
9393+ those known to the collate implementation.
9394+ First find out whether the bytes in `str' are
9395+ actually from exactly one character. */
9396+ const int32_t *table;
9397+ const unsigned char *weights;
9398+ const unsigned char *extra;
9399+ const int32_t *indirect;
9400+ int32_t idx;
9401+ const unsigned char *cp = str;
9402+ int ch;
9403+
9404+ /* This #include defines a local function! */
9405+# include <locale/weight.h>
9406+
9407+ table = (const int32_t *)
9408+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
9409+ weights = (const unsigned char *)
9410+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
9411+ extra = (const unsigned char *)
9412+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
9413+ indirect = (const int32_t *)
9414+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
9415+
9416+ idx = findidx (&cp, c1);
9417+ if (idx == 0 || cp < str + c1)
9418+ /* This is no valid character. */
9419+ FREE_STACK_RETURN (REG_ECOLLATE);
9420+
9421+ /* Throw away the ] at the end of the equivalence
9422+ class. */
9423+ PATFETCH (c);
9424+
9425+ /* Now we have to go throught the whole table
9426+ and find all characters which have the same
9427+ first level weight.
9428+
9429+ XXX Note that this is not entirely correct.
9430+ we would have to match multibyte sequences
9431+ but this is not possible with the current
9432+ implementation. */
9433+ for (ch = 1; ch < 256; ++ch)
9434+ /* XXX This test would have to be changed if we
9435+ would allow matching multibyte sequences. */
9436+ if (table[ch] > 0)
9437+ {
9438+ int32_t idx2 = table[ch];
9439+ size_t len = weights[idx2];
9440+
9441+ /* Test whether the lenghts match. */
9442+ if (weights[idx] == len)
9443+ {
9444+ /* They do. New compare the bytes of
9445+ the weight. */
9446+ size_t cnt = 0;
9447+
9448+ while (cnt < len
9449+ && (weights[idx + 1 + cnt]
9450+ == weights[idx2 + 1 + cnt]))
9451+ ++cnt;
9452+
9453+ if (cnt == len)
9454+ /* They match. Mark the character as
9455+ acceptable. */
9456+ SET_LIST_BIT (ch);
9457+ }
9458+ }
9459+ }
9460+# endif
9461+ had_char_class = true;
9462+ }
9463+ else
9464+ {
9465+ c1++;
9466+ while (c1--)
9467+ PATUNFETCH;
9468+ SET_LIST_BIT ('[');
9469+ SET_LIST_BIT ('=');
9470+ range_start = '=';
9471+ had_char_class = false;
9472+ }
9473+ }
9474+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '.')
9475+ {
9476+ unsigned char str[128]; /* Should be large enough. */
9477+# ifdef _LIBC
9478+ uint32_t nrules =
9479+ _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
9480+# endif
9481+
9482+ PATFETCH (c);
9483+ c1 = 0;
9484+
9485+ /* If pattern is `[[.'. */
9486+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
9487+
9488+ for (;;)
9489+ {
9490+ PATFETCH (c);
9491+ if ((c == '.' && *p == ']') || p == pend)
9492+ break;
9493+ if (c1 < sizeof (str))
9494+ str[c1++] = c;
9495+ else
9496+ /* This is in any case an invalid class name. */
9497+ str[0] = '\0';
9498+ }
9499+ str[c1] = '\0';
9500+
9501+ if (c == '.' && *p == ']' && str[0] != '\0')
9502+ {
9503+ /* If we have no collation data we use the default
9504+ collation in which each character is the name
9505+ for its own class which contains only the one
9506+ character. It also means that ASCII is the
9507+ character set and therefore we cannot have character
9508+ with more than one byte in the multibyte
9509+ representation. */
9510+# ifdef _LIBC
9511+ if (nrules == 0)
9512+# endif
9513+ {
9514+ if (c1 != 1)
9515+ FREE_STACK_RETURN (REG_ECOLLATE);
9516+
9517+ /* Throw away the ] at the end of the equivalence
9518+ class. */
9519+ PATFETCH (c);
9520+
9521+ /* Set the bit for the character. */
9522+ SET_LIST_BIT (str[0]);
9523+ range_start = ((const unsigned char *) str)[0];
9524+ }
9525+# ifdef _LIBC
9526+ else
9527+ {
9528+ /* Try to match the byte sequence in `str' against
9529+ those known to the collate implementation.
9530+ First find out whether the bytes in `str' are
9531+ actually from exactly one character. */
9532+ int32_t table_size;
9533+ const int32_t *symb_table;
9534+ const unsigned char *extra;
9535+ int32_t idx;
9536+ int32_t elem;
9537+ int32_t second;
9538+ int32_t hash;
9539+
9540+ table_size =
9541+ _NL_CURRENT_WORD (LC_COLLATE,
9542+ _NL_COLLATE_SYMB_HASH_SIZEMB);
9543+ symb_table = (const int32_t *)
9544+ _NL_CURRENT (LC_COLLATE,
9545+ _NL_COLLATE_SYMB_TABLEMB);
9546+ extra = (const unsigned char *)
9547+ _NL_CURRENT (LC_COLLATE,
9548+ _NL_COLLATE_SYMB_EXTRAMB);
9549+
9550+ /* Locate the character in the hashing table. */
9551+ hash = elem_hash ((const char *) str, c1);
9552+
9553+ idx = 0;
9554+ elem = hash % table_size;
9555+ second = hash % (table_size - 2);
9556+ while (symb_table[2 * elem] != 0)
9557+ {
9558+ /* First compare the hashing value. */
9559+ if (symb_table[2 * elem] == hash
9560+ && c1 == extra[symb_table[2 * elem + 1]]
9561+ && memcmp (str,
9562+ &extra[symb_table[2 * elem + 1]
9563+ + 1],
9564+ c1) == 0)
9565+ {
9566+ /* Yep, this is the entry. */
9567+ idx = symb_table[2 * elem + 1];
9568+ idx += 1 + extra[idx];
9569+ break;
9570+ }
9571+
9572+ /* Next entry. */
9573+ elem += second;
9574+ }
9575+
9576+ if (symb_table[2 * elem] == 0)
9577+ /* This is no valid character. */
9578+ FREE_STACK_RETURN (REG_ECOLLATE);
9579+
9580+ /* Throw away the ] at the end of the equivalence
9581+ class. */
9582+ PATFETCH (c);
9583+
9584+ /* Now add the multibyte character(s) we found
9585+ to the accept list.
9586+
9587+ XXX Note that this is not entirely correct.
9588+ we would have to match multibyte sequences
9589+ but this is not possible with the current
9590+ implementation. Also, we have to match
9591+ collating symbols, which expand to more than
9592+ one file, as a whole and not allow the
9593+ individual bytes. */
9594+ c1 = extra[idx++];
9595+ if (c1 == 1)
9596+ range_start = extra[idx];
9597+ while (c1-- > 0)
9598+ {
9599+ SET_LIST_BIT (extra[idx]);
9600+ ++idx;
9601+ }
9602+ }
9603+# endif
9604+ had_char_class = false;
9605+ }
9606+ else
9607+ {
9608+ c1++;
9609+ while (c1--)
9610+ PATUNFETCH;
9611+ SET_LIST_BIT ('[');
9612+ SET_LIST_BIT ('.');
9613+ range_start = '.';
9614+ had_char_class = false;
9615+ }
9616+ }
9617+ else
9618+ {
9619+ had_char_class = false;
9620+ SET_LIST_BIT (c);
9621+ range_start = c;
9622+ }
9623+ }
9624+
9625+ /* Discard any (non)matching list bytes that are all 0 at the
9626+ end of the map. Decrease the map-length byte too. */
9627+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
9628+ b[-1]--;
9629+ b += b[-1];
9630+#endif /* WCHAR */
9631+ }
9632+ break;
9633+
9634+
9635+ case '(':
9636+ if (syntax & RE_NO_BK_PARENS)
9637+ goto handle_open;
9638+ else
9639+ goto normal_char;
9640+
9641+
9642+ case ')':
9643+ if (syntax & RE_NO_BK_PARENS)
9644+ goto handle_close;
9645+ else
9646+ goto normal_char;
9647+
9648+
9649+ case '\n':
9650+ if (syntax & RE_NEWLINE_ALT)
9651+ goto handle_alt;
9652+ else
9653+ goto normal_char;
9654+
9655+
9656+ case '|':
9657+ if (syntax & RE_NO_BK_VBAR)
9658+ goto handle_alt;
9659+ else
9660+ goto normal_char;
9661+
9662+
9663+ case '{':
9664+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
9665+ goto handle_interval;
9666+ else
9667+ goto normal_char;
9668+
9669+
9670+ case '\\':
9671+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
9672+
9673+ /* Do not translate the character after the \, so that we can
9674+ distinguish, e.g., \B from \b, even if we normally would
9675+ translate, e.g., B to b. */
9676+ PATFETCH_RAW (c);
9677+
9678+ switch (c)
9679+ {
9680+ case '(':
9681+ if (syntax & RE_NO_BK_PARENS)
9682+ goto normal_backslash;
9683+
9684+ handle_open:
9685+ bufp->re_nsub++;
9686+ regnum++;
9687+
9688+ if (COMPILE_STACK_FULL)
9689+ {
9690+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
9691+ compile_stack_elt_t);
9692+ if (compile_stack.stack == NULL) return REG_ESPACE;
9693+
9694+ compile_stack.size <<= 1;
9695+ }
9696+
9697+ /* These are the values to restore when we hit end of this
9698+ group. They are all relative offsets, so that if the
9699+ whole pattern moves because of realloc, they will still
9700+ be valid. */
9701+ COMPILE_STACK_TOP.begalt_offset = begalt - COMPILED_BUFFER_VAR;
9702+ COMPILE_STACK_TOP.fixup_alt_jump
9703+ = fixup_alt_jump ? fixup_alt_jump - COMPILED_BUFFER_VAR + 1 : 0;
9704+ COMPILE_STACK_TOP.laststart_offset = b - COMPILED_BUFFER_VAR;
9705+ COMPILE_STACK_TOP.regnum = regnum;
9706+
9707+ /* We will eventually replace the 0 with the number of
9708+ groups inner to this one. But do not push a
9709+ start_memory for groups beyond the last one we can
9710+ represent in the compiled pattern. */
9711+ if (regnum <= MAX_REGNUM)
9712+ {
9713+ COMPILE_STACK_TOP.inner_group_offset = b
9714+ - COMPILED_BUFFER_VAR + 2;
9715+ BUF_PUSH_3 (start_memory, regnum, 0);
9716+ }
9717+
9718+ compile_stack.avail++;
9719+
9720+ fixup_alt_jump = 0;
9721+ laststart = 0;
9722+ begalt = b;
9723+ /* If we've reached MAX_REGNUM groups, then this open
9724+ won't actually generate any code, so we'll have to
9725+ clear pending_exact explicitly. */
9726+ pending_exact = 0;
9727+ break;
9728+
9729+
9730+ case ')':
9731+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
9732+
9733+ if (COMPILE_STACK_EMPTY)
9734+ {
9735+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
9736+ goto normal_backslash;
9737+ else
9738+ FREE_STACK_RETURN (REG_ERPAREN);
9739+ }
9740+
9741+ handle_close:
9742+ if (fixup_alt_jump)
9743+ { /* Push a dummy failure point at the end of the
9744+ alternative for a possible future
9745+ `pop_failure_jump' to pop. See comments at
9746+ `push_dummy_failure' in `re_match_2'. */
9747+ BUF_PUSH (push_dummy_failure);
9748+
9749+ /* We allocated space for this jump when we assigned
9750+ to `fixup_alt_jump', in the `handle_alt' case below. */
9751+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
9752+ }
9753+
9754+ /* See similar code for backslashed left paren above. */
9755+ if (COMPILE_STACK_EMPTY)
9756+ {
9757+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
9758+ goto normal_char;
9759+ else
9760+ FREE_STACK_RETURN (REG_ERPAREN);
9761+ }
9762+
9763+ /* Since we just checked for an empty stack above, this
9764+ ``can't happen''. */
9765+ assert (compile_stack.avail != 0);
9766+ {
9767+ /* We don't just want to restore into `regnum', because
9768+ later groups should continue to be numbered higher,
9769+ as in `(ab)c(de)' -- the second group is #2. */
9770+ regnum_t this_group_regnum;
9771+
9772+ compile_stack.avail--;
9773+ begalt = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.begalt_offset;
9774+ fixup_alt_jump
9775+ = COMPILE_STACK_TOP.fixup_alt_jump
9776+ ? COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.fixup_alt_jump - 1
9777+ : 0;
9778+ laststart = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.laststart_offset;
9779+ this_group_regnum = COMPILE_STACK_TOP.regnum;
9780+ /* If we've reached MAX_REGNUM groups, then this open
9781+ won't actually generate any code, so we'll have to
9782+ clear pending_exact explicitly. */
9783+ pending_exact = 0;
9784+
9785+ /* We're at the end of the group, so now we know how many
9786+ groups were inside this one. */
9787+ if (this_group_regnum <= MAX_REGNUM)
9788+ {
9789+ UCHAR_T *inner_group_loc
9790+ = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.inner_group_offset;
9791+
9792+ *inner_group_loc = regnum - this_group_regnum;
9793+ BUF_PUSH_3 (stop_memory, this_group_regnum,
9794+ regnum - this_group_regnum);
9795+ }
9796+ }
9797+ break;
9798+
9799+
9800+ case '|': /* `\|'. */
9801+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
9802+ goto normal_backslash;
9803+ handle_alt:
9804+ if (syntax & RE_LIMITED_OPS)
9805+ goto normal_char;
9806+
9807+ /* Insert before the previous alternative a jump which
9808+ jumps to this alternative if the former fails. */
9809+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
9810+ INSERT_JUMP (on_failure_jump, begalt,
9811+ b + 2 + 2 * OFFSET_ADDRESS_SIZE);
9812+ pending_exact = 0;
9813+ b += 1 + OFFSET_ADDRESS_SIZE;
9814+
9815+ /* The alternative before this one has a jump after it
9816+ which gets executed if it gets matched. Adjust that
9817+ jump so it will jump to this alternative's analogous
9818+ jump (put in below, which in turn will jump to the next
9819+ (if any) alternative's such jump, etc.). The last such
9820+ jump jumps to the correct final destination. A picture:
9821+ _____ _____
9822+ | | | |
9823+ | v | v
9824+ a | b | c
9825+
9826+ If we are at `b', then fixup_alt_jump right now points to a
9827+ three-byte space after `a'. We'll put in the jump, set
9828+ fixup_alt_jump to right after `b', and leave behind three
9829+ bytes which we'll fill in when we get to after `c'. */
9830+
9831+ if (fixup_alt_jump)
9832+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
9833+
9834+ /* Mark and leave space for a jump after this alternative,
9835+ to be filled in later either by next alternative or
9836+ when know we're at the end of a series of alternatives. */
9837+ fixup_alt_jump = b;
9838+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
9839+ b += 1 + OFFSET_ADDRESS_SIZE;
9840+
9841+ laststart = 0;
9842+ begalt = b;
9843+ break;
9844+
9845+
9846+ case '{':
9847+ /* If \{ is a literal. */
9848+ if (!(syntax & RE_INTERVALS)
9849+ /* If we're at `\{' and it's not the open-interval
9850+ operator. */
9851+ || (syntax & RE_NO_BK_BRACES))
9852+ goto normal_backslash;
9853+
9854+ handle_interval:
9855+ {
9856+ /* If got here, then the syntax allows intervals. */
9857+
9858+ /* At least (most) this many matches must be made. */
9859+ int lower_bound = -1, upper_bound = -1;
9860+
9861+ /* Place in the uncompiled pattern (i.e., just after
9862+ the '{') to go back to if the interval is invalid. */
9863+ const CHAR_T *beg_interval = p;
9864+
9865+ if (p == pend)
9866+ goto invalid_interval;
9867+
9868+ GET_UNSIGNED_NUMBER (lower_bound);
9869+
9870+ if (c == ',')
9871+ {
9872+ GET_UNSIGNED_NUMBER (upper_bound);
9873+ if (upper_bound < 0)
9874+ upper_bound = RE_DUP_MAX;
9875+ }
9876+ else
9877+ /* Interval such as `{1}' => match exactly once. */
9878+ upper_bound = lower_bound;
9879+
9880+ if (! (0 <= lower_bound && lower_bound <= upper_bound))
9881+ goto invalid_interval;
9882+
9883+ if (!(syntax & RE_NO_BK_BRACES))
9884+ {
9885+ if (c != '\\' || p == pend)
9886+ goto invalid_interval;
9887+ PATFETCH (c);
9888+ }
9889+
9890+ if (c != '}')
9891+ goto invalid_interval;
9892+
9893+ /* If it's invalid to have no preceding re. */
9894+ if (!laststart)
9895+ {
9896+ if (syntax & RE_CONTEXT_INVALID_OPS
9897+ && !(syntax & RE_INVALID_INTERVAL_ORD))
9898+ FREE_STACK_RETURN (REG_BADRPT);
9899+ else if (syntax & RE_CONTEXT_INDEP_OPS)
9900+ laststart = b;
9901+ else
9902+ goto unfetch_interval;
9903+ }
9904+
9905+ /* We just parsed a valid interval. */
9906+
9907+ if (RE_DUP_MAX < upper_bound)
9908+ FREE_STACK_RETURN (REG_BADBR);
9909+
9910+ /* If the upper bound is zero, don't want to succeed at
9911+ all; jump from `laststart' to `b + 3', which will be
9912+ the end of the buffer after we insert the jump. */
9913+ /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE'
9914+ instead of 'b + 3'. */
9915+ if (upper_bound == 0)
9916+ {
9917+ GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
9918+ INSERT_JUMP (jump, laststart, b + 1
9919+ + OFFSET_ADDRESS_SIZE);
9920+ b += 1 + OFFSET_ADDRESS_SIZE;
9921+ }
9922+
9923+ /* Otherwise, we have a nontrivial interval. When
9924+ we're all done, the pattern will look like:
9925+ set_number_at <jump count> <upper bound>
9926+ set_number_at <succeed_n count> <lower bound>
9927+ succeed_n <after jump addr> <succeed_n count>
9928+ <body of loop>
9929+ jump_n <succeed_n addr> <jump count>
9930+ (The upper bound and `jump_n' are omitted if
9931+ `upper_bound' is 1, though.) */
9932+ else
9933+ { /* If the upper bound is > 1, we need to insert
9934+ more at the end of the loop. */
9935+ unsigned nbytes = 2 + 4 * OFFSET_ADDRESS_SIZE +
9936+ (upper_bound > 1) * (2 + 4 * OFFSET_ADDRESS_SIZE);
9937+
9938+ GET_BUFFER_SPACE (nbytes);
9939+
9940+ /* Initialize lower bound of the `succeed_n', even
9941+ though it will be set during matching by its
9942+ attendant `set_number_at' (inserted next),
9943+ because `re_compile_fastmap' needs to know.
9944+ Jump to the `jump_n' we might insert below. */
9945+ INSERT_JUMP2 (succeed_n, laststart,
9946+ b + 1 + 2 * OFFSET_ADDRESS_SIZE
9947+ + (upper_bound > 1) * (1 + 2 * OFFSET_ADDRESS_SIZE)
9948+ , lower_bound);
9949+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
9950+
9951+ /* Code to initialize the lower bound. Insert
9952+ before the `succeed_n'. The `5' is the last two
9953+ bytes of this `set_number_at', plus 3 bytes of
9954+ the following `succeed_n'. */
9955+ /* ifdef WCHAR, The '1+2*OFFSET_ADDRESS_SIZE'
9956+ is the 'set_number_at', plus '1+OFFSET_ADDRESS_SIZE'
9957+ of the following `succeed_n'. */
9958+ PREFIX(insert_op2) (set_number_at, laststart, 1
9959+ + 2 * OFFSET_ADDRESS_SIZE, lower_bound, b);
9960+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
9961+
9962+ if (upper_bound > 1)
9963+ { /* More than one repetition is allowed, so
9964+ append a backward jump to the `succeed_n'
9965+ that starts this interval.
9966+
9967+ When we've reached this during matching,
9968+ we'll have matched the interval once, so
9969+ jump back only `upper_bound - 1' times. */
9970+ STORE_JUMP2 (jump_n, b, laststart
9971+ + 2 * OFFSET_ADDRESS_SIZE + 1,
9972+ upper_bound - 1);
9973+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
9974+
9975+ /* The location we want to set is the second
9976+ parameter of the `jump_n'; that is `b-2' as
9977+ an absolute address. `laststart' will be
9978+ the `set_number_at' we're about to insert;
9979+ `laststart+3' the number to set, the source
9980+ for the relative address. But we are
9981+ inserting into the middle of the pattern --
9982+ so everything is getting moved up by 5.
9983+ Conclusion: (b - 2) - (laststart + 3) + 5,
9984+ i.e., b - laststart.
9985+
9986+ We insert this at the beginning of the loop
9987+ so that if we fail during matching, we'll
9988+ reinitialize the bounds. */
9989+ PREFIX(insert_op2) (set_number_at, laststart,
9990+ b - laststart,
9991+ upper_bound - 1, b);
9992+ b += 1 + 2 * OFFSET_ADDRESS_SIZE;
9993+ }
9994+ }
9995+ pending_exact = 0;
9996+ break;
9997+
9998+ invalid_interval:
9999+ if (!(syntax & RE_INVALID_INTERVAL_ORD))
10000+ FREE_STACK_RETURN (p == pend ? REG_EBRACE : REG_BADBR);
10001+ unfetch_interval:
10002+ /* Match the characters as literals. */
10003+ p = beg_interval;
10004+ c = '{';
10005+ if (syntax & RE_NO_BK_BRACES)
10006+ goto normal_char;
10007+ else
10008+ goto normal_backslash;
10009+ }
10010+
10011+#ifdef emacs
10012+ /* There is no way to specify the before_dot and after_dot
10013+ operators. rms says this is ok. --karl */
10014+ case '=':
10015+ BUF_PUSH (at_dot);
10016+ break;
10017+
10018+ case 's':
10019+ laststart = b;
10020+ PATFETCH (c);
10021+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
10022+ break;
10023+
10024+ case 'S':
10025+ laststart = b;
10026+ PATFETCH (c);
10027+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
10028+ break;
10029+#endif /* emacs */
10030+
10031+
10032+ case 'w':
10033+ if (syntax & RE_NO_GNU_OPS)
10034+ goto normal_char;
10035+ laststart = b;
10036+ BUF_PUSH (wordchar);
10037+ break;
10038+
10039+
10040+ case 'W':
10041+ if (syntax & RE_NO_GNU_OPS)
10042+ goto normal_char;
10043+ laststart = b;
10044+ BUF_PUSH (notwordchar);
10045+ break;
10046+
10047+
10048+ case '<':
10049+ if (syntax & RE_NO_GNU_OPS)
10050+ goto normal_char;
10051+ BUF_PUSH (wordbeg);
10052+ break;
10053+
10054+ case '>':
10055+ if (syntax & RE_NO_GNU_OPS)
10056+ goto normal_char;
10057+ BUF_PUSH (wordend);
10058+ break;
10059+
10060+ case 'b':
10061+ if (syntax & RE_NO_GNU_OPS)
10062+ goto normal_char;
10063+ BUF_PUSH (wordbound);
10064+ break;
10065+
10066+ case 'B':
10067+ if (syntax & RE_NO_GNU_OPS)
10068+ goto normal_char;
10069+ BUF_PUSH (notwordbound);
10070+ break;
10071+
10072+ case '`':
10073+ if (syntax & RE_NO_GNU_OPS)
10074+ goto normal_char;
10075+ BUF_PUSH (begbuf);
10076+ break;
10077+
10078+ case '\'':
10079+ if (syntax & RE_NO_GNU_OPS)
10080+ goto normal_char;
10081+ BUF_PUSH (endbuf);
10082+ break;
10083+
10084+ case '1': case '2': case '3': case '4': case '5':
10085+ case '6': case '7': case '8': case '9':
10086+ if (syntax & RE_NO_BK_REFS)
10087+ goto normal_char;
10088+
10089+ c1 = c - '0';
10090+
10091+ if (c1 > regnum)
10092+ FREE_STACK_RETURN (REG_ESUBREG);
10093+
10094+ /* Can't back reference to a subexpression if inside of it. */
10095+ if (group_in_compile_stack (compile_stack, (regnum_t) c1))
10096+ goto normal_char;
10097+
10098+ laststart = b;
10099+ BUF_PUSH_2 (duplicate, c1);
10100+ break;
10101+
10102+
10103+ case '+':
10104+ case '?':
10105+ if (syntax & RE_BK_PLUS_QM)
10106+ goto handle_plus;
10107+ else
10108+ goto normal_backslash;
10109+
10110+ default:
10111+ normal_backslash:
10112+ /* You might think it would be useful for \ to mean
10113+ not to translate; but if we don't translate it
10114+ it will never match anything. */
10115+ c = TRANSLATE (c);
10116+ goto normal_char;
10117+ }
10118+ break;
10119+
10120+
10121+ default:
10122+ /* Expects the character in `c'. */
10123+ normal_char:
10124+ /* If no exactn currently being built. */
10125+ if (!pending_exact
10126+#ifdef WCHAR
10127+ /* If last exactn handle binary(or character) and
10128+ new exactn handle character(or binary). */
10129+ || is_exactn_bin != is_binary[p - 1 - pattern]
10130+#endif /* WCHAR */
10131+
10132+ /* If last exactn not at current position. */
10133+ || pending_exact + *pending_exact + 1 != b
10134+
10135+ /* We have only one byte following the exactn for the count. */
10136+ || *pending_exact == (1 << BYTEWIDTH) - 1
10137+
10138+ /* If followed by a repetition operator. */
10139+ || *p == '*' || *p == '^'
10140+ || ((syntax & RE_BK_PLUS_QM)
10141+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
10142+ : (*p == '+' || *p == '?'))
10143+ || ((syntax & RE_INTERVALS)
10144+ && ((syntax & RE_NO_BK_BRACES)
10145+ ? *p == '{'
10146+ : (p[0] == '\\' && p[1] == '{'))))
10147+ {
10148+ /* Start building a new exactn. */
10149+
10150+ laststart = b;
10151+
10152+#ifdef WCHAR
10153+ /* Is this exactn binary data or character? */
10154+ is_exactn_bin = is_binary[p - 1 - pattern];
10155+ if (is_exactn_bin)
10156+ BUF_PUSH_2 (exactn_bin, 0);
10157+ else
10158+ BUF_PUSH_2 (exactn, 0);
10159+#else
10160+ BUF_PUSH_2 (exactn, 0);
10161+#endif /* WCHAR */
10162+ pending_exact = b - 1;
10163+ }
10164+
10165+ BUF_PUSH (c);
10166+ (*pending_exact)++;
10167+ break;
10168+ } /* switch (c) */
10169+ } /* while p != pend */
10170+
10171+
10172+ /* Through the pattern now. */
10173+
10174+ if (fixup_alt_jump)
10175+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
10176+
10177+ if (!COMPILE_STACK_EMPTY)
10178+ FREE_STACK_RETURN (REG_EPAREN);
10179+
10180+ /* If we don't want backtracking, force success
10181+ the first time we reach the end of the compiled pattern. */
10182+ if (syntax & RE_NO_POSIX_BACKTRACKING)
10183+ BUF_PUSH (succeed);
10184+
10185+#ifdef WCHAR
10186+ free (pattern);
10187+ free (mbs_offset);
10188+ free (is_binary);
10189+#endif
10190+ free (compile_stack.stack);
10191+
10192+ /* We have succeeded; set the length of the buffer. */
10193+#ifdef WCHAR
10194+ bufp->used = (uintptr_t) b - (uintptr_t) COMPILED_BUFFER_VAR;
10195+#else
10196+ bufp->used = b - bufp->buffer;
10197+#endif
10198+
10199+#ifdef DEBUG
10200+ if (debug)
10201+ {
10202+ DEBUG_PRINT1 ("\nCompiled pattern: \n");
10203+ PREFIX(print_compiled_pattern) (bufp);
10204+ }
10205+#endif /* DEBUG */
10206+
10207+#ifndef MATCH_MAY_ALLOCATE
10208+ /* Initialize the failure stack to the largest possible stack. This
10209+ isn't necessary unless we're trying to avoid calling alloca in
10210+ the search and match routines. */
10211+ {
10212+ int num_regs = bufp->re_nsub + 1;
10213+
10214+ /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
10215+ is strictly greater than re_max_failures, the largest possible stack
10216+ is 2 * re_max_failures failure points. */
10217+ if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
10218+ {
10219+ fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
10220+
10221+# ifdef emacs
10222+ if (! fail_stack.stack)
10223+ fail_stack.stack
10224+ = (PREFIX(fail_stack_elt_t) *) xmalloc (fail_stack.size
10225+ * sizeof (PREFIX(fail_stack_elt_t)));
10226+ else
10227+ fail_stack.stack
10228+ = (PREFIX(fail_stack_elt_t) *) xrealloc (fail_stack.stack,
10229+ (fail_stack.size
10230+ * sizeof (PREFIX(fail_stack_elt_t))));
10231+# else /* not emacs */
10232+ if (! fail_stack.stack)
10233+ fail_stack.stack
10234+ = (PREFIX(fail_stack_elt_t) *) malloc (fail_stack.size
10235+ * sizeof (PREFIX(fail_stack_elt_t)));
10236+ else
10237+ fail_stack.stack
10238+ = (PREFIX(fail_stack_elt_t) *) realloc (fail_stack.stack,
10239+ (fail_stack.size
10240+ * sizeof (PREFIX(fail_stack_elt_t))));
10241+# endif /* not emacs */
10242+ }
10243+
10244+ PREFIX(regex_grow_registers) (num_regs);
10245+ }
10246+#endif /* not MATCH_MAY_ALLOCATE */
10247+
10248+ return REG_NOERROR;
10249+} /* regex_compile */
10250+
10251+/* Subroutines for `regex_compile'. */
10252+
10253+/* Store OP at LOC followed by two-byte integer parameter ARG. */
10254+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
10255+
10256+static void
10257+PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg)
10258+{
10259+ *loc = (UCHAR_T) op;
10260+ STORE_NUMBER (loc + 1, arg);
10261+}
10262+
10263+
10264+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
10265+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
10266+
10267+static void
10268+PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, int arg2)
10269+{
10270+ *loc = (UCHAR_T) op;
10271+ STORE_NUMBER (loc + 1, arg1);
10272+ STORE_NUMBER (loc + 1 + OFFSET_ADDRESS_SIZE, arg2);
10273+}
10274+
10275+
10276+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
10277+ for OP followed by two-byte integer parameter ARG. */
10278+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
10279+
10280+static void
10281+PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, int arg, UCHAR_T *end)
10282+{
10283+ register UCHAR_T *pfrom = end;
10284+ register UCHAR_T *pto = end + 1 + OFFSET_ADDRESS_SIZE;
10285+
10286+ while (pfrom != loc)
10287+ *--pto = *--pfrom;
10288+
10289+ PREFIX(store_op1) (op, loc, arg);
10290+}
10291+
10292+
10293+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
10294+/* ifdef WCHAR, integer parameter is 1 wchar_t. */
10295+
10296+static void
10297+PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, int arg1,
10298+ int arg2, UCHAR_T *end)
10299+{
10300+ register UCHAR_T *pfrom = end;
10301+ register UCHAR_T *pto = end + 1 + 2 * OFFSET_ADDRESS_SIZE;
10302+
10303+ while (pfrom != loc)
10304+ *--pto = *--pfrom;
10305+
10306+ PREFIX(store_op2) (op, loc, arg1, arg2);
10307+}
10308+
10309+
10310+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
10311+ after an alternative or a begin-subexpression. We assume there is at
10312+ least one character before the ^. */
10313+
10314+static boolean
10315+PREFIX(at_begline_loc_p) (const CHAR_T *pattern, const CHAR_T *p,
10316+ reg_syntax_t syntax)
10317+{
10318+ const CHAR_T *prev = p - 2;
10319+ boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
10320+
10321+ return
10322+ /* After a subexpression? */
10323+ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
10324+ /* After an alternative? */
10325+ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
10326+}
10327+
10328+
10329+/* The dual of at_begline_loc_p. This one is for $. We assume there is
10330+ at least one character after the $, i.e., `P < PEND'. */
10331+
10332+static boolean
10333+PREFIX(at_endline_loc_p) (const CHAR_T *p, const CHAR_T *pend,
10334+ reg_syntax_t syntax)
10335+{
10336+ const CHAR_T *next = p;
10337+ boolean next_backslash = *next == '\\';
10338+ const CHAR_T *next_next = p + 1 < pend ? p + 1 : 0;
10339+
10340+ return
10341+ /* Before a subexpression? */
10342+ (syntax & RE_NO_BK_PARENS ? *next == ')'
10343+ : next_backslash && next_next && *next_next == ')')
10344+ /* Before an alternative? */
10345+ || (syntax & RE_NO_BK_VBAR ? *next == '|'
10346+ : next_backslash && next_next && *next_next == '|');
10347+}
10348+
10349+#else /* not INSIDE_RECURSION */
10350+
10351+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
10352+ false if it's not. */
10353+
10354+static boolean
10355+group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum)
10356+{
10357+ int this_element;
10358+
10359+ for (this_element = compile_stack.avail - 1;
10360+ this_element >= 0;
10361+ this_element--)
10362+ if (compile_stack.stack[this_element].regnum == regnum)
10363+ return true;
10364+
10365+ return false;
10366+}
10367+#endif /* not INSIDE_RECURSION */
10368+
10369+#ifdef INSIDE_RECURSION
10370+
10371+#ifdef WCHAR
10372+/* This insert space, which size is "num", into the pattern at "loc".
10373+ "end" must point the end of the allocated buffer. */
10374+static void
10375+insert_space (int num, CHAR_T *loc, CHAR_T *end)
10376+{
10377+ register CHAR_T *pto = end;
10378+ register CHAR_T *pfrom = end - num;
10379+
10380+ while (pfrom >= loc)
10381+ *pto-- = *pfrom--;
10382+}
10383+#endif /* WCHAR */
10384+
10385+#ifdef WCHAR
10386+static reg_errcode_t
10387+wcs_compile_range (CHAR_T range_start_char, const CHAR_T **p_ptr,
10388+ const CHAR_T *pend, RE_TRANSLATE_TYPE translate,
10389+ reg_syntax_t syntax, CHAR_T *b, CHAR_T *char_set)
10390+{
10391+ const CHAR_T *p = *p_ptr;
10392+ CHAR_T range_start, range_end;
10393+ reg_errcode_t ret;
10394+# ifdef _LIBC
10395+ uint32_t nrules;
10396+ uint32_t start_val, end_val;
10397+# endif
10398+ if (p == pend)
10399+ return REG_ERANGE;
10400+
10401+# ifdef _LIBC
10402+ nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
10403+ if (nrules != 0)
10404+ {
10405+ const char *collseq = (const char *) _NL_CURRENT(LC_COLLATE,
10406+ _NL_COLLATE_COLLSEQWC);
10407+ const unsigned char *extra = (const unsigned char *)
10408+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
10409+
10410+ if (range_start_char < -1)
10411+ {
10412+ /* range_start is a collating symbol. */
10413+ int32_t *wextra;
10414+ /* Retreive the index and get collation sequence value. */
10415+ wextra = (int32_t*)(extra + char_set[-range_start_char]);
10416+ start_val = wextra[1 + *wextra];
10417+ }
10418+ else
10419+ start_val = collseq_table_lookup(collseq, TRANSLATE(range_start_char));
10420+
10421+ end_val = collseq_table_lookup (collseq, TRANSLATE (p[0]));
10422+
10423+ /* Report an error if the range is empty and the syntax prohibits
10424+ this. */
10425+ ret = ((syntax & RE_NO_EMPTY_RANGES)
10426+ && (start_val > end_val))? REG_ERANGE : REG_NOERROR;
10427+
10428+ /* Insert space to the end of the char_ranges. */
10429+ insert_space(2, b - char_set[5] - 2, b - 1);
10430+ *(b - char_set[5] - 2) = (wchar_t)start_val;
10431+ *(b - char_set[5] - 1) = (wchar_t)end_val;
10432+ char_set[4]++; /* ranges_index */
10433+ }
10434+ else
10435+# endif
10436+ {
10437+ range_start = (range_start_char >= 0)? TRANSLATE (range_start_char):
10438+ range_start_char;
10439+ range_end = TRANSLATE (p[0]);
10440+ /* Report an error if the range is empty and the syntax prohibits
10441+ this. */
10442+ ret = ((syntax & RE_NO_EMPTY_RANGES)
10443+ && (range_start > range_end))? REG_ERANGE : REG_NOERROR;
10444+
10445+ /* Insert space to the end of the char_ranges. */
10446+ insert_space(2, b - char_set[5] - 2, b - 1);
10447+ *(b - char_set[5] - 2) = range_start;
10448+ *(b - char_set[5] - 1) = range_end;
10449+ char_set[4]++; /* ranges_index */
10450+ }
10451+ /* Have to increment the pointer into the pattern string, so the
10452+ caller isn't still at the ending character. */
10453+ (*p_ptr)++;
10454+
10455+ return ret;
10456+}
10457+#else /* BYTE */
10458+/* Read the ending character of a range (in a bracket expression) from the
10459+ uncompiled pattern *P_PTR (which ends at PEND). We assume the
10460+ starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
10461+ Then we set the translation of all bits between the starting and
10462+ ending characters (inclusive) in the compiled pattern B.
10463+
10464+ Return an error code.
10465+
10466+ We use these short variable names so we can use the same macros as
10467+ `regex_compile' itself. */
10468+
10469+static reg_errcode_t
10470+byte_compile_range (unsigned int range_start_char, const char **p_ptr,
10471+ const char *pend, RE_TRANSLATE_TYPE translate,
10472+ reg_syntax_t syntax, unsigned char *b)
10473+{
10474+ unsigned this_char;
10475+ const char *p = *p_ptr;
10476+ reg_errcode_t ret;
10477+# if _LIBC
10478+ const unsigned char *collseq;
10479+ unsigned int start_colseq;
10480+ unsigned int end_colseq;
10481+# else
10482+ unsigned end_char;
10483+# endif
10484+
10485+ if (p == pend)
10486+ return REG_ERANGE;
10487+
10488+ /* Have to increment the pointer into the pattern string, so the
10489+ caller isn't still at the ending character. */
10490+ (*p_ptr)++;
10491+
10492+ /* Report an error if the range is empty and the syntax prohibits this. */
10493+ ret = syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
10494+
10495+# if _LIBC
10496+ collseq = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
10497+ _NL_COLLATE_COLLSEQMB);
10498+
10499+ start_colseq = collseq[(unsigned char) TRANSLATE (range_start_char)];
10500+ end_colseq = collseq[(unsigned char) TRANSLATE (p[0])];
10501+ for (this_char = 0; this_char <= (unsigned char) -1; ++this_char)
10502+ {
10503+ unsigned int this_colseq = collseq[(unsigned char) TRANSLATE (this_char)];
10504+
10505+ if (start_colseq <= this_colseq && this_colseq <= end_colseq)
10506+ {
10507+ SET_LIST_BIT (TRANSLATE (this_char));
10508+ ret = REG_NOERROR;
10509+ }
10510+ }
10511+# else
10512+ /* Here we see why `this_char' has to be larger than an `unsigned
10513+ char' -- we would otherwise go into an infinite loop, since all
10514+ characters <= 0xff. */
10515+ range_start_char = TRANSLATE (range_start_char);
10516+ /* TRANSLATE(p[0]) is casted to char (not unsigned char) in TRANSLATE,
10517+ and some compilers cast it to int implicitly, so following for_loop
10518+ may fall to (almost) infinite loop.
10519+ e.g. If translate[p[0]] = 0xff, end_char may equals to 0xffffffff.
10520+ To avoid this, we cast p[0] to unsigned int and truncate it. */
10521+ end_char = ((unsigned)TRANSLATE(p[0]) & ((1 << BYTEWIDTH) - 1));
10522+
10523+ for (this_char = range_start_char; this_char <= end_char; ++this_char)
10524+ {
10525+ SET_LIST_BIT (TRANSLATE (this_char));
10526+ ret = REG_NOERROR;
10527+ }
10528+# endif
10529+
10530+ return ret;
10531+}
10532+#endif /* WCHAR */
10533+
10534+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
10535+ BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
10536+ characters can start a string that matches the pattern. This fastmap
10537+ is used by re_search to skip quickly over impossible starting points.
10538+
10539+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
10540+ area as BUFP->fastmap.
10541+
10542+ We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
10543+ the pattern buffer.
10544+
10545+ Returns 0 if we succeed, -2 if an internal error. */
10546+
10547+#ifdef WCHAR
10548+/* local function for re_compile_fastmap.
10549+ truncate wchar_t character to char. */
10550+static unsigned char truncate_wchar (CHAR_T c);
10551+
10552+static unsigned char
10553+truncate_wchar (CHAR_T c)
10554+{
10555+ unsigned char buf[MB_CUR_MAX];
10556+ mbstate_t state;
10557+ int retval;
10558+ memset (&state, '\0', sizeof (state));
10559+# ifdef _LIBC
10560+ retval = __wcrtomb (buf, c, &state);
10561+# else
10562+ retval = wcrtomb (buf, c, &state);
10563+# endif
10564+ return retval > 0 ? buf[0] : (unsigned char) c;
10565+}
10566+#endif /* WCHAR */
10567+
10568+static int
10569+PREFIX(re_compile_fastmap) (struct re_pattern_buffer *bufp)
10570+{
10571+ int j, k;
10572+#ifdef MATCH_MAY_ALLOCATE
10573+ PREFIX(fail_stack_type) fail_stack;
10574+#endif
10575+#ifndef REGEX_MALLOC
10576+ char *destination;
10577+#endif
10578+
10579+ register char *fastmap = bufp->fastmap;
10580+
10581+#ifdef WCHAR
10582+ /* We need to cast pattern to (wchar_t*), because we casted this compiled
10583+ pattern to (char*) in regex_compile. */
10584+ UCHAR_T *pattern = (UCHAR_T*)bufp->buffer;
10585+ register UCHAR_T *pend = (UCHAR_T*) (bufp->buffer + bufp->used);
10586+#else /* BYTE */
10587+ UCHAR_T *pattern = bufp->buffer;
10588+ register UCHAR_T *pend = pattern + bufp->used;
10589+#endif /* WCHAR */
10590+ UCHAR_T *p = pattern;
10591+
10592+#ifdef REL_ALLOC
10593+ /* This holds the pointer to the failure stack, when
10594+ it is allocated relocatably. */
10595+ fail_stack_elt_t *failure_stack_ptr;
10596+#endif
10597+
10598+ /* Assume that each path through the pattern can be null until
10599+ proven otherwise. We set this false at the bottom of switch
10600+ statement, to which we get only if a particular path doesn't
10601+ match the empty string. */
10602+ boolean path_can_be_null = true;
10603+
10604+ /* We aren't doing a `succeed_n' to begin with. */
10605+ boolean succeed_n_p = false;
10606+
10607+ assert (fastmap != NULL && p != NULL);
10608+
10609+ INIT_FAIL_STACK ();
10610+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
10611+ bufp->fastmap_accurate = 1; /* It will be when we're done. */
10612+ bufp->can_be_null = 0;
10613+
10614+ while (1)
10615+ {
10616+ if (p == pend || *p == (UCHAR_T) succeed)
10617+ {
10618+ /* We have reached the (effective) end of pattern. */
10619+ if (!FAIL_STACK_EMPTY ())
10620+ {
10621+ bufp->can_be_null |= path_can_be_null;
10622+
10623+ /* Reset for next path. */
10624+ path_can_be_null = true;
10625+
10626+ p = fail_stack.stack[--fail_stack.avail].pointer;
10627+
10628+ continue;
10629+ }
10630+ else
10631+ break;
10632+ }
10633+
10634+ /* We should never be about to go beyond the end of the pattern. */
10635+ assert (p < pend);
10636+
10637+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
10638+ {
10639+
10640+ /* I guess the idea here is to simply not bother with a fastmap
10641+ if a backreference is used, since it's too hard to figure out
10642+ the fastmap for the corresponding group. Setting
10643+ `can_be_null' stops `re_search_2' from using the fastmap, so
10644+ that is all we do. */
10645+ case duplicate:
10646+ bufp->can_be_null = 1;
10647+ goto done;
10648+
10649+
10650+ /* Following are the cases which match a character. These end
10651+ with `break'. */
10652+
10653+#ifdef WCHAR
10654+ case exactn:
10655+ fastmap[truncate_wchar(p[1])] = 1;
10656+ break;
10657+#else /* BYTE */
10658+ case exactn:
10659+ fastmap[p[1]] = 1;
10660+ break;
10661+#endif /* WCHAR */
10662+#ifdef MBS_SUPPORT
10663+ case exactn_bin:
10664+ fastmap[p[1]] = 1;
10665+ break;
10666+#endif
10667+
10668+#ifdef WCHAR
10669+ /* It is hard to distinguish fastmap from (multi byte) characters
10670+ which depends on current locale. */
10671+ case charset:
10672+ case charset_not:
10673+ case wordchar:
10674+ case notwordchar:
10675+ bufp->can_be_null = 1;
10676+ goto done;
10677+#else /* BYTE */
10678+ case charset:
10679+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
10680+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
10681+ fastmap[j] = 1;
10682+ break;
10683+
10684+
10685+ case charset_not:
10686+ /* Chars beyond end of map must be allowed. */
10687+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
10688+ fastmap[j] = 1;
10689+
10690+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
10691+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
10692+ fastmap[j] = 1;
10693+ break;
10694+
10695+
10696+ case wordchar:
10697+ for (j = 0; j < (1 << BYTEWIDTH); j++)
10698+ if (SYNTAX (j) == Sword)
10699+ fastmap[j] = 1;
10700+ break;
10701+
10702+
10703+ case notwordchar:
10704+ for (j = 0; j < (1 << BYTEWIDTH); j++)
10705+ if (SYNTAX (j) != Sword)
10706+ fastmap[j] = 1;
10707+ break;
10708+#endif /* WCHAR */
10709+
10710+ case anychar:
10711+ {
10712+ int fastmap_newline = fastmap['\n'];
10713+
10714+ /* `.' matches anything ... */
10715+ for (j = 0; j < (1 << BYTEWIDTH); j++)
10716+ fastmap[j] = 1;
10717+
10718+ /* ... except perhaps newline. */
10719+ if (!(bufp->syntax & RE_DOT_NEWLINE))
10720+ fastmap['\n'] = fastmap_newline;
10721+
10722+ /* Return if we have already set `can_be_null'; if we have,
10723+ then the fastmap is irrelevant. Something's wrong here. */
10724+ else if (bufp->can_be_null)
10725+ goto done;
10726+
10727+ /* Otherwise, have to check alternative paths. */
10728+ break;
10729+ }
10730+
10731+#ifdef emacs
10732+ case syntaxspec:
10733+ k = *p++;
10734+ for (j = 0; j < (1 << BYTEWIDTH); j++)
10735+ if (SYNTAX (j) == (enum syntaxcode) k)
10736+ fastmap[j] = 1;
10737+ break;
10738+
10739+
10740+ case notsyntaxspec:
10741+ k = *p++;
10742+ for (j = 0; j < (1 << BYTEWIDTH); j++)
10743+ if (SYNTAX (j) != (enum syntaxcode) k)
10744+ fastmap[j] = 1;
10745+ break;
10746+
10747+
10748+ /* All cases after this match the empty string. These end with
10749+ `continue'. */
10750+
10751+
10752+ case before_dot:
10753+ case at_dot:
10754+ case after_dot:
10755+ continue;
10756+#endif /* emacs */
10757+
10758+
10759+ case no_op:
10760+ case begline:
10761+ case endline:
10762+ case begbuf:
10763+ case endbuf:
10764+ case wordbound:
10765+ case notwordbound:
10766+ case wordbeg:
10767+ case wordend:
10768+ case push_dummy_failure:
10769+ continue;
10770+
10771+
10772+ case jump_n:
10773+ case pop_failure_jump:
10774+ case maybe_pop_jump:
10775+ case jump:
10776+ case jump_past_alt:
10777+ case dummy_failure_jump:
10778+ EXTRACT_NUMBER_AND_INCR (j, p);
10779+ p += j;
10780+ if (j > 0)
10781+ continue;
10782+
10783+ /* Jump backward implies we just went through the body of a
10784+ loop and matched nothing. Opcode jumped to should be
10785+ `on_failure_jump' or `succeed_n'. Just treat it like an
10786+ ordinary jump. For a * loop, it has pushed its failure
10787+ point already; if so, discard that as redundant. */
10788+ if ((re_opcode_t) *p != on_failure_jump
10789+ && (re_opcode_t) *p != succeed_n)
10790+ continue;
10791+
10792+ p++;
10793+ EXTRACT_NUMBER_AND_INCR (j, p);
10794+ p += j;
10795+
10796+ /* If what's on the stack is where we are now, pop it. */
10797+ if (!FAIL_STACK_EMPTY ()
10798+ && fail_stack.stack[fail_stack.avail - 1].pointer == p)
10799+ fail_stack.avail--;
10800+
10801+ continue;
10802+
10803+
10804+ case on_failure_jump:
10805+ case on_failure_keep_string_jump:
10806+ handle_on_failure_jump:
10807+ EXTRACT_NUMBER_AND_INCR (j, p);
10808+
10809+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
10810+ end of the pattern. We don't want to push such a point,
10811+ since when we restore it above, entering the switch will
10812+ increment `p' past the end of the pattern. We don't need
10813+ to push such a point since we obviously won't find any more
10814+ fastmap entries beyond `pend'. Such a pattern can match
10815+ the null string, though. */
10816+ if (p + j < pend)
10817+ {
10818+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
10819+ {
10820+ RESET_FAIL_STACK ();
10821+ return -2;
10822+ }
10823+ }
10824+ else
10825+ bufp->can_be_null = 1;
10826+
10827+ if (succeed_n_p)
10828+ {
10829+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
10830+ succeed_n_p = false;
10831+ }
10832+
10833+ continue;
10834+
10835+
10836+ case succeed_n:
10837+ /* Get to the number of times to succeed. */
10838+ p += OFFSET_ADDRESS_SIZE;
10839+
10840+ /* Increment p past the n for when k != 0. */
10841+ EXTRACT_NUMBER_AND_INCR (k, p);
10842+ if (k == 0)
10843+ {
10844+ p -= 2 * OFFSET_ADDRESS_SIZE;
10845+ succeed_n_p = true; /* Spaghetti code alert. */
10846+ goto handle_on_failure_jump;
10847+ }
10848+ continue;
10849+
10850+
10851+ case set_number_at:
10852+ p += 2 * OFFSET_ADDRESS_SIZE;
10853+ continue;
10854+
10855+
10856+ case start_memory:
10857+ case stop_memory:
10858+ p += 2;
10859+ continue;
10860+
10861+
10862+ default:
10863+ abort (); /* We have listed all the cases. */
10864+ } /* switch *p++ */
10865+
10866+ /* Getting here means we have found the possible starting
10867+ characters for one path of the pattern -- and that the empty
10868+ string does not match. We need not follow this path further.
10869+ Instead, look at the next alternative (remembered on the
10870+ stack), or quit if no more. The test at the top of the loop
10871+ does these things. */
10872+ path_can_be_null = false;
10873+ p = pend;
10874+ } /* while p */
10875+
10876+ /* Set `can_be_null' for the last path (also the first path, if the
10877+ pattern is empty). */
10878+ bufp->can_be_null |= path_can_be_null;
10879+
10880+ done:
10881+ RESET_FAIL_STACK ();
10882+ return 0;
10883+}
10884+
10885+#else /* not INSIDE_RECURSION */
10886+
10887+int
10888+re_compile_fastmap (struct re_pattern_buffer *bufp)
10889+{
10890+# ifdef MBS_SUPPORT
10891+ if (MB_CUR_MAX != 1)
10892+ return wcs_re_compile_fastmap(bufp);
10893+ else
10894+# endif
10895+ return byte_re_compile_fastmap(bufp);
10896+} /* re_compile_fastmap */
10897+#ifdef _LIBC
10898+weak_alias (__re_compile_fastmap, re_compile_fastmap)
10899+#endif
10900+
10901+
10902+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
10903+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
10904+ this memory for recording register information. STARTS and ENDS
10905+ must be allocated using the malloc library routine, and must each
10906+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
10907+
10908+ If NUM_REGS == 0, then subsequent matches should allocate their own
10909+ register data.
10910+
10911+ Unless this function is called, the first search or match using
10912+ PATTERN_BUFFER will allocate its own register data, without
10913+ freeing the old data. */
10914+
10915+void
10916+re_set_registers (struct re_pattern_buffer *bufp,
10917+ struct re_registers *regs, unsigned num_regs,
10918+ regoff_t *starts, regoff_t *ends)
10919+{
10920+ if (num_regs)
10921+ {
10922+ bufp->regs_allocated = REGS_REALLOCATE;
10923+ regs->num_regs = num_regs;
10924+ regs->start = starts;
10925+ regs->end = ends;
10926+ }
10927+ else
10928+ {
10929+ bufp->regs_allocated = REGS_UNALLOCATED;
10930+ regs->num_regs = 0;
10931+ regs->start = regs->end = (regoff_t *) 0;
10932+ }
10933+}
10934+#ifdef _LIBC
10935+weak_alias (__re_set_registers, re_set_registers)
10936+#endif
10937+
10938+/* Searching routines. */
10939+
10940+/* Like re_search_2, below, but only one string is specified, and
10941+ doesn't let you say where to stop matching. */
10942+
10943+int
10944+re_search (struct re_pattern_buffer *bufp, const char *string, int size,
10945+ int startpos, int range, struct re_registers *regs)
10946+{
10947+ return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
10948+ regs, size);
10949+}
10950+#ifdef _LIBC
10951+weak_alias (__re_search, re_search)
10952+#endif
10953+
10954+
10955+/* Using the compiled pattern in BUFP->buffer, first tries to match the
10956+ virtual concatenation of STRING1 and STRING2, starting first at index
10957+ STARTPOS, then at STARTPOS + 1, and so on.
10958+
10959+ STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
10960+
10961+ RANGE is how far to scan while trying to match. RANGE = 0 means try
10962+ only at STARTPOS; in general, the last start tried is STARTPOS +
10963+ RANGE.
10964+
10965+ In REGS, return the indices of the virtual concatenation of STRING1
10966+ and STRING2 that matched the entire BUFP->buffer and its contained
10967+ subexpressions.
10968+
10969+ Do not consider matching one past the index STOP in the virtual
10970+ concatenation of STRING1 and STRING2.
10971+
10972+ We return either the position in the strings at which the match was
10973+ found, -1 if no match, or -2 if error (such as failure
10974+ stack overflow). */
10975+
10976+int
10977+re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
10978+ const char *string2, int size2, int startpos, int range,
10979+ struct re_registers *regs, int stop)
10980+{
10981+# ifdef MBS_SUPPORT
10982+ if (MB_CUR_MAX != 1)
10983+ return wcs_re_search_2 (bufp, string1, size1, string2, size2, startpos,
10984+ range, regs, stop);
10985+ else
10986+# endif
10987+ return byte_re_search_2 (bufp, string1, size1, string2, size2, startpos,
10988+ range, regs, stop);
10989+} /* re_search_2 */
10990+#ifdef _LIBC
10991+weak_alias (__re_search_2, re_search_2)
10992+#endif
10993+
10994+#endif /* not INSIDE_RECURSION */
10995+
10996+#ifdef INSIDE_RECURSION
10997+
10998+#ifdef MATCH_MAY_ALLOCATE
10999+# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL
11000+#else
11001+# define FREE_VAR(var) if (var) free (var); var = NULL
11002+#endif
11003+
11004+#ifdef WCHAR
11005+# define MAX_ALLOCA_SIZE 2000
11006+
11007+# define FREE_WCS_BUFFERS() \
11008+ do { \
11009+ if (size1 > MAX_ALLOCA_SIZE) \
11010+ { \
11011+ free (wcs_string1); \
11012+ free (mbs_offset1); \
11013+ } \
11014+ else \
11015+ { \
11016+ FREE_VAR (wcs_string1); \
11017+ FREE_VAR (mbs_offset1); \
11018+ } \
11019+ if (size2 > MAX_ALLOCA_SIZE) \
11020+ { \
11021+ free (wcs_string2); \
11022+ free (mbs_offset2); \
11023+ } \
11024+ else \
11025+ { \
11026+ FREE_VAR (wcs_string2); \
11027+ FREE_VAR (mbs_offset2); \
11028+ } \
11029+ } while (0)
11030+
11031+#endif
11032+
11033+
11034+static int
11035+PREFIX(re_search_2) (struct re_pattern_buffer *bufp, const char *string1,
11036+ int size1, const char *string2, int size2,
11037+ int startpos, int range,
11038+ struct re_registers *regs, int stop)
11039+{
11040+ int val;
11041+ register char *fastmap = bufp->fastmap;
11042+ register RE_TRANSLATE_TYPE translate = bufp->translate;
11043+ int total_size = size1 + size2;
11044+ int endpos = startpos + range;
11045+#ifdef WCHAR
11046+ /* We need wchar_t* buffers correspond to cstring1, cstring2. */
11047+ wchar_t *wcs_string1 = NULL, *wcs_string2 = NULL;
11048+ /* We need the size of wchar_t buffers correspond to csize1, csize2. */
11049+ int wcs_size1 = 0, wcs_size2 = 0;
11050+ /* offset buffer for optimizatoin. See convert_mbs_to_wc. */
11051+ int *mbs_offset1 = NULL, *mbs_offset2 = NULL;
11052+ /* They hold whether each wchar_t is binary data or not. */
11053+ char *is_binary = NULL;
11054+#endif /* WCHAR */
11055+
11056+ /* Check for out-of-range STARTPOS. */
11057+ if (startpos < 0 || startpos > total_size)
11058+ return -1;
11059+
11060+ /* Fix up RANGE if it might eventually take us outside
11061+ the virtual concatenation of STRING1 and STRING2.
11062+ Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */
11063+ if (endpos < 0)
11064+ range = 0 - startpos;
11065+ else if (endpos > total_size)
11066+ range = total_size - startpos;
11067+
11068+ /* If the search isn't to be a backwards one, don't waste time in a
11069+ search for a pattern that must be anchored. */
11070+ if (bufp->used > 0 && range > 0
11071+ && ((re_opcode_t) bufp->buffer[0] == begbuf
11072+ /* `begline' is like `begbuf' if it cannot match at newlines. */
11073+ || ((re_opcode_t) bufp->buffer[0] == begline
11074+ && !bufp->newline_anchor)))
11075+ {
11076+ if (startpos > 0)
11077+ return -1;
11078+ else
11079+ range = 1;
11080+ }
11081+
11082+#ifdef emacs
11083+ /* In a forward search for something that starts with \=.
11084+ don't keep searching past point. */
11085+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
11086+ {
11087+ range = PT - startpos;
11088+ if (range <= 0)
11089+ return -1;
11090+ }
11091+#endif /* emacs */
11092+
11093+ /* Update the fastmap now if not correct already. */
11094+ if (fastmap && !bufp->fastmap_accurate)
11095+ if (re_compile_fastmap (bufp) == -2)
11096+ return -2;
11097+
11098+#ifdef WCHAR
11099+ /* Allocate wchar_t array for wcs_string1 and wcs_string2 and
11100+ fill them with converted string. */
11101+ if (size1 != 0)
11102+ {
11103+ if (size1 > MAX_ALLOCA_SIZE)
11104+ {
11105+ wcs_string1 = TALLOC (size1 + 1, CHAR_T);
11106+ mbs_offset1 = TALLOC (size1 + 1, int);
11107+ is_binary = TALLOC (size1 + 1, char);
11108+ }
11109+ else
11110+ {
11111+ wcs_string1 = REGEX_TALLOC (size1 + 1, CHAR_T);
11112+ mbs_offset1 = REGEX_TALLOC (size1 + 1, int);
11113+ is_binary = REGEX_TALLOC (size1 + 1, char);
11114+ }
11115+ if (!wcs_string1 || !mbs_offset1 || !is_binary)
11116+ {
11117+ if (size1 > MAX_ALLOCA_SIZE)
11118+ {
11119+ free (wcs_string1);
11120+ free (mbs_offset1);
11121+ free (is_binary);
11122+ }
11123+ else
11124+ {
11125+ FREE_VAR (wcs_string1);
11126+ FREE_VAR (mbs_offset1);
11127+ FREE_VAR (is_binary);
11128+ }
11129+ return -2;
11130+ }
11131+ wcs_size1 = convert_mbs_to_wcs(wcs_string1, string1, size1,
11132+ mbs_offset1, is_binary);
11133+ wcs_string1[wcs_size1] = L'\0'; /* for a sentinel */
11134+ if (size1 > MAX_ALLOCA_SIZE)
11135+ free (is_binary);
11136+ else
11137+ FREE_VAR (is_binary);
11138+ }
11139+ if (size2 != 0)
11140+ {
11141+ if (size2 > MAX_ALLOCA_SIZE)
11142+ {
11143+ wcs_string2 = TALLOC (size2 + 1, CHAR_T);
11144+ mbs_offset2 = TALLOC (size2 + 1, int);
11145+ is_binary = TALLOC (size2 + 1, char);
11146+ }
11147+ else
11148+ {
11149+ wcs_string2 = REGEX_TALLOC (size2 + 1, CHAR_T);
11150+ mbs_offset2 = REGEX_TALLOC (size2 + 1, int);
11151+ is_binary = REGEX_TALLOC (size2 + 1, char);
11152+ }
11153+ if (!wcs_string2 || !mbs_offset2 || !is_binary)
11154+ {
11155+ FREE_WCS_BUFFERS ();
11156+ if (size2 > MAX_ALLOCA_SIZE)
11157+ free (is_binary);
11158+ else
11159+ FREE_VAR (is_binary);
11160+ return -2;
11161+ }
11162+ wcs_size2 = convert_mbs_to_wcs(wcs_string2, string2, size2,
11163+ mbs_offset2, is_binary);
11164+ wcs_string2[wcs_size2] = L'\0'; /* for a sentinel */
11165+ if (size2 > MAX_ALLOCA_SIZE)
11166+ free (is_binary);
11167+ else
11168+ FREE_VAR (is_binary);
11169+ }
11170+#endif /* WCHAR */
11171+
11172+
11173+ /* Loop through the string, looking for a place to start matching. */
11174+ for (;;)
11175+ {
11176+ /* If a fastmap is supplied, skip quickly over characters that
11177+ cannot be the start of a match. If the pattern can match the
11178+ null string, however, we don't need to skip characters; we want
11179+ the first null string. */
11180+ if (fastmap && startpos < total_size && !bufp->can_be_null)
11181+ {
11182+ if (range > 0) /* Searching forwards. */
11183+ {
11184+ register const char *d;
11185+ register int lim = 0;
11186+ int irange = range;
11187+
11188+ if (startpos < size1 && startpos + range >= size1)
11189+ lim = range - (size1 - startpos);
11190+
11191+ d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
11192+
11193+ /* Written out as an if-else to avoid testing `translate'
11194+ inside the loop. */
11195+ if (translate)
11196+ while (range > lim
11197+ && !fastmap[(unsigned char)
11198+ translate[(unsigned char) *d++]])
11199+ range--;
11200+ else
11201+ while (range > lim && !fastmap[(unsigned char) *d++])
11202+ range--;
11203+
11204+ startpos += irange - range;
11205+ }
11206+ else /* Searching backwards. */
11207+ {
11208+ register CHAR_T c = (size1 == 0 || startpos >= size1
11209+ ? string2[startpos - size1]
11210+ : string1[startpos]);
11211+
11212+ if (!fastmap[(unsigned char) TRANSLATE (c)])
11213+ goto advance;
11214+ }
11215+ }
11216+
11217+ /* If can't match the null string, and that's all we have left, fail. */
11218+ if (range >= 0 && startpos == total_size && fastmap
11219+ && !bufp->can_be_null)
11220+ {
11221+#ifdef WCHAR
11222+ FREE_WCS_BUFFERS ();
11223+#endif
11224+ return -1;
11225+ }
11226+
11227+#ifdef WCHAR
11228+ val = wcs_re_match_2_internal (bufp, string1, size1, string2,
11229+ size2, startpos, regs, stop,
11230+ wcs_string1, wcs_size1,
11231+ wcs_string2, wcs_size2,
11232+ mbs_offset1, mbs_offset2);
11233+#else /* BYTE */
11234+ val = byte_re_match_2_internal (bufp, string1, size1, string2,
11235+ size2, startpos, regs, stop);
11236+#endif /* BYTE */
11237+
11238+#ifndef REGEX_MALLOC
11239+# ifdef C_ALLOCA
11240+ alloca (0);
11241+# endif
11242+#endif
11243+
11244+ if (val >= 0)
11245+ {
11246+#ifdef WCHAR
11247+ FREE_WCS_BUFFERS ();
11248+#endif
11249+ return startpos;
11250+ }
11251+
11252+ if (val == -2)
11253+ {
11254+#ifdef WCHAR
11255+ FREE_WCS_BUFFERS ();
11256+#endif
11257+ return -2;
11258+ }
11259+
11260+ advance:
11261+ if (!range)
11262+ break;
11263+ else if (range > 0)
11264+ {
11265+ range--;
11266+ startpos++;
11267+ }
11268+ else
11269+ {
11270+ range++;
11271+ startpos--;
11272+ }
11273+ }
11274+#ifdef WCHAR
11275+ FREE_WCS_BUFFERS ();
11276+#endif
11277+ return -1;
11278+}
11279+
11280+#ifdef WCHAR
11281+/* This converts PTR, a pointer into one of the search wchar_t strings
11282+ `string1' and `string2' into an multibyte string offset from the
11283+ beginning of that string. We use mbs_offset to optimize.
11284+ See convert_mbs_to_wcs. */
11285+# define POINTER_TO_OFFSET(ptr) \
11286+ (FIRST_STRING_P (ptr) \
11287+ ? ((regoff_t)(mbs_offset1 != NULL? mbs_offset1[(ptr)-string1] : 0)) \
11288+ : ((regoff_t)((mbs_offset2 != NULL? mbs_offset2[(ptr)-string2] : 0) \
11289+ + csize1)))
11290+#else /* BYTE */
11291+/* This converts PTR, a pointer into one of the search strings `string1'
11292+ and `string2' into an offset from the beginning of that string. */
11293+# define POINTER_TO_OFFSET(ptr) \
11294+ (FIRST_STRING_P (ptr) \
11295+ ? ((regoff_t) ((ptr) - string1)) \
11296+ : ((regoff_t) ((ptr) - string2 + size1)))
11297+#endif /* WCHAR */
11298+
11299+/* Macros for dealing with the split strings in re_match_2. */
11300+
11301+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
11302+
11303+/* Call before fetching a character with *d. This switches over to
11304+ string2 if necessary. */
11305+#define PREFETCH() \
11306+ while (d == dend) \
11307+ { \
11308+ /* End of string2 => fail. */ \
11309+ if (dend == end_match_2) \
11310+ goto fail; \
11311+ /* End of string1 => advance to string2. */ \
11312+ d = string2; \
11313+ dend = end_match_2; \
11314+ }
11315+
11316+/* Test if at very beginning or at very end of the virtual concatenation
11317+ of `string1' and `string2'. If only one string, it's `string2'. */
11318+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
11319+#define AT_STRINGS_END(d) ((d) == end2)
11320+
11321+
11322+/* Test if D points to a character which is word-constituent. We have
11323+ two special cases to check for: if past the end of string1, look at
11324+ the first character in string2; and if before the beginning of
11325+ string2, look at the last character in string1. */
11326+#ifdef WCHAR
11327+/* Use internationalized API instead of SYNTAX. */
11328+# define WORDCHAR_P(d) \
11329+ (iswalnum ((wint_t)((d) == end1 ? *string2 \
11330+ : (d) == string2 - 1 ? *(end1 - 1) : *(d))) != 0 \
11331+ || ((d) == end1 ? *string2 \
11332+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) == L'_')
11333+#else /* BYTE */
11334+# define WORDCHAR_P(d) \
11335+ (SYNTAX ((d) == end1 ? *string2 \
11336+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
11337+ == Sword)
11338+#endif /* WCHAR */
11339+
11340+/* Disabled due to a compiler bug -- see comment at case wordbound */
11341+#if 0
11342+/* Test if the character before D and the one at D differ with respect
11343+ to being word-constituent. */
11344+#define AT_WORD_BOUNDARY(d) \
11345+ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
11346+ || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
11347+#endif
11348+
11349+/* Free everything we malloc. */
11350+#ifdef MATCH_MAY_ALLOCATE
11351+# ifdef WCHAR
11352+# define FREE_VARIABLES() \
11353+ do { \
11354+ REGEX_FREE_STACK (fail_stack.stack); \
11355+ FREE_VAR (regstart); \
11356+ FREE_VAR (regend); \
11357+ FREE_VAR (old_regstart); \
11358+ FREE_VAR (old_regend); \
11359+ FREE_VAR (best_regstart); \
11360+ FREE_VAR (best_regend); \
11361+ FREE_VAR (reg_info); \
11362+ FREE_VAR (reg_dummy); \
11363+ FREE_VAR (reg_info_dummy); \
11364+ if (!cant_free_wcs_buf) \
11365+ { \
11366+ FREE_VAR (string1); \
11367+ FREE_VAR (string2); \
11368+ FREE_VAR (mbs_offset1); \
11369+ FREE_VAR (mbs_offset2); \
11370+ } \
11371+ } while (0)
11372+# else /* BYTE */
11373+# define FREE_VARIABLES() \
11374+ do { \
11375+ REGEX_FREE_STACK (fail_stack.stack); \
11376+ FREE_VAR (regstart); \
11377+ FREE_VAR (regend); \
11378+ FREE_VAR (old_regstart); \
11379+ FREE_VAR (old_regend); \
11380+ FREE_VAR (best_regstart); \
11381+ FREE_VAR (best_regend); \
11382+ FREE_VAR (reg_info); \
11383+ FREE_VAR (reg_dummy); \
11384+ FREE_VAR (reg_info_dummy); \
11385+ } while (0)
11386+# endif /* WCHAR */
11387+#else
11388+# ifdef WCHAR
11389+# define FREE_VARIABLES() \
11390+ do { \
11391+ if (!cant_free_wcs_buf) \
11392+ { \
11393+ FREE_VAR (string1); \
11394+ FREE_VAR (string2); \
11395+ FREE_VAR (mbs_offset1); \
11396+ FREE_VAR (mbs_offset2); \
11397+ } \
11398+ } while (0)
11399+# else /* BYTE */
11400+# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */
11401+# endif /* WCHAR */
11402+#endif /* not MATCH_MAY_ALLOCATE */
11403+
11404+/* These values must meet several constraints. They must not be valid
11405+ register values; since we have a limit of 255 registers (because
11406+ we use only one byte in the pattern for the register number), we can
11407+ use numbers larger than 255. They must differ by 1, because of
11408+ NUM_FAILURE_ITEMS above. And the value for the lowest register must
11409+ be larger than the value for the highest register, so we do not try
11410+ to actually save any registers when none are active. */
11411+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
11412+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
11413+
11414+#else /* not INSIDE_RECURSION */
11415+/* Matching routines. */
11416+
11417+#ifndef emacs /* Emacs never uses this. */
11418+/* re_match is like re_match_2 except it takes only a single string. */
11419+
11420+int
11421+re_match (struct re_pattern_buffer *bufp, const char *string,
11422+ int size, int pos, struct re_registers *regs)
11423+{
11424+ int result;
11425+# ifdef MBS_SUPPORT
11426+ if (MB_CUR_MAX != 1)
11427+ result = wcs_re_match_2_internal (bufp, NULL, 0, string, size,
11428+ pos, regs, size,
11429+ NULL, 0, NULL, 0, NULL, NULL);
11430+ else
11431+# endif
11432+ result = byte_re_match_2_internal (bufp, NULL, 0, string, size,
11433+ pos, regs, size);
11434+# ifndef REGEX_MALLOC
11435+# ifdef C_ALLOCA
11436+ alloca (0);
11437+# endif
11438+# endif
11439+ return result;
11440+}
11441+# ifdef _LIBC
11442+weak_alias (__re_match, re_match)
11443+# endif
11444+#endif /* not emacs */
11445+
11446+#endif /* not INSIDE_RECURSION */
11447+
11448+#ifdef INSIDE_RECURSION
11449+static boolean PREFIX(group_match_null_string_p) (UCHAR_T **p,
11450+ UCHAR_T *end,
11451+ PREFIX(register_info_type) *reg_info);
11452+static boolean PREFIX(alt_match_null_string_p) (UCHAR_T *p,
11453+ UCHAR_T *end,
11454+ PREFIX(register_info_type) *reg_info);
11455+static boolean PREFIX(common_op_match_null_string_p) (UCHAR_T **p,
11456+ UCHAR_T *end,
11457+ PREFIX(register_info_type) *reg_info);
11458+static int PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2,
11459+ register int len,
11460+ RE_TRANSLATE_TYPE translate);
11461+#else /* not INSIDE_RECURSION */
11462+
11463+/* re_match_2 matches the compiled pattern in BUFP against the
11464+ the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
11465+ and SIZE2, respectively). We start matching at POS, and stop
11466+ matching at STOP.
11467+
11468+ If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
11469+ store offsets for the substring each group matched in REGS. See the
11470+ documentation for exactly how many groups we fill.
11471+
11472+ We return -1 if no match, -2 if an internal error (such as the
11473+ failure stack overflowing). Otherwise, we return the length of the
11474+ matched substring. */
11475+
11476+int
11477+re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
11478+ const char *string2, int size2, int pos,
11479+ struct re_registers *regs, int stop)
11480+{
11481+ int result;
11482+# ifdef MBS_SUPPORT
11483+ if (MB_CUR_MAX != 1)
11484+ result = wcs_re_match_2_internal (bufp, string1, size1, string2, size2,
11485+ pos, regs, stop,
11486+ NULL, 0, NULL, 0, NULL, NULL);
11487+ else
11488+# endif
11489+ result = byte_re_match_2_internal (bufp, string1, size1, string2, size2,
11490+ pos, regs, stop);
11491+
11492+#ifndef REGEX_MALLOC
11493+# ifdef C_ALLOCA
11494+ alloca (0);
11495+# endif
11496+#endif
11497+ return result;
11498+}
11499+#ifdef _LIBC
11500+weak_alias (__re_match_2, re_match_2)
11501+#endif
11502+
11503+#endif /* not INSIDE_RECURSION */
11504+
11505+#ifdef INSIDE_RECURSION
11506+
11507+#ifdef WCHAR
11508+static int count_mbs_length (int *, int);
11509+
11510+/* This check the substring (from 0, to length) of the multibyte string,
11511+ to which offset_buffer correspond. And count how many wchar_t_characters
11512+ the substring occupy. We use offset_buffer to optimization.
11513+ See convert_mbs_to_wcs. */
11514+
11515+static int
11516+count_mbs_length(int *offset_buffer, int length)
11517+{
11518+ int upper, lower;
11519+
11520+ /* Check whether the size is valid. */
11521+ if (length < 0)
11522+ return -1;
11523+
11524+ if (offset_buffer == NULL)
11525+ return 0;
11526+
11527+ /* If there are no multibyte character, offset_buffer[i] == i.
11528+ Optmize for this case. */
11529+ if (offset_buffer[length] == length)
11530+ return length;
11531+
11532+ /* Set up upper with length. (because for all i, offset_buffer[i] >= i) */
11533+ upper = length;
11534+ lower = 0;
11535+
11536+ while (true)
11537+ {
11538+ int middle = (lower + upper) / 2;
11539+ if (middle == lower || middle == upper)
11540+ break;
11541+ if (offset_buffer[middle] > length)
11542+ upper = middle;
11543+ else if (offset_buffer[middle] < length)
11544+ lower = middle;
11545+ else
11546+ return middle;
11547+ }
11548+
11549+ return -1;
11550+}
11551+#endif /* WCHAR */
11552+
11553+/* This is a separate function so that we can force an alloca cleanup
11554+ afterwards. */
11555+#ifdef WCHAR
11556+static int
11557+wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
11558+ const char *cstring1, int csize1,
11559+ const char *cstring2, int csize2,
11560+ int pos,
11561+ struct re_registers *regs,
11562+ int stop,
11563+ /* string1 == string2 == NULL means string1/2, size1/2 and
11564+ mbs_offset1/2 need seting up in this function. */
11565+ /* We need wchar_t* buffers correspond to cstring1, cstring2. */
11566+ wchar_t *string1, int size1,
11567+ wchar_t *string2, int size2,
11568+ /* offset buffer for optimizatoin. See convert_mbs_to_wc. */
11569+ int *mbs_offset1, int *mbs_offset2)
11570+#else /* BYTE */
11571+static int
11572+byte_re_match_2_internal (struct re_pattern_buffer *bufp,
11573+ const char *string1, int size1,
11574+ const char *string2, int size2,
11575+ int pos,
11576+ struct re_registers *regs, int stop)
11577+#endif /* BYTE */
11578+{
11579+ /* General temporaries. */
11580+ int mcnt;
11581+ UCHAR_T *p1;
11582+#ifdef WCHAR
11583+ /* They hold whether each wchar_t is binary data or not. */
11584+ char *is_binary = NULL;
11585+ /* If true, we can't free string1/2, mbs_offset1/2. */
11586+ int cant_free_wcs_buf = 1;
11587+#endif /* WCHAR */
11588+
11589+ /* Just past the end of the corresponding string. */
11590+ const CHAR_T *end1, *end2;
11591+
11592+ /* Pointers into string1 and string2, just past the last characters in
11593+ each to consider matching. */
11594+ const CHAR_T *end_match_1, *end_match_2;
11595+
11596+ /* Where we are in the data, and the end of the current string. */
11597+ const CHAR_T *d, *dend;
11598+
11599+ /* Where we are in the pattern, and the end of the pattern. */
11600+#ifdef WCHAR
11601+ UCHAR_T *pattern, *p;
11602+ register UCHAR_T *pend;
11603+#else /* BYTE */
11604+ UCHAR_T *p = bufp->buffer;
11605+ register UCHAR_T *pend = p + bufp->used;
11606+#endif /* WCHAR */
11607+
11608+ /* Mark the opcode just after a start_memory, so we can test for an
11609+ empty subpattern when we get to the stop_memory. */
11610+ UCHAR_T *just_past_start_mem = 0;
11611+
11612+ /* We use this to map every character in the string. */
11613+ RE_TRANSLATE_TYPE translate = bufp->translate;
11614+
11615+ /* Failure point stack. Each place that can handle a failure further
11616+ down the line pushes a failure point on this stack. It consists of
11617+ restart, regend, and reg_info for all registers corresponding to
11618+ the subexpressions we're currently inside, plus the number of such
11619+ registers, and, finally, two char *'s. The first char * is where
11620+ to resume scanning the pattern; the second one is where to resume
11621+ scanning the strings. If the latter is zero, the failure point is
11622+ a ``dummy''; if a failure happens and the failure point is a dummy,
11623+ it gets discarded and the next next one is tried. */
11624+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
11625+ PREFIX(fail_stack_type) fail_stack;
11626+#endif
11627+#ifdef DEBUG
11628+ static unsigned failure_id;
11629+ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
11630+#endif
11631+
11632+#ifdef REL_ALLOC
11633+ /* This holds the pointer to the failure stack, when
11634+ it is allocated relocatably. */
11635+ fail_stack_elt_t *failure_stack_ptr;
11636+#endif
11637+
11638+ /* We fill all the registers internally, independent of what we
11639+ return, for use in backreferences. The number here includes
11640+ an element for register zero. */
11641+ size_t num_regs = bufp->re_nsub + 1;
11642+
11643+ /* The currently active registers. */
11644+ active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
11645+ active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
11646+
11647+ /* Information on the contents of registers. These are pointers into
11648+ the input strings; they record just what was matched (on this
11649+ attempt) by a subexpression part of the pattern, that is, the
11650+ regnum-th regstart pointer points to where in the pattern we began
11651+ matching and the regnum-th regend points to right after where we
11652+ stopped matching the regnum-th subexpression. (The zeroth register
11653+ keeps track of what the whole pattern matches.) */
11654+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
11655+ const CHAR_T **regstart, **regend;
11656+#endif
11657+
11658+ /* If a group that's operated upon by a repetition operator fails to
11659+ match anything, then the register for its start will need to be
11660+ restored because it will have been set to wherever in the string we
11661+ are when we last see its open-group operator. Similarly for a
11662+ register's end. */
11663+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
11664+ const CHAR_T **old_regstart, **old_regend;
11665+#endif
11666+
11667+ /* The is_active field of reg_info helps us keep track of which (possibly
11668+ nested) subexpressions we are currently in. The matched_something
11669+ field of reg_info[reg_num] helps us tell whether or not we have
11670+ matched any of the pattern so far this time through the reg_num-th
11671+ subexpression. These two fields get reset each time through any
11672+ loop their register is in. */
11673+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
11674+ PREFIX(register_info_type) *reg_info;
11675+#endif
11676+
11677+ /* The following record the register info as found in the above
11678+ variables when we find a match better than any we've seen before.
11679+ This happens as we backtrack through the failure points, which in
11680+ turn happens only if we have not yet matched the entire string. */
11681+ unsigned best_regs_set = false;
11682+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
11683+ const CHAR_T **best_regstart, **best_regend;
11684+#endif
11685+
11686+ /* Logically, this is `best_regend[0]'. But we don't want to have to
11687+ allocate space for that if we're not allocating space for anything
11688+ else (see below). Also, we never need info about register 0 for
11689+ any of the other register vectors, and it seems rather a kludge to
11690+ treat `best_regend' differently than the rest. So we keep track of
11691+ the end of the best match so far in a separate variable. We
11692+ initialize this to NULL so that when we backtrack the first time
11693+ and need to test it, it's not garbage. */
11694+ const CHAR_T *match_end = NULL;
11695+
11696+ /* This helps SET_REGS_MATCHED avoid doing redundant work. */
11697+ int set_regs_matched_done = 0;
11698+
11699+ /* Used when we pop values we don't care about. */
11700+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
11701+ const CHAR_T **reg_dummy;
11702+ PREFIX(register_info_type) *reg_info_dummy;
11703+#endif
11704+
11705+#ifdef DEBUG
11706+ /* Counts the total number of registers pushed. */
11707+ unsigned num_regs_pushed = 0;
11708+#endif
11709+
11710+ DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
11711+
11712+ INIT_FAIL_STACK ();
11713+
11714+#ifdef MATCH_MAY_ALLOCATE
11715+ /* Do not bother to initialize all the register variables if there are
11716+ no groups in the pattern, as it takes a fair amount of time. If
11717+ there are groups, we include space for register 0 (the whole
11718+ pattern), even though we never use it, since it simplifies the
11719+ array indexing. We should fix this. */
11720+ if (bufp->re_nsub)
11721+ {
11722+ regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
11723+ regend = REGEX_TALLOC (num_regs, const CHAR_T *);
11724+ old_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
11725+ old_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
11726+ best_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
11727+ best_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
11728+ reg_info = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
11729+ reg_dummy = REGEX_TALLOC (num_regs, const CHAR_T *);
11730+ reg_info_dummy = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
11731+
11732+ if (!(regstart && regend && old_regstart && old_regend && reg_info
11733+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
11734+ {
11735+ FREE_VARIABLES ();
11736+ return -2;
11737+ }
11738+ }
11739+ else
11740+ {
11741+ /* We must initialize all our variables to NULL, so that
11742+ `FREE_VARIABLES' doesn't try to free them. */
11743+ regstart = regend = old_regstart = old_regend = best_regstart
11744+ = best_regend = reg_dummy = NULL;
11745+ reg_info = reg_info_dummy = (PREFIX(register_info_type) *) NULL;
11746+ }
11747+#endif /* MATCH_MAY_ALLOCATE */
11748+
11749+ /* The starting position is bogus. */
11750+#ifdef WCHAR
11751+ if (pos < 0 || pos > csize1 + csize2)
11752+#else /* BYTE */
11753+ if (pos < 0 || pos > size1 + size2)
11754+#endif
11755+ {
11756+ FREE_VARIABLES ();
11757+ return -1;
11758+ }
11759+
11760+#ifdef WCHAR
11761+ /* Allocate wchar_t array for string1 and string2 and
11762+ fill them with converted string. */
11763+ if (string1 == NULL && string2 == NULL)
11764+ {
11765+ /* We need seting up buffers here. */
11766+
11767+ /* We must free wcs buffers in this function. */
11768+ cant_free_wcs_buf = 0;
11769+
11770+ if (csize1 != 0)
11771+ {
11772+ string1 = REGEX_TALLOC (csize1 + 1, CHAR_T);
11773+ mbs_offset1 = REGEX_TALLOC (csize1 + 1, int);
11774+ is_binary = REGEX_TALLOC (csize1 + 1, char);
11775+ if (!string1 || !mbs_offset1 || !is_binary)
11776+ {
11777+ FREE_VAR (string1);
11778+ FREE_VAR (mbs_offset1);
11779+ FREE_VAR (is_binary);
11780+ return -2;
11781+ }
11782+ }
11783+ if (csize2 != 0)
11784+ {
11785+ string2 = REGEX_TALLOC (csize2 + 1, CHAR_T);
11786+ mbs_offset2 = REGEX_TALLOC (csize2 + 1, int);
11787+ is_binary = REGEX_TALLOC (csize2 + 1, char);
11788+ if (!string2 || !mbs_offset2 || !is_binary)
11789+ {
11790+ FREE_VAR (string1);
11791+ FREE_VAR (mbs_offset1);
11792+ FREE_VAR (string2);
11793+ FREE_VAR (mbs_offset2);
11794+ FREE_VAR (is_binary);
11795+ return -2;
11796+ }
11797+ size2 = convert_mbs_to_wcs(string2, cstring2, csize2,
11798+ mbs_offset2, is_binary);
11799+ string2[size2] = L'\0'; /* for a sentinel */
11800+ FREE_VAR (is_binary);
11801+ }
11802+ }
11803+
11804+ /* We need to cast pattern to (wchar_t*), because we casted this compiled
11805+ pattern to (char*) in regex_compile. */
11806+ p = pattern = (CHAR_T*)bufp->buffer;
11807+ pend = (CHAR_T*)(bufp->buffer + bufp->used);
11808+
11809+#endif /* WCHAR */
11810+
11811+ /* Initialize subexpression text positions to -1 to mark ones that no
11812+ start_memory/stop_memory has been seen for. Also initialize the
11813+ register information struct. */
11814+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
11815+ {
11816+ regstart[mcnt] = regend[mcnt]
11817+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
11818+
11819+ REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
11820+ IS_ACTIVE (reg_info[mcnt]) = 0;
11821+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
11822+ EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
11823+ }
11824+
11825+ /* We move `string1' into `string2' if the latter's empty -- but not if
11826+ `string1' is null. */
11827+ if (size2 == 0 && string1 != NULL)
11828+ {
11829+ string2 = string1;
11830+ size2 = size1;
11831+ string1 = 0;
11832+ size1 = 0;
11833+#ifdef WCHAR
11834+ mbs_offset2 = mbs_offset1;
11835+ csize2 = csize1;
11836+ mbs_offset1 = NULL;
11837+ csize1 = 0;
11838+#endif
11839+ }
11840+ end1 = string1 + size1;
11841+ end2 = string2 + size2;
11842+
11843+ /* Compute where to stop matching, within the two strings. */
11844+#ifdef WCHAR
11845+ if (stop <= csize1)
11846+ {
11847+ mcnt = count_mbs_length(mbs_offset1, stop);
11848+ end_match_1 = string1 + mcnt;
11849+ end_match_2 = string2;
11850+ }
11851+ else
11852+ {
11853+ if (stop > csize1 + csize2)
11854+ stop = csize1 + csize2;
11855+ end_match_1 = end1;
11856+ mcnt = count_mbs_length(mbs_offset2, stop-csize1);
11857+ end_match_2 = string2 + mcnt;
11858+ }
11859+ if (mcnt < 0)
11860+ { /* count_mbs_length return error. */
11861+ FREE_VARIABLES ();
11862+ return -1;
11863+ }
11864+#else
11865+ if (stop <= size1)
11866+ {
11867+ end_match_1 = string1 + stop;
11868+ end_match_2 = string2;
11869+ }
11870+ else
11871+ {
11872+ end_match_1 = end1;
11873+ end_match_2 = string2 + stop - size1;
11874+ }
11875+#endif /* WCHAR */
11876+
11877+ /* `p' scans through the pattern as `d' scans through the data.
11878+ `dend' is the end of the input string that `d' points within. `d'
11879+ is advanced into the following input string whenever necessary, but
11880+ this happens before fetching; therefore, at the beginning of the
11881+ loop, `d' can be pointing at the end of a string, but it cannot
11882+ equal `string2'. */
11883+#ifdef WCHAR
11884+ if (size1 > 0 && pos <= csize1)
11885+ {
11886+ mcnt = count_mbs_length(mbs_offset1, pos);
11887+ d = string1 + mcnt;
11888+ dend = end_match_1;
11889+ }
11890+ else
11891+ {
11892+ mcnt = count_mbs_length(mbs_offset2, pos-csize1);
11893+ d = string2 + mcnt;
11894+ dend = end_match_2;
11895+ }
11896+
11897+ if (mcnt < 0)
11898+ { /* count_mbs_length return error. */
11899+ FREE_VARIABLES ();
11900+ return -1;
11901+ }
11902+#else
11903+ if (size1 > 0 && pos <= size1)
11904+ {
11905+ d = string1 + pos;
11906+ dend = end_match_1;
11907+ }
11908+ else
11909+ {
11910+ d = string2 + pos - size1;
11911+ dend = end_match_2;
11912+ }
11913+#endif /* WCHAR */
11914+
11915+ DEBUG_PRINT1 ("The compiled pattern is:\n");
11916+ DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
11917+ DEBUG_PRINT1 ("The string to match is: `");
11918+ DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
11919+ DEBUG_PRINT1 ("'\n");
11920+
11921+ /* This loops over pattern commands. It exits by returning from the
11922+ function if the match is complete, or it drops through if the match
11923+ fails at this starting point in the input data. */
11924+ for (;;)
11925+ {
11926+#ifdef _LIBC
11927+ DEBUG_PRINT2 ("\n%p: ", p);
11928+#else
11929+ DEBUG_PRINT2 ("\n0x%x: ", p);
11930+#endif
11931+
11932+ if (p == pend)
11933+ { /* End of pattern means we might have succeeded. */
11934+ DEBUG_PRINT1 ("end of pattern ... ");
11935+
11936+ /* If we haven't matched the entire string, and we want the
11937+ longest match, try backtracking. */
11938+ if (d != end_match_2)
11939+ {
11940+ /* 1 if this match ends in the same string (string1 or string2)
11941+ as the best previous match. */
11942+ boolean same_str_p = (FIRST_STRING_P (match_end)
11943+ == MATCHING_IN_FIRST_STRING);
11944+ /* 1 if this match is the best seen so far. */
11945+ boolean best_match_p;
11946+
11947+ /* AIX compiler got confused when this was combined
11948+ with the previous declaration. */
11949+ if (same_str_p)
11950+ best_match_p = d > match_end;
11951+ else
11952+ best_match_p = !MATCHING_IN_FIRST_STRING;
11953+
11954+ DEBUG_PRINT1 ("backtracking.\n");
11955+
11956+ if (!FAIL_STACK_EMPTY ())
11957+ { /* More failure points to try. */
11958+
11959+ /* If exceeds best match so far, save it. */
11960+ if (!best_regs_set || best_match_p)
11961+ {
11962+ best_regs_set = true;
11963+ match_end = d;
11964+
11965+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
11966+
11967+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
11968+ {
11969+ best_regstart[mcnt] = regstart[mcnt];
11970+ best_regend[mcnt] = regend[mcnt];
11971+ }
11972+ }
11973+ goto fail;
11974+ }
11975+
11976+ /* If no failure points, don't restore garbage. And if
11977+ last match is real best match, don't restore second
11978+ best one. */
11979+ else if (best_regs_set && !best_match_p)
11980+ {
11981+ restore_best_regs:
11982+ /* Restore best match. It may happen that `dend ==
11983+ end_match_1' while the restored d is in string2.
11984+ For example, the pattern `x.*y.*z' against the
11985+ strings `x-' and `y-z-', if the two strings are
11986+ not consecutive in memory. */
11987+ DEBUG_PRINT1 ("Restoring best registers.\n");
11988+
11989+ d = match_end;
11990+ dend = ((d >= string1 && d <= end1)
11991+ ? end_match_1 : end_match_2);
11992+
11993+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
11994+ {
11995+ regstart[mcnt] = best_regstart[mcnt];
11996+ regend[mcnt] = best_regend[mcnt];
11997+ }
11998+ }
11999+ } /* d != end_match_2 */
12000+
12001+ succeed_label:
12002+ DEBUG_PRINT1 ("Accepting match.\n");
12003+ /* If caller wants register contents data back, do it. */
12004+ if (regs && !bufp->no_sub)
12005+ {
12006+ /* Have the register data arrays been allocated? */
12007+ if (bufp->regs_allocated == REGS_UNALLOCATED)
12008+ { /* No. So allocate them with malloc. We need one
12009+ extra element beyond `num_regs' for the `-1' marker
12010+ GNU code uses. */
12011+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
12012+ regs->start = TALLOC (regs->num_regs, regoff_t);
12013+ regs->end = TALLOC (regs->num_regs, regoff_t);
12014+ if (regs->start == NULL || regs->end == NULL)
12015+ {
12016+ FREE_VARIABLES ();
12017+ return -2;
12018+ }
12019+ bufp->regs_allocated = REGS_REALLOCATE;
12020+ }
12021+ else if (bufp->regs_allocated == REGS_REALLOCATE)
12022+ { /* Yes. If we need more elements than were already
12023+ allocated, reallocate them. If we need fewer, just
12024+ leave it alone. */
12025+ if (regs->num_regs < num_regs + 1)
12026+ {
12027+ regs->num_regs = num_regs + 1;
12028+ RETALLOC (regs->start, regs->num_regs, regoff_t);
12029+ RETALLOC (regs->end, regs->num_regs, regoff_t);
12030+ if (regs->start == NULL || regs->end == NULL)
12031+ {
12032+ FREE_VARIABLES ();
12033+ return -2;
12034+ }
12035+ }
12036+ }
12037+ else
12038+ {
12039+ /* These braces fend off a "empty body in an else-statement"
12040+ warning under GCC when assert expands to nothing. */
12041+ assert (bufp->regs_allocated == REGS_FIXED);
12042+ }
12043+
12044+ /* Convert the pointer data in `regstart' and `regend' to
12045+ indices. Register zero has to be set differently,
12046+ since we haven't kept track of any info for it. */
12047+ if (regs->num_regs > 0)
12048+ {
12049+ regs->start[0] = pos;
12050+#ifdef WCHAR
12051+ if (MATCHING_IN_FIRST_STRING)
12052+ regs->end[0] = mbs_offset1 != NULL ?
12053+ mbs_offset1[d-string1] : 0;
12054+ else
12055+ regs->end[0] = csize1 + (mbs_offset2 != NULL ?
12056+ mbs_offset2[d-string2] : 0);
12057+#else
12058+ regs->end[0] = (MATCHING_IN_FIRST_STRING
12059+ ? ((regoff_t) (d - string1))
12060+ : ((regoff_t) (d - string2 + size1)));
12061+#endif /* WCHAR */
12062+ }
12063+
12064+ /* Go through the first `min (num_regs, regs->num_regs)'
12065+ registers, since that is all we initialized. */
12066+ for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs);
12067+ mcnt++)
12068+ {
12069+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
12070+ regs->start[mcnt] = regs->end[mcnt] = -1;
12071+ else
12072+ {
12073+ regs->start[mcnt]
12074+ = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
12075+ regs->end[mcnt]
12076+ = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
12077+ }
12078+ }
12079+
12080+ /* If the regs structure we return has more elements than
12081+ were in the pattern, set the extra elements to -1. If
12082+ we (re)allocated the registers, this is the case,
12083+ because we always allocate enough to have at least one
12084+ -1 at the end. */
12085+ for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++)
12086+ regs->start[mcnt] = regs->end[mcnt] = -1;
12087+ } /* regs && !bufp->no_sub */
12088+
12089+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
12090+ nfailure_points_pushed, nfailure_points_popped,
12091+ nfailure_points_pushed - nfailure_points_popped);
12092+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
12093+
12094+#ifdef WCHAR
12095+ if (MATCHING_IN_FIRST_STRING)
12096+ mcnt = mbs_offset1 != NULL ? mbs_offset1[d-string1] : 0;
12097+ else
12098+ mcnt = (mbs_offset2 != NULL ? mbs_offset2[d-string2] : 0) +
12099+ csize1;
12100+ mcnt -= pos;
12101+#else
12102+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
12103+ ? string1
12104+ : string2 - size1);
12105+#endif /* WCHAR */
12106+
12107+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
12108+
12109+ FREE_VARIABLES ();
12110+ return mcnt;
12111+ }
12112+
12113+ /* Otherwise match next pattern command. */
12114+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
12115+ {
12116+ /* Ignore these. Used to ignore the n of succeed_n's which
12117+ currently have n == 0. */
12118+ case no_op:
12119+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
12120+ break;
12121+
12122+ case succeed:
12123+ DEBUG_PRINT1 ("EXECUTING succeed.\n");
12124+ goto succeed_label;
12125+
12126+ /* Match the next n pattern characters exactly. The following
12127+ byte in the pattern defines n, and the n bytes after that
12128+ are the characters to match. */
12129+ case exactn:
12130+#ifdef MBS_SUPPORT
12131+ case exactn_bin:
12132+#endif
12133+ mcnt = *p++;
12134+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
12135+
12136+ /* This is written out as an if-else so we don't waste time
12137+ testing `translate' inside the loop. */
12138+ if (translate)
12139+ {
12140+ do
12141+ {
12142+ PREFETCH ();
12143+#ifdef WCHAR
12144+ if (*d <= 0xff)
12145+ {
12146+ if ((UCHAR_T) translate[(unsigned char) *d++]
12147+ != (UCHAR_T) *p++)
12148+ goto fail;
12149+ }
12150+ else
12151+ {
12152+ if (*d++ != (CHAR_T) *p++)
12153+ goto fail;
12154+ }
12155+#else
12156+ if ((UCHAR_T) translate[(unsigned char) *d++]
12157+ != (UCHAR_T) *p++)
12158+ goto fail;
12159+#endif /* WCHAR */
12160+ }
12161+ while (--mcnt);
12162+ }
12163+ else
12164+ {
12165+ do
12166+ {
12167+ PREFETCH ();
12168+ if (*d++ != (CHAR_T) *p++) goto fail;
12169+ }
12170+ while (--mcnt);
12171+ }
12172+ SET_REGS_MATCHED ();
12173+ break;
12174+
12175+
12176+ /* Match any character except possibly a newline or a null. */
12177+ case anychar:
12178+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
12179+
12180+ PREFETCH ();
12181+
12182+ if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
12183+ || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
12184+ goto fail;
12185+
12186+ SET_REGS_MATCHED ();
12187+ DEBUG_PRINT2 (" Matched `%ld'.\n", (long int) *d);
12188+ d++;
12189+ break;
12190+
12191+
12192+ case charset:
12193+ case charset_not:
12194+ {
12195+ register UCHAR_T c;
12196+#ifdef WCHAR
12197+ unsigned int i, char_class_length, coll_symbol_length,
12198+ equiv_class_length, ranges_length, chars_length, length;
12199+ CHAR_T *workp, *workp2, *charset_top;
12200+#define WORK_BUFFER_SIZE 128
12201+ CHAR_T str_buf[WORK_BUFFER_SIZE];
12202+# ifdef _LIBC
12203+ uint32_t nrules;
12204+# endif /* _LIBC */
12205+#endif /* WCHAR */
12206+ boolean negate = (re_opcode_t) *(p - 1) == charset_not;
12207+
12208+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", negate ? "_not" : "");
12209+ PREFETCH ();
12210+ c = TRANSLATE (*d); /* The character to match. */
12211+#ifdef WCHAR
12212+# ifdef _LIBC
12213+ nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
12214+# endif /* _LIBC */
12215+ charset_top = p - 1;
12216+ char_class_length = *p++;
12217+ coll_symbol_length = *p++;
12218+ equiv_class_length = *p++;
12219+ ranges_length = *p++;
12220+ chars_length = *p++;
12221+ /* p points charset[6], so the address of the next instruction
12222+ (charset[l+m+n+2o+k+p']) equals p[l+m+n+2*o+p'],
12223+ where l=length of char_classes, m=length of collating_symbol,
12224+ n=equivalence_class, o=length of char_range,
12225+ p'=length of character. */
12226+ workp = p;
12227+ /* Update p to indicate the next instruction. */
12228+ p += char_class_length + coll_symbol_length+ equiv_class_length +
12229+ 2*ranges_length + chars_length;
12230+
12231+ /* match with char_class? */
12232+ for (i = 0; i < char_class_length ; i += CHAR_CLASS_SIZE)
12233+ {
12234+ wctype_t wctype;
12235+ uintptr_t alignedp = ((uintptr_t)workp
12236+ + __alignof__(wctype_t) - 1)
12237+ & ~(uintptr_t)(__alignof__(wctype_t) - 1);
12238+ wctype = *((wctype_t*)alignedp);
12239+ workp += CHAR_CLASS_SIZE;
12240+# ifdef _LIBC
12241+ if (__iswctype((wint_t)c, wctype))
12242+ goto char_set_matched;
12243+# else
12244+ if (iswctype((wint_t)c, wctype))
12245+ goto char_set_matched;
12246+# endif
12247+ }
12248+
12249+ /* match with collating_symbol? */
12250+# ifdef _LIBC
12251+ if (nrules != 0)
12252+ {
12253+ const unsigned char *extra = (const unsigned char *)
12254+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
12255+
12256+ for (workp2 = workp + coll_symbol_length ; workp < workp2 ;
12257+ workp++)
12258+ {
12259+ int32_t *wextra;
12260+ wextra = (int32_t*)(extra + *workp++);
12261+ for (i = 0; i < *wextra; ++i)
12262+ if (TRANSLATE(d[i]) != wextra[1 + i])
12263+ break;
12264+
12265+ if (i == *wextra)
12266+ {
12267+ /* Update d, however d will be incremented at
12268+ char_set_matched:, we decrement d here. */
12269+ d += i - 1;
12270+ goto char_set_matched;
12271+ }
12272+ }
12273+ }
12274+ else /* (nrules == 0) */
12275+# endif
12276+ /* If we can't look up collation data, we use wcscoll
12277+ instead. */
12278+ {
12279+ for (workp2 = workp + coll_symbol_length ; workp < workp2 ;)
12280+ {
12281+ const CHAR_T *backup_d = d, *backup_dend = dend;
12282+# ifdef _LIBC
12283+ length = __wcslen (workp);
12284+# else
12285+ length = wcslen (workp);
12286+# endif
12287+
12288+ /* If wcscoll(the collating symbol, whole string) > 0,
12289+ any substring of the string never match with the
12290+ collating symbol. */
12291+# ifdef _LIBC
12292+ if (__wcscoll (workp, d) > 0)
12293+# else
12294+ if (wcscoll (workp, d) > 0)
12295+# endif
12296+ {
12297+ workp += length + 1;
12298+ continue;
12299+ }
12300+
12301+ /* First, we compare the collating symbol with
12302+ the first character of the string.
12303+ If it don't match, we add the next character to
12304+ the compare buffer in turn. */
12305+ for (i = 0 ; i < WORK_BUFFER_SIZE-1 ; i++, d++)
12306+ {
12307+ int match;
12308+ if (d == dend)
12309+ {
12310+ if (dend == end_match_2)
12311+ break;
12312+ d = string2;
12313+ dend = end_match_2;
12314+ }
12315+
12316+ /* add next character to the compare buffer. */
12317+ str_buf[i] = TRANSLATE(*d);
12318+ str_buf[i+1] = '\0';
12319+
12320+# ifdef _LIBC
12321+ match = __wcscoll (workp, str_buf);
12322+# else
12323+ match = wcscoll (workp, str_buf);
12324+# endif
12325+ if (match == 0)
12326+ goto char_set_matched;
12327+
12328+ if (match < 0)
12329+ /* (str_buf > workp) indicate (str_buf + X > workp),
12330+ because for all X (str_buf + X > str_buf).
12331+ So we don't need continue this loop. */
12332+ break;
12333+
12334+ /* Otherwise(str_buf < workp),
12335+ (str_buf+next_character) may equals (workp).
12336+ So we continue this loop. */
12337+ }
12338+ /* not matched */
12339+ d = backup_d;
12340+ dend = backup_dend;
12341+ workp += length + 1;
12342+ }
12343+ }
12344+ /* match with equivalence_class? */
12345+# ifdef _LIBC
12346+ if (nrules != 0)
12347+ {
12348+ const CHAR_T *backup_d = d, *backup_dend = dend;
12349+ /* Try to match the equivalence class against
12350+ those known to the collate implementation. */
12351+ const int32_t *table;
12352+ const int32_t *weights;
12353+ const int32_t *extra;
12354+ const int32_t *indirect;
12355+ int32_t idx, idx2;
12356+ wint_t *cp;
12357+ size_t len;
12358+
12359+ /* This #include defines a local function! */
12360+# include <locale/weightwc.h>
12361+
12362+ table = (const int32_t *)
12363+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
12364+ weights = (const wint_t *)
12365+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
12366+ extra = (const wint_t *)
12367+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
12368+ indirect = (const int32_t *)
12369+ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
12370+
12371+ /* Write 1 collating element to str_buf, and
12372+ get its index. */
12373+ idx2 = 0;
12374+
12375+ for (i = 0 ; idx2 == 0 && i < WORK_BUFFER_SIZE - 1; i++)
12376+ {
12377+ cp = (wint_t*)str_buf;
12378+ if (d == dend)
12379+ {
12380+ if (dend == end_match_2)
12381+ break;
12382+ d = string2;
12383+ dend = end_match_2;
12384+ }
12385+ str_buf[i] = TRANSLATE(*(d+i));
12386+ str_buf[i+1] = '\0'; /* sentinel */
12387+ idx2 = findidx ((const wint_t**)&cp, i);
12388+ }
12389+
12390+ /* Update d, however d will be incremented at
12391+ char_set_matched:, we decrement d here. */
12392+ d = backup_d + ((wchar_t*)cp - (wchar_t*)str_buf - 1);
12393+ if (d >= dend)
12394+ {
12395+ if (dend == end_match_2)
12396+ d = dend;
12397+ else
12398+ {
12399+ d = string2;
12400+ dend = end_match_2;
12401+ }
12402+ }
12403+
12404+ len = weights[idx2];
12405+
12406+ for (workp2 = workp + equiv_class_length ; workp < workp2 ;
12407+ workp++)
12408+ {
12409+ idx = (int32_t)*workp;
12410+ /* We already checked idx != 0 in regex_compile. */
12411+
12412+ if (idx2 != 0 && len == weights[idx])
12413+ {
12414+ int cnt = 0;
12415+ while (cnt < len && (weights[idx + 1 + cnt]
12416+ == weights[idx2 + 1 + cnt]))
12417+ ++cnt;
12418+
12419+ if (cnt == len)
12420+ goto char_set_matched;
12421+ }
12422+ }
12423+ /* not matched */
12424+ d = backup_d;
12425+ dend = backup_dend;
12426+ }
12427+ else /* (nrules == 0) */
12428+# endif
12429+ /* If we can't look up collation data, we use wcscoll
12430+ instead. */
12431+ {
12432+ for (workp2 = workp + equiv_class_length ; workp < workp2 ;)
12433+ {
12434+ const CHAR_T *backup_d = d, *backup_dend = dend;
12435+# ifdef _LIBC
12436+ length = __wcslen (workp);
12437+# else
12438+ length = wcslen (workp);
12439+# endif
12440+
12441+ /* If wcscoll(the collating symbol, whole string) > 0,
12442+ any substring of the string never match with the
12443+ collating symbol. */
12444+# ifdef _LIBC
12445+ if (__wcscoll (workp, d) > 0)
12446+# else
12447+ if (wcscoll (workp, d) > 0)
12448+# endif
12449+ {
12450+ workp += length + 1;
12451+ break;
12452+ }
12453+
12454+ /* First, we compare the equivalence class with
12455+ the first character of the string.
12456+ If it don't match, we add the next character to
12457+ the compare buffer in turn. */
12458+ for (i = 0 ; i < WORK_BUFFER_SIZE - 1 ; i++, d++)
12459+ {
12460+ int match;
12461+ if (d == dend)
12462+ {
12463+ if (dend == end_match_2)
12464+ break;
12465+ d = string2;
12466+ dend = end_match_2;
12467+ }
12468+
12469+ /* add next character to the compare buffer. */
12470+ str_buf[i] = TRANSLATE(*d);
12471+ str_buf[i+1] = '\0';
12472+
12473+# ifdef _LIBC
12474+ match = __wcscoll (workp, str_buf);
12475+# else
12476+ match = wcscoll (workp, str_buf);
12477+# endif
12478+
12479+ if (match == 0)
12480+ goto char_set_matched;
12481+
12482+ if (match < 0)
12483+ /* (str_buf > workp) indicate (str_buf + X > workp),
12484+ because for all X (str_buf + X > str_buf).
12485+ So we don't need continue this loop. */
12486+ break;
12487+
12488+ /* Otherwise(str_buf < workp),
12489+ (str_buf+next_character) may equals (workp).
12490+ So we continue this loop. */
12491+ }
12492+ /* not matched */
12493+ d = backup_d;
12494+ dend = backup_dend;
12495+ workp += length + 1;
12496+ }
12497+ }
12498+
12499+ /* match with char_range? */
12500+# ifdef _LIBC
12501+ if (nrules != 0)
12502+ {
12503+ uint32_t collseqval;
12504+ const char *collseq = (const char *)
12505+ _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
12506+
12507+ collseqval = collseq_table_lookup (collseq, c);
12508+
12509+ for (; workp < p - chars_length ;)
12510+ {
12511+ uint32_t start_val, end_val;
12512+
12513+ /* We already compute the collation sequence value
12514+ of the characters (or collating symbols). */
12515+ start_val = (uint32_t) *workp++; /* range_start */
12516+ end_val = (uint32_t) *workp++; /* range_end */
12517+
12518+ if (start_val <= collseqval && collseqval <= end_val)
12519+ goto char_set_matched;
12520+ }
12521+ }
12522+ else
12523+# endif
12524+ {
12525+ /* We set range_start_char at str_buf[0], range_end_char
12526+ at str_buf[4], and compared char at str_buf[2]. */
12527+ str_buf[1] = 0;
12528+ str_buf[2] = c;
12529+ str_buf[3] = 0;
12530+ str_buf[5] = 0;
12531+ for (; workp < p - chars_length ;)
12532+ {
12533+ wchar_t *range_start_char, *range_end_char;
12534+
12535+ /* match if (range_start_char <= c <= range_end_char). */
12536+
12537+ /* If range_start(or end) < 0, we assume -range_start(end)
12538+ is the offset of the collating symbol which is specified
12539+ as the character of the range start(end). */
12540+
12541+ /* range_start */
12542+ if (*workp < 0)
12543+ range_start_char = charset_top - (*workp++);
12544+ else
12545+ {
12546+ str_buf[0] = *workp++;
12547+ range_start_char = str_buf;
12548+ }
12549+
12550+ /* range_end */
12551+ if (*workp < 0)
12552+ range_end_char = charset_top - (*workp++);
12553+ else
12554+ {
12555+ str_buf[4] = *workp++;
12556+ range_end_char = str_buf + 4;
12557+ }
12558+
12559+# ifdef _LIBC
12560+ if (__wcscoll (range_start_char, str_buf+2) <= 0
12561+ && __wcscoll (str_buf+2, range_end_char) <= 0)
12562+# else
12563+ if (wcscoll (range_start_char, str_buf+2) <= 0
12564+ && wcscoll (str_buf+2, range_end_char) <= 0)
12565+# endif
12566+ goto char_set_matched;
12567+ }
12568+ }
12569+
12570+ /* match with char? */
12571+ for (; workp < p ; workp++)
12572+ if (c == *workp)
12573+ goto char_set_matched;
12574+
12575+ negate = !negate;
12576+
12577+ char_set_matched:
12578+ if (negate) goto fail;
12579+#else
12580+ /* Cast to `unsigned' instead of `unsigned char' in case the
12581+ bit list is a full 32 bytes long. */
12582+ if (c < (unsigned) (*p * BYTEWIDTH)
12583+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
12584+ negate = !negate;
12585+
12586+ p += 1 + *p;
12587+
12588+ if (!negate) goto fail;
12589+#undef WORK_BUFFER_SIZE
12590+#endif /* WCHAR */
12591+ SET_REGS_MATCHED ();
12592+ d++;
12593+ break;
12594+ }
12595+
12596+
12597+ /* The beginning of a group is represented by start_memory.
12598+ The arguments are the register number in the next byte, and the
12599+ number of groups inner to this one in the next. The text
12600+ matched within the group is recorded (in the internal
12601+ registers data structure) under the register number. */
12602+ case start_memory:
12603+ DEBUG_PRINT3 ("EXECUTING start_memory %ld (%ld):\n",
12604+ (long int) *p, (long int) p[1]);
12605+
12606+ /* Find out if this group can match the empty string. */
12607+ p1 = p; /* To send to group_match_null_string_p. */
12608+
12609+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
12610+ REG_MATCH_NULL_STRING_P (reg_info[*p])
12611+ = PREFIX(group_match_null_string_p) (&p1, pend, reg_info);
12612+
12613+ /* Save the position in the string where we were the last time
12614+ we were at this open-group operator in case the group is
12615+ operated upon by a repetition operator, e.g., with `(a*)*b'
12616+ against `ab'; then we want to ignore where we are now in
12617+ the string in case this attempt to match fails. */
12618+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
12619+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
12620+ : regstart[*p];
12621+ DEBUG_PRINT2 (" old_regstart: %d\n",
12622+ POINTER_TO_OFFSET (old_regstart[*p]));
12623+
12624+ regstart[*p] = d;
12625+ DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
12626+
12627+ IS_ACTIVE (reg_info[*p]) = 1;
12628+ MATCHED_SOMETHING (reg_info[*p]) = 0;
12629+
12630+ /* Clear this whenever we change the register activity status. */
12631+ set_regs_matched_done = 0;
12632+
12633+ /* This is the new highest active register. */
12634+ highest_active_reg = *p;
12635+
12636+ /* If nothing was active before, this is the new lowest active
12637+ register. */
12638+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
12639+ lowest_active_reg = *p;
12640+
12641+ /* Move past the register number and inner group count. */
12642+ p += 2;
12643+ just_past_start_mem = p;
12644+
12645+ break;
12646+
12647+
12648+ /* The stop_memory opcode represents the end of a group. Its
12649+ arguments are the same as start_memory's: the register
12650+ number, and the number of inner groups. */
12651+ case stop_memory:
12652+ DEBUG_PRINT3 ("EXECUTING stop_memory %ld (%ld):\n",
12653+ (long int) *p, (long int) p[1]);
12654+
12655+ /* We need to save the string position the last time we were at
12656+ this close-group operator in case the group is operated
12657+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
12658+ against `aba'; then we want to ignore where we are now in
12659+ the string in case this attempt to match fails. */
12660+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
12661+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
12662+ : regend[*p];
12663+ DEBUG_PRINT2 (" old_regend: %d\n",
12664+ POINTER_TO_OFFSET (old_regend[*p]));
12665+
12666+ regend[*p] = d;
12667+ DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
12668+
12669+ /* This register isn't active anymore. */
12670+ IS_ACTIVE (reg_info[*p]) = 0;
12671+
12672+ /* Clear this whenever we change the register activity status. */
12673+ set_regs_matched_done = 0;
12674+
12675+ /* If this was the only register active, nothing is active
12676+ anymore. */
12677+ if (lowest_active_reg == highest_active_reg)
12678+ {
12679+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
12680+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
12681+ }
12682+ else
12683+ { /* We must scan for the new highest active register, since
12684+ it isn't necessarily one less than now: consider
12685+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
12686+ new highest active register is 1. */
12687+ UCHAR_T r = *p - 1;
12688+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
12689+ r--;
12690+
12691+ /* If we end up at register zero, that means that we saved
12692+ the registers as the result of an `on_failure_jump', not
12693+ a `start_memory', and we jumped to past the innermost
12694+ `stop_memory'. For example, in ((.)*) we save
12695+ registers 1 and 2 as a result of the *, but when we pop
12696+ back to the second ), we are at the stop_memory 1.
12697+ Thus, nothing is active. */
12698+ if (r == 0)
12699+ {
12700+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
12701+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
12702+ }
12703+ else
12704+ highest_active_reg = r;
12705+ }
12706+
12707+ /* If just failed to match something this time around with a
12708+ group that's operated on by a repetition operator, try to
12709+ force exit from the ``loop'', and restore the register
12710+ information for this group that we had before trying this
12711+ last match. */
12712+ if ((!MATCHED_SOMETHING (reg_info[*p])
12713+ || just_past_start_mem == p - 1)
12714+ && (p + 2) < pend)
12715+ {
12716+ boolean is_a_jump_n = false;
12717+
12718+ p1 = p + 2;
12719+ mcnt = 0;
12720+ switch ((re_opcode_t) *p1++)
12721+ {
12722+ case jump_n:
12723+ is_a_jump_n = true;
12724+ case pop_failure_jump:
12725+ case maybe_pop_jump:
12726+ case jump:
12727+ case dummy_failure_jump:
12728+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
12729+ if (is_a_jump_n)
12730+ p1 += OFFSET_ADDRESS_SIZE;
12731+ break;
12732+
12733+ default:
12734+ /* do nothing */ ;
12735+ }
12736+ p1 += mcnt;
12737+
12738+ /* If the next operation is a jump backwards in the pattern
12739+ to an on_failure_jump right before the start_memory
12740+ corresponding to this stop_memory, exit from the loop
12741+ by forcing a failure after pushing on the stack the
12742+ on_failure_jump's jump in the pattern, and d. */
12743+ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
12744+ && (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == start_memory
12745+ && p1[2+OFFSET_ADDRESS_SIZE] == *p)
12746+ {
12747+ /* If this group ever matched anything, then restore
12748+ what its registers were before trying this last
12749+ failed match, e.g., with `(a*)*b' against `ab' for
12750+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
12751+ against `aba' for regend[3].
12752+
12753+ Also restore the registers for inner groups for,
12754+ e.g., `((a*)(b*))*' against `aba' (register 3 would
12755+ otherwise get trashed). */
12756+
12757+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
12758+ {
12759+ unsigned r;
12760+
12761+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
12762+
12763+ /* Restore this and inner groups' (if any) registers. */
12764+ for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1);
12765+ r++)
12766+ {
12767+ regstart[r] = old_regstart[r];
12768+
12769+ /* xx why this test? */
12770+ if (old_regend[r] >= regstart[r])
12771+ regend[r] = old_regend[r];
12772+ }
12773+ }
12774+ p1++;
12775+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
12776+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
12777+
12778+ goto fail;
12779+ }
12780+ }
12781+
12782+ /* Move past the register number and the inner group count. */
12783+ p += 2;
12784+ break;
12785+
12786+
12787+ /* \<digit> has been turned into a `duplicate' command which is
12788+ followed by the numeric value of <digit> as the register number. */
12789+ case duplicate:
12790+ {
12791+ register const CHAR_T *d2, *dend2;
12792+ int regno = *p++; /* Get which register to match against. */
12793+ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
12794+
12795+ /* Can't back reference a group which we've never matched. */
12796+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
12797+ goto fail;
12798+
12799+ /* Where in input to try to start matching. */
12800+ d2 = regstart[regno];
12801+
12802+ /* Where to stop matching; if both the place to start and
12803+ the place to stop matching are in the same string, then
12804+ set to the place to stop, otherwise, for now have to use
12805+ the end of the first string. */
12806+
12807+ dend2 = ((FIRST_STRING_P (regstart[regno])
12808+ == FIRST_STRING_P (regend[regno]))
12809+ ? regend[regno] : end_match_1);
12810+ for (;;)
12811+ {
12812+ /* If necessary, advance to next segment in register
12813+ contents. */
12814+ while (d2 == dend2)
12815+ {
12816+ if (dend2 == end_match_2) break;
12817+ if (dend2 == regend[regno]) break;
12818+
12819+ /* End of string1 => advance to string2. */
12820+ d2 = string2;
12821+ dend2 = regend[regno];
12822+ }
12823+ /* At end of register contents => success */
12824+ if (d2 == dend2) break;
12825+
12826+ /* If necessary, advance to next segment in data. */
12827+ PREFETCH ();
12828+
12829+ /* How many characters left in this segment to match. */
12830+ mcnt = dend - d;
12831+
12832+ /* Want how many consecutive characters we can match in
12833+ one shot, so, if necessary, adjust the count. */
12834+ if (mcnt > dend2 - d2)
12835+ mcnt = dend2 - d2;
12836+
12837+ /* Compare that many; failure if mismatch, else move
12838+ past them. */
12839+ if (translate
12840+ ? PREFIX(bcmp_translate) (d, d2, mcnt, translate)
12841+ : memcmp (d, d2, mcnt*sizeof(UCHAR_T)))
12842+ goto fail;
12843+ d += mcnt, d2 += mcnt;
12844+
12845+ /* Do this because we've match some characters. */
12846+ SET_REGS_MATCHED ();
12847+ }
12848+ }
12849+ break;
12850+
12851+
12852+ /* begline matches the empty string at the beginning of the string
12853+ (unless `not_bol' is set in `bufp'), and, if
12854+ `newline_anchor' is set, after newlines. */
12855+ case begline:
12856+ DEBUG_PRINT1 ("EXECUTING begline.\n");
12857+
12858+ if (AT_STRINGS_BEG (d))
12859+ {
12860+ if (!bufp->not_bol) break;
12861+ }
12862+ else if (d[-1] == '\n' && bufp->newline_anchor)
12863+ {
12864+ break;
12865+ }
12866+ /* In all other cases, we fail. */
12867+ goto fail;
12868+
12869+
12870+ /* endline is the dual of begline. */
12871+ case endline:
12872+ DEBUG_PRINT1 ("EXECUTING endline.\n");
12873+
12874+ if (AT_STRINGS_END (d))
12875+ {
12876+ if (!bufp->not_eol) break;
12877+ }
12878+
12879+ /* We have to ``prefetch'' the next character. */
12880+ else if ((d == end1 ? *string2 : *d) == '\n'
12881+ && bufp->newline_anchor)
12882+ {
12883+ break;
12884+ }
12885+ goto fail;
12886+
12887+
12888+ /* Match at the very beginning of the data. */
12889+ case begbuf:
12890+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
12891+ if (AT_STRINGS_BEG (d))
12892+ break;
12893+ goto fail;
12894+
12895+
12896+ /* Match at the very end of the data. */
12897+ case endbuf:
12898+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
12899+ if (AT_STRINGS_END (d))
12900+ break;
12901+ goto fail;
12902+
12903+
12904+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
12905+ pushes NULL as the value for the string on the stack. Then
12906+ `pop_failure_point' will keep the current value for the
12907+ string, instead of restoring it. To see why, consider
12908+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
12909+ then the . fails against the \n. But the next thing we want
12910+ to do is match the \n against the \n; if we restored the
12911+ string value, we would be back at the foo.
12912+
12913+ Because this is used only in specific cases, we don't need to
12914+ check all the things that `on_failure_jump' does, to make
12915+ sure the right things get saved on the stack. Hence we don't
12916+ share its code. The only reason to push anything on the
12917+ stack at all is that otherwise we would have to change
12918+ `anychar's code to do something besides goto fail in this
12919+ case; that seems worse than this. */
12920+ case on_failure_keep_string_jump:
12921+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
12922+
12923+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
12924+#ifdef _LIBC
12925+ DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt);
12926+#else
12927+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
12928+#endif
12929+
12930+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
12931+ break;
12932+
12933+
12934+ /* Uses of on_failure_jump:
12935+
12936+ Each alternative starts with an on_failure_jump that points
12937+ to the beginning of the next alternative. Each alternative
12938+ except the last ends with a jump that in effect jumps past
12939+ the rest of the alternatives. (They really jump to the
12940+ ending jump of the following alternative, because tensioning
12941+ these jumps is a hassle.)
12942+
12943+ Repeats start with an on_failure_jump that points past both
12944+ the repetition text and either the following jump or
12945+ pop_failure_jump back to this on_failure_jump. */
12946+ case on_failure_jump:
12947+ on_failure:
12948+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
12949+
12950+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
12951+#ifdef _LIBC
12952+ DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt);
12953+#else
12954+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
12955+#endif
12956+
12957+ /* If this on_failure_jump comes right before a group (i.e.,
12958+ the original * applied to a group), save the information
12959+ for that group and all inner ones, so that if we fail back
12960+ to this point, the group's information will be correct.
12961+ For example, in \(a*\)*\1, we need the preceding group,
12962+ and in \(zz\(a*\)b*\)\2, we need the inner group. */
12963+
12964+ /* We can't use `p' to check ahead because we push
12965+ a failure point to `p + mcnt' after we do this. */
12966+ p1 = p;
12967+
12968+ /* We need to skip no_op's before we look for the
12969+ start_memory in case this on_failure_jump is happening as
12970+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
12971+ against aba. */
12972+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
12973+ p1++;
12974+
12975+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
12976+ {
12977+ /* We have a new highest active register now. This will
12978+ get reset at the start_memory we are about to get to,
12979+ but we will have saved all the registers relevant to
12980+ this repetition op, as described above. */
12981+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
12982+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
12983+ lowest_active_reg = *(p1 + 1);
12984+ }
12985+
12986+ DEBUG_PRINT1 (":\n");
12987+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
12988+ break;
12989+
12990+
12991+ /* A smart repeat ends with `maybe_pop_jump'.
12992+ We change it to either `pop_failure_jump' or `jump'. */
12993+ case maybe_pop_jump:
12994+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
12995+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
12996+ {
12997+ register UCHAR_T *p2 = p;
12998+
12999+ /* Compare the beginning of the repeat with what in the
13000+ pattern follows its end. If we can establish that there
13001+ is nothing that they would both match, i.e., that we
13002+ would have to backtrack because of (as in, e.g., `a*a')
13003+ then we can change to pop_failure_jump, because we'll
13004+ never have to backtrack.
13005+
13006+ This is not true in the case of alternatives: in
13007+ `(a|ab)*' we do need to backtrack to the `ab' alternative
13008+ (e.g., if the string was `ab'). But instead of trying to
13009+ detect that here, the alternative has put on a dummy
13010+ failure point which is what we will end up popping. */
13011+
13012+ /* Skip over open/close-group commands.
13013+ If what follows this loop is a ...+ construct,
13014+ look at what begins its body, since we will have to
13015+ match at least one of that. */
13016+ while (1)
13017+ {
13018+ if (p2 + 2 < pend
13019+ && ((re_opcode_t) *p2 == stop_memory
13020+ || (re_opcode_t) *p2 == start_memory))
13021+ p2 += 3;
13022+ else if (p2 + 2 + 2 * OFFSET_ADDRESS_SIZE < pend
13023+ && (re_opcode_t) *p2 == dummy_failure_jump)
13024+ p2 += 2 + 2 * OFFSET_ADDRESS_SIZE;
13025+ else
13026+ break;
13027+ }
13028+
13029+ p1 = p + mcnt;
13030+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
13031+ to the `maybe_finalize_jump' of this case. Examine what
13032+ follows. */
13033+
13034+ /* If we're at the end of the pattern, we can change. */
13035+ if (p2 == pend)
13036+ {
13037+ /* Consider what happens when matching ":\(.*\)"
13038+ against ":/". I don't really understand this code
13039+ yet. */
13040+ p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
13041+ pop_failure_jump;
13042+ DEBUG_PRINT1
13043+ (" End of pattern: change to `pop_failure_jump'.\n");
13044+ }
13045+
13046+ else if ((re_opcode_t) *p2 == exactn
13047+#ifdef MBS_SUPPORT
13048+ || (re_opcode_t) *p2 == exactn_bin
13049+#endif
13050+ || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
13051+ {
13052+ register UCHAR_T c
13053+ = *p2 == (UCHAR_T) endline ? '\n' : p2[2];
13054+
13055+ if (((re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn
13056+#ifdef MBS_SUPPORT
13057+ || (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn_bin
13058+#endif
13059+ ) && p1[3+OFFSET_ADDRESS_SIZE] != c)
13060+ {
13061+ p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
13062+ pop_failure_jump;
13063+#ifdef WCHAR
13064+ DEBUG_PRINT3 (" %C != %C => pop_failure_jump.\n",
13065+ (wint_t) c,
13066+ (wint_t) p1[3+OFFSET_ADDRESS_SIZE]);
13067+#else
13068+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
13069+ (char) c,
13070+ (char) p1[3+OFFSET_ADDRESS_SIZE]);
13071+#endif
13072+ }
13073+
13074+#ifndef WCHAR
13075+ else if ((re_opcode_t) p1[3] == charset
13076+ || (re_opcode_t) p1[3] == charset_not)
13077+ {
13078+ int negate = (re_opcode_t) p1[3] == charset_not;
13079+
13080+ if (c < (unsigned) (p1[4] * BYTEWIDTH)
13081+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
13082+ negate = !negate;
13083+
13084+ /* `negate' is equal to 1 if c would match, which means
13085+ that we can't change to pop_failure_jump. */
13086+ if (!negate)
13087+ {
13088+ p[-3] = (unsigned char) pop_failure_jump;
13089+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
13090+ }
13091+ }
13092+#endif /* not WCHAR */
13093+ }
13094+#ifndef WCHAR
13095+ else if ((re_opcode_t) *p2 == charset)
13096+ {
13097+ /* We win if the first character of the loop is not part
13098+ of the charset. */
13099+ if ((re_opcode_t) p1[3] == exactn
13100+ && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
13101+ && (p2[2 + p1[5] / BYTEWIDTH]
13102+ & (1 << (p1[5] % BYTEWIDTH)))))
13103+ {
13104+ p[-3] = (unsigned char) pop_failure_jump;
13105+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
13106+ }
13107+
13108+ else if ((re_opcode_t) p1[3] == charset_not)
13109+ {
13110+ int idx;
13111+ /* We win if the charset_not inside the loop
13112+ lists every character listed in the charset after. */
13113+ for (idx = 0; idx < (int) p2[1]; idx++)
13114+ if (! (p2[2 + idx] == 0
13115+ || (idx < (int) p1[4]
13116+ && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
13117+ break;
13118+
13119+ if (idx == p2[1])
13120+ {
13121+ p[-3] = (unsigned char) pop_failure_jump;
13122+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
13123+ }
13124+ }
13125+ else if ((re_opcode_t) p1[3] == charset)
13126+ {
13127+ int idx;
13128+ /* We win if the charset inside the loop
13129+ has no overlap with the one after the loop. */
13130+ for (idx = 0;
13131+ idx < (int) p2[1] && idx < (int) p1[4];
13132+ idx++)
13133+ if ((p2[2 + idx] & p1[5 + idx]) != 0)
13134+ break;
13135+
13136+ if (idx == p2[1] || idx == p1[4])
13137+ {
13138+ p[-3] = (unsigned char) pop_failure_jump;
13139+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
13140+ }
13141+ }
13142+ }
13143+#endif /* not WCHAR */
13144+ }
13145+ p -= OFFSET_ADDRESS_SIZE; /* Point at relative address again. */
13146+ if ((re_opcode_t) p[-1] != pop_failure_jump)
13147+ {
13148+ p[-1] = (UCHAR_T) jump;
13149+ DEBUG_PRINT1 (" Match => jump.\n");
13150+ goto unconditional_jump;
13151+ }
13152+ /* Note fall through. */
13153+
13154+
13155+ /* The end of a simple repeat has a pop_failure_jump back to
13156+ its matching on_failure_jump, where the latter will push a
13157+ failure point. The pop_failure_jump takes off failure
13158+ points put on by this pop_failure_jump's matching
13159+ on_failure_jump; we got through the pattern to here from the
13160+ matching on_failure_jump, so didn't fail. */
13161+ case pop_failure_jump:
13162+ {
13163+ /* We need to pass separate storage for the lowest and
13164+ highest registers, even though we don't care about the
13165+ actual values. Otherwise, we will restore only one
13166+ register from the stack, since lowest will == highest in
13167+ `pop_failure_point'. */
13168+ active_reg_t dummy_low_reg, dummy_high_reg;
13169+ UCHAR_T *pdummy = NULL;
13170+ const CHAR_T *sdummy = NULL;
13171+
13172+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
13173+ POP_FAILURE_POINT (sdummy, pdummy,
13174+ dummy_low_reg, dummy_high_reg,
13175+ reg_dummy, reg_dummy, reg_info_dummy);
13176+ }
13177+ /* Note fall through. */
13178+
13179+ unconditional_jump:
13180+#ifdef _LIBC
13181+ DEBUG_PRINT2 ("\n%p: ", p);
13182+#else
13183+ DEBUG_PRINT2 ("\n0x%x: ", p);
13184+#endif
13185+ /* Note fall through. */
13186+
13187+ /* Unconditionally jump (without popping any failure points). */
13188+ case jump:
13189+ EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
13190+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
13191+ p += mcnt; /* Do the jump. */
13192+#ifdef _LIBC
13193+ DEBUG_PRINT2 ("(to %p).\n", p);
13194+#else
13195+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
13196+#endif
13197+ break;
13198+
13199+
13200+ /* We need this opcode so we can detect where alternatives end
13201+ in `group_match_null_string_p' et al. */
13202+ case jump_past_alt:
13203+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
13204+ goto unconditional_jump;
13205+
13206+
13207+ /* Normally, the on_failure_jump pushes a failure point, which
13208+ then gets popped at pop_failure_jump. We will end up at
13209+ pop_failure_jump, also, and with a pattern of, say, `a+', we
13210+ are skipping over the on_failure_jump, so we have to push
13211+ something meaningless for pop_failure_jump to pop. */
13212+ case dummy_failure_jump:
13213+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
13214+ /* It doesn't matter what we push for the string here. What
13215+ the code at `fail' tests is the value for the pattern. */
13216+ PUSH_FAILURE_POINT (NULL, NULL, -2);
13217+ goto unconditional_jump;
13218+
13219+
13220+ /* At the end of an alternative, we need to push a dummy failure
13221+ point in case we are followed by a `pop_failure_jump', because
13222+ we don't want the failure point for the alternative to be
13223+ popped. For example, matching `(a|ab)*' against `aab'
13224+ requires that we match the `ab' alternative. */
13225+ case push_dummy_failure:
13226+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
13227+ /* See comments just above at `dummy_failure_jump' about the
13228+ two zeroes. */
13229+ PUSH_FAILURE_POINT (NULL, NULL, -2);
13230+ break;
13231+
13232+ /* Have to succeed matching what follows at least n times.
13233+ After that, handle like `on_failure_jump'. */
13234+ case succeed_n:
13235+ EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
13236+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
13237+
13238+ assert (mcnt >= 0);
13239+ /* Originally, this is how many times we HAVE to succeed. */
13240+ if (mcnt > 0)
13241+ {
13242+ mcnt--;
13243+ p += OFFSET_ADDRESS_SIZE;
13244+ STORE_NUMBER_AND_INCR (p, mcnt);
13245+#ifdef _LIBC
13246+ DEBUG_PRINT3 (" Setting %p to %d.\n", p - OFFSET_ADDRESS_SIZE
13247+ , mcnt);
13248+#else
13249+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - OFFSET_ADDRESS_SIZE
13250+ , mcnt);
13251+#endif
13252+ }
13253+ else if (mcnt == 0)
13254+ {
13255+#ifdef _LIBC
13256+ DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n",
13257+ p + OFFSET_ADDRESS_SIZE);
13258+#else
13259+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n",
13260+ p + OFFSET_ADDRESS_SIZE);
13261+#endif /* _LIBC */
13262+
13263+#ifdef WCHAR
13264+ p[1] = (UCHAR_T) no_op;
13265+#else
13266+ p[2] = (UCHAR_T) no_op;
13267+ p[3] = (UCHAR_T) no_op;
13268+#endif /* WCHAR */
13269+ goto on_failure;
13270+ }
13271+ break;
13272+
13273+ case jump_n:
13274+ EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
13275+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
13276+
13277+ /* Originally, this is how many times we CAN jump. */
13278+ if (mcnt)
13279+ {
13280+ mcnt--;
13281+ STORE_NUMBER (p + OFFSET_ADDRESS_SIZE, mcnt);
13282+
13283+#ifdef _LIBC
13284+ DEBUG_PRINT3 (" Setting %p to %d.\n", p + OFFSET_ADDRESS_SIZE,
13285+ mcnt);
13286+#else
13287+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + OFFSET_ADDRESS_SIZE,
13288+ mcnt);
13289+#endif /* _LIBC */
13290+ goto unconditional_jump;
13291+ }
13292+ /* If don't have to jump any more, skip over the rest of command. */
13293+ else
13294+ p += 2 * OFFSET_ADDRESS_SIZE;
13295+ break;
13296+
13297+ case set_number_at:
13298+ {
13299+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
13300+
13301+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
13302+ p1 = p + mcnt;
13303+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
13304+#ifdef _LIBC
13305+ DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt);
13306+#else
13307+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
13308+#endif
13309+ STORE_NUMBER (p1, mcnt);
13310+ break;
13311+ }
13312+
13313+#if 0
13314+ /* The DEC Alpha C compiler 3.x generates incorrect code for the
13315+ test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of
13316+ AT_WORD_BOUNDARY, so this code is disabled. Expanding the
13317+ macro and introducing temporary variables works around the bug. */
13318+
13319+ case wordbound:
13320+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
13321+ if (AT_WORD_BOUNDARY (d))
13322+ break;
13323+ goto fail;
13324+
13325+ case notwordbound:
13326+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
13327+ if (AT_WORD_BOUNDARY (d))
13328+ goto fail;
13329+ break;
13330+#else
13331+ case wordbound:
13332+ {
13333+ boolean prevchar, thischar;
13334+
13335+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
13336+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
13337+ break;
13338+
13339+ prevchar = WORDCHAR_P (d - 1);
13340+ thischar = WORDCHAR_P (d);
13341+ if (prevchar != thischar)
13342+ break;
13343+ goto fail;
13344+ }
13345+
13346+ case notwordbound:
13347+ {
13348+ boolean prevchar, thischar;
13349+
13350+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
13351+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
13352+ goto fail;
13353+
13354+ prevchar = WORDCHAR_P (d - 1);
13355+ thischar = WORDCHAR_P (d);
13356+ if (prevchar != thischar)
13357+ goto fail;
13358+ break;
13359+ }
13360+#endif
13361+
13362+ case wordbeg:
13363+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
13364+ if (!AT_STRINGS_END (d) && WORDCHAR_P (d)
13365+ && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
13366+ break;
13367+ goto fail;
13368+
13369+ case wordend:
13370+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
13371+ if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
13372+ && (AT_STRINGS_END (d) || !WORDCHAR_P (d)))
13373+ break;
13374+ goto fail;
13375+
13376+#ifdef emacs
13377+ case before_dot:
13378+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
13379+ if (PTR_CHAR_POS ((unsigned char *) d) >= point)
13380+ goto fail;
13381+ break;
13382+
13383+ case at_dot:
13384+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
13385+ if (PTR_CHAR_POS ((unsigned char *) d) != point)
13386+ goto fail;
13387+ break;
13388+
13389+ case after_dot:
13390+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
13391+ if (PTR_CHAR_POS ((unsigned char *) d) <= point)
13392+ goto fail;
13393+ break;
13394+
13395+ case syntaxspec:
13396+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
13397+ mcnt = *p++;
13398+ goto matchsyntax;
13399+
13400+ case wordchar:
13401+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
13402+ mcnt = (int) Sword;
13403+ matchsyntax:
13404+ PREFETCH ();
13405+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
13406+ d++;
13407+ if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
13408+ goto fail;
13409+ SET_REGS_MATCHED ();
13410+ break;
13411+
13412+ case notsyntaxspec:
13413+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
13414+ mcnt = *p++;
13415+ goto matchnotsyntax;
13416+
13417+ case notwordchar:
13418+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
13419+ mcnt = (int) Sword;
13420+ matchnotsyntax:
13421+ PREFETCH ();
13422+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
13423+ d++;
13424+ if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
13425+ goto fail;
13426+ SET_REGS_MATCHED ();
13427+ break;
13428+
13429+#else /* not emacs */
13430+ case wordchar:
13431+ DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
13432+ PREFETCH ();
13433+ if (!WORDCHAR_P (d))
13434+ goto fail;
13435+ SET_REGS_MATCHED ();
13436+ d++;
13437+ break;
13438+
13439+ case notwordchar:
13440+ DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
13441+ PREFETCH ();
13442+ if (WORDCHAR_P (d))
13443+ goto fail;
13444+ SET_REGS_MATCHED ();
13445+ d++;
13446+ break;
13447+#endif /* not emacs */
13448+
13449+ default:
13450+ abort ();
13451+ }
13452+ continue; /* Successfully executed one pattern command; keep going. */
13453+
13454+
13455+ /* We goto here if a matching operation fails. */
13456+ fail:
13457+ if (!FAIL_STACK_EMPTY ())
13458+ { /* A restart point is known. Restore to that state. */
13459+ DEBUG_PRINT1 ("\nFAIL:\n");
13460+ POP_FAILURE_POINT (d, p,
13461+ lowest_active_reg, highest_active_reg,
13462+ regstart, regend, reg_info);
13463+
13464+ /* If this failure point is a dummy, try the next one. */
13465+ if (!p)
13466+ goto fail;
13467+
13468+ /* If we failed to the end of the pattern, don't examine *p. */
13469+ assert (p <= pend);
13470+ if (p < pend)
13471+ {
13472+ boolean is_a_jump_n = false;
13473+
13474+ /* If failed to a backwards jump that's part of a repetition
13475+ loop, need to pop this failure point and use the next one. */
13476+ switch ((re_opcode_t) *p)
13477+ {
13478+ case jump_n:
13479+ is_a_jump_n = true;
13480+ case maybe_pop_jump:
13481+ case pop_failure_jump:
13482+ case jump:
13483+ p1 = p + 1;
13484+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13485+ p1 += mcnt;
13486+
13487+ if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
13488+ || (!is_a_jump_n
13489+ && (re_opcode_t) *p1 == on_failure_jump))
13490+ goto fail;
13491+ break;
13492+ default:
13493+ /* do nothing */ ;
13494+ }
13495+ }
13496+
13497+ if (d >= string1 && d <= end1)
13498+ dend = end_match_1;
13499+ }
13500+ else
13501+ break; /* Matching at this starting point really fails. */
13502+ } /* for (;;) */
13503+
13504+ if (best_regs_set)
13505+ goto restore_best_regs;
13506+
13507+ FREE_VARIABLES ();
13508+
13509+ return -1; /* Failure to match. */
13510+} /* re_match_2 */
13511+
13512+/* Subroutine definitions for re_match_2. */
13513+
13514+
13515+/* We are passed P pointing to a register number after a start_memory.
13516+
13517+ Return true if the pattern up to the corresponding stop_memory can
13518+ match the empty string, and false otherwise.
13519+
13520+ If we find the matching stop_memory, sets P to point to one past its number.
13521+ Otherwise, sets P to an undefined byte less than or equal to END.
13522+
13523+ We don't handle duplicates properly (yet). */
13524+
13525+static boolean
13526+PREFIX(group_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
13527+ PREFIX(register_info_type) *reg_info)
13528+{
13529+ int mcnt;
13530+ /* Point to after the args to the start_memory. */
13531+ UCHAR_T *p1 = *p + 2;
13532+
13533+ while (p1 < end)
13534+ {
13535+ /* Skip over opcodes that can match nothing, and return true or
13536+ false, as appropriate, when we get to one that can't, or to the
13537+ matching stop_memory. */
13538+
13539+ switch ((re_opcode_t) *p1)
13540+ {
13541+ /* Could be either a loop or a series of alternatives. */
13542+ case on_failure_jump:
13543+ p1++;
13544+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13545+
13546+ /* If the next operation is not a jump backwards in the
13547+ pattern. */
13548+
13549+ if (mcnt >= 0)
13550+ {
13551+ /* Go through the on_failure_jumps of the alternatives,
13552+ seeing if any of the alternatives cannot match nothing.
13553+ The last alternative starts with only a jump,
13554+ whereas the rest start with on_failure_jump and end
13555+ with a jump, e.g., here is the pattern for `a|b|c':
13556+
13557+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
13558+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
13559+ /exactn/1/c
13560+
13561+ So, we have to first go through the first (n-1)
13562+ alternatives and then deal with the last one separately. */
13563+
13564+
13565+ /* Deal with the first (n-1) alternatives, which start
13566+ with an on_failure_jump (see above) that jumps to right
13567+ past a jump_past_alt. */
13568+
13569+ while ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] ==
13570+ jump_past_alt)
13571+ {
13572+ /* `mcnt' holds how many bytes long the alternative
13573+ is, including the ending `jump_past_alt' and
13574+ its number. */
13575+
13576+ if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt -
13577+ (1 + OFFSET_ADDRESS_SIZE),
13578+ reg_info))
13579+ return false;
13580+
13581+ /* Move to right after this alternative, including the
13582+ jump_past_alt. */
13583+ p1 += mcnt;
13584+
13585+ /* Break if it's the beginning of an n-th alternative
13586+ that doesn't begin with an on_failure_jump. */
13587+ if ((re_opcode_t) *p1 != on_failure_jump)
13588+ break;
13589+
13590+ /* Still have to check that it's not an n-th
13591+ alternative that starts with an on_failure_jump. */
13592+ p1++;
13593+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13594+ if ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] !=
13595+ jump_past_alt)
13596+ {
13597+ /* Get to the beginning of the n-th alternative. */
13598+ p1 -= 1 + OFFSET_ADDRESS_SIZE;
13599+ break;
13600+ }
13601+ }
13602+
13603+ /* Deal with the last alternative: go back and get number
13604+ of the `jump_past_alt' just before it. `mcnt' contains
13605+ the length of the alternative. */
13606+ EXTRACT_NUMBER (mcnt, p1 - OFFSET_ADDRESS_SIZE);
13607+
13608+ if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt, reg_info))
13609+ return false;
13610+
13611+ p1 += mcnt; /* Get past the n-th alternative. */
13612+ } /* if mcnt > 0 */
13613+ break;
13614+
13615+
13616+ case stop_memory:
13617+ assert (p1[1] == **p);
13618+ *p = p1 + 2;
13619+ return true;
13620+
13621+
13622+ default:
13623+ if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
13624+ return false;
13625+ }
13626+ } /* while p1 < end */
13627+
13628+ return false;
13629+} /* group_match_null_string_p */
13630+
13631+
13632+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
13633+ It expects P to be the first byte of a single alternative and END one
13634+ byte past the last. The alternative can contain groups. */
13635+
13636+static boolean
13637+PREFIX(alt_match_null_string_p) (UCHAR_T *p, UCHAR_T *end,
13638+ PREFIX(register_info_type) *reg_info)
13639+{
13640+ int mcnt;
13641+ UCHAR_T *p1 = p;
13642+
13643+ while (p1 < end)
13644+ {
13645+ /* Skip over opcodes that can match nothing, and break when we get
13646+ to one that can't. */
13647+
13648+ switch ((re_opcode_t) *p1)
13649+ {
13650+ /* It's a loop. */
13651+ case on_failure_jump:
13652+ p1++;
13653+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13654+ p1 += mcnt;
13655+ break;
13656+
13657+ default:
13658+ if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
13659+ return false;
13660+ }
13661+ } /* while p1 < end */
13662+
13663+ return true;
13664+} /* alt_match_null_string_p */
13665+
13666+
13667+/* Deals with the ops common to group_match_null_string_p and
13668+ alt_match_null_string_p.
13669+
13670+ Sets P to one after the op and its arguments, if any. */
13671+
13672+static boolean
13673+PREFIX(common_op_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
13674+ PREFIX(register_info_type) *reg_info)
13675+{
13676+ int mcnt;
13677+ boolean ret;
13678+ int reg_no;
13679+ UCHAR_T *p1 = *p;
13680+
13681+ switch ((re_opcode_t) *p1++)
13682+ {
13683+ case no_op:
13684+ case begline:
13685+ case endline:
13686+ case begbuf:
13687+ case endbuf:
13688+ case wordbeg:
13689+ case wordend:
13690+ case wordbound:
13691+ case notwordbound:
13692+#ifdef emacs
13693+ case before_dot:
13694+ case at_dot:
13695+ case after_dot:
13696+#endif
13697+ break;
13698+
13699+ case start_memory:
13700+ reg_no = *p1;
13701+ assert (reg_no > 0 && reg_no <= MAX_REGNUM);
13702+ ret = PREFIX(group_match_null_string_p) (&p1, end, reg_info);
13703+
13704+ /* Have to set this here in case we're checking a group which
13705+ contains a group and a back reference to it. */
13706+
13707+ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
13708+ REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
13709+
13710+ if (!ret)
13711+ return false;
13712+ break;
13713+
13714+ /* If this is an optimized succeed_n for zero times, make the jump. */
13715+ case jump:
13716+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13717+ if (mcnt >= 0)
13718+ p1 += mcnt;
13719+ else
13720+ return false;
13721+ break;
13722+
13723+ case succeed_n:
13724+ /* Get to the number of times to succeed. */
13725+ p1 += OFFSET_ADDRESS_SIZE;
13726+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13727+
13728+ if (mcnt == 0)
13729+ {
13730+ p1 -= 2 * OFFSET_ADDRESS_SIZE;
13731+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
13732+ p1 += mcnt;
13733+ }
13734+ else
13735+ return false;
13736+ break;
13737+
13738+ case duplicate:
13739+ if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
13740+ return false;
13741+ break;
13742+
13743+ case set_number_at:
13744+ p1 += 2 * OFFSET_ADDRESS_SIZE;
13745+
13746+ default:
13747+ /* All other opcodes mean we cannot match the empty string. */
13748+ return false;
13749+ }
13750+
13751+ *p = p1;
13752+ return true;
13753+} /* common_op_match_null_string_p */
13754+
13755+
13756+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
13757+ bytes; nonzero otherwise. */
13758+
13759+static int
13760+PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, register int len,
13761+ RE_TRANSLATE_TYPE translate)
13762+{
13763+ register const UCHAR_T *p1 = (const UCHAR_T *) s1;
13764+ register const UCHAR_T *p2 = (const UCHAR_T *) s2;
13765+ while (len)
13766+ {
13767+#ifdef WCHAR
13768+ if (((*p1<=0xff)?translate[*p1++]:*p1++)
13769+ != ((*p2<=0xff)?translate[*p2++]:*p2++))
13770+ return 1;
13771+#else /* BYTE */
13772+ if (translate[*p1++] != translate[*p2++]) return 1;
13773+#endif /* WCHAR */
13774+ len--;
13775+ }
13776+ return 0;
13777+}
13778+
13779+
13780+#else /* not INSIDE_RECURSION */
13781+
13782+/* Entry points for GNU code. */
13783+
13784+/* re_compile_pattern is the GNU regular expression compiler: it
13785+ compiles PATTERN (of length SIZE) and puts the result in BUFP.
13786+ Returns 0 if the pattern was valid, otherwise an error string.
13787+
13788+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields
13789+ are set in BUFP on entry.
13790+
13791+ We call regex_compile to do the actual compilation. */
13792+
13793+const char *
13794+re_compile_pattern (const char *pattern, size_t length,
13795+ struct re_pattern_buffer *bufp)
13796+{
13797+ reg_errcode_t ret;
13798+
13799+ /* GNU code is written to assume at least RE_NREGS registers will be set
13800+ (and at least one extra will be -1). */
13801+ bufp->regs_allocated = REGS_UNALLOCATED;
13802+
13803+ /* And GNU code determines whether or not to get register information
13804+ by passing null for the REGS argument to re_match, etc., not by
13805+ setting no_sub. */
13806+ bufp->no_sub = 0;
13807+
13808+ /* Match anchors at newline. */
13809+ bufp->newline_anchor = 1;
13810+
13811+# ifdef MBS_SUPPORT
13812+ if (MB_CUR_MAX != 1)
13813+ ret = wcs_regex_compile (pattern, length, re_syntax_options, bufp);
13814+ else
13815+# endif
13816+ ret = byte_regex_compile (pattern, length, re_syntax_options, bufp);
13817+
13818+ if (!ret)
13819+ return NULL;
13820+ return gettext (re_error_msgid[(int) ret]);
13821+}
13822+#ifdef _LIBC
13823+weak_alias (__re_compile_pattern, re_compile_pattern)
13824+#endif
13825+
13826+/* Entry points compatible with 4.2 BSD regex library. We don't define
13827+ them unless specifically requested. */
13828+
13829+#if defined _REGEX_RE_COMP || defined _LIBC
13830+
13831+/* BSD has one and only one pattern buffer. */
13832+static struct re_pattern_buffer re_comp_buf;
13833+
13834+char *
13835+#ifdef _LIBC
13836+/* Make these definitions weak in libc, so POSIX programs can redefine
13837+ these names if they don't use our functions, and still use
13838+ regcomp/regexec below without link errors. */
13839+weak_function
13840+#endif
13841+re_comp (const char *s)
13842+{
13843+ reg_errcode_t ret;
13844+
13845+ if (!s)
13846+ {
13847+ if (!re_comp_buf.buffer)
13848+ return (char *) gettext ("No previous regular expression");
13849+ return 0;
13850+ }
13851+
13852+ if (!re_comp_buf.buffer)
13853+ {
13854+ re_comp_buf.buffer = (unsigned char *) malloc (200);
13855+ if (re_comp_buf.buffer == NULL)
13856+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
13857+ re_comp_buf.allocated = 200;
13858+
13859+ re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
13860+ if (re_comp_buf.fastmap == NULL)
13861+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
13862+ }
13863+
13864+ /* Since `re_exec' always passes NULL for the `regs' argument, we
13865+ don't need to initialize the pattern buffer fields which affect it. */
13866+
13867+ /* Match anchors at newlines. */
13868+ re_comp_buf.newline_anchor = 1;
13869+
13870+# ifdef MBS_SUPPORT
13871+ if (MB_CUR_MAX != 1)
13872+ ret = wcs_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
13873+ else
13874+# endif
13875+ ret = byte_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
13876+
13877+ if (!ret)
13878+ return NULL;
13879+
13880+ /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */
13881+ return (char *) gettext (re_error_msgid[(int) ret]);
13882+}
13883+
13884+
13885+int
13886+#ifdef _LIBC
13887+weak_function
13888+#endif
13889+re_exec (const char *s)
13890+{
13891+ const int len = strlen (s);
13892+ return
13893+ 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
13894+}
13895+
13896+#endif /* _REGEX_RE_COMP */
13897+
13898+/* POSIX.2 functions. Don't define these for Emacs. */
13899+
13900+#ifndef emacs
13901+
13902+/* regcomp takes a regular expression as a string and compiles it.
13903+
13904+ PREG is a regex_t *. We do not expect any fields to be initialized,
13905+ since POSIX says we shouldn't. Thus, we set
13906+
13907+ `buffer' to the compiled pattern;
13908+ `used' to the length of the compiled pattern;
13909+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
13910+ REG_EXTENDED bit in CFLAGS is set; otherwise, to
13911+ RE_SYNTAX_POSIX_BASIC;
13912+ `newline_anchor' to REG_NEWLINE being set in CFLAGS;
13913+ `fastmap' to an allocated space for the fastmap;
13914+ `fastmap_accurate' to zero;
13915+ `re_nsub' to the number of subexpressions in PATTERN.
13916+
13917+ PATTERN is the address of the pattern string.
13918+
13919+ CFLAGS is a series of bits which affect compilation.
13920+
13921+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
13922+ use POSIX basic syntax.
13923+
13924+ If REG_NEWLINE is set, then . and [^...] don't match newline.
13925+ Also, regexec will try a match beginning after every newline.
13926+
13927+ If REG_ICASE is set, then we considers upper- and lowercase
13928+ versions of letters to be equivalent when matching.
13929+
13930+ If REG_NOSUB is set, then when PREG is passed to regexec, that
13931+ routine will report only success or failure, and nothing about the
13932+ registers.
13933+
13934+ It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
13935+ the return codes and their meanings.) */
13936+
13937+int
13938+regcomp (regex_t *preg, const char *pattern, int cflags)
13939+{
13940+ reg_errcode_t ret;
13941+ reg_syntax_t syntax
13942+ = (cflags & REG_EXTENDED) ?
13943+ RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
13944+
13945+ /* regex_compile will allocate the space for the compiled pattern. */
13946+ preg->buffer = 0;
13947+ preg->allocated = 0;
13948+ preg->used = 0;
13949+
13950+ /* Try to allocate space for the fastmap. */
13951+ preg->fastmap = (char *) malloc (1 << BYTEWIDTH);
13952+
13953+ if (cflags & REG_ICASE)
13954+ {
13955+ int i;
13956+
13957+ preg->translate
13958+ = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
13959+ * sizeof (*(RE_TRANSLATE_TYPE)0));
13960+ if (preg->translate == NULL)
13961+ return (int) REG_ESPACE;
13962+
13963+ /* Map uppercase characters to corresponding lowercase ones. */
13964+ for (i = 0; i < CHAR_SET_SIZE; i++)
13965+ preg->translate[i] = ISUPPER (i) ? TOLOWER (i) : i;
13966+ }
13967+ else
13968+ preg->translate = NULL;
13969+
13970+ /* If REG_NEWLINE is set, newlines are treated differently. */
13971+ if (cflags & REG_NEWLINE)
13972+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */
13973+ syntax &= ~RE_DOT_NEWLINE;
13974+ syntax |= RE_HAT_LISTS_NOT_NEWLINE;
13975+ /* It also changes the matching behavior. */
13976+ preg->newline_anchor = 1;
13977+ }
13978+ else
13979+ preg->newline_anchor = 0;
13980+
13981+ preg->no_sub = !!(cflags & REG_NOSUB);
13982+
13983+ /* POSIX says a null character in the pattern terminates it, so we
13984+ can use strlen here in compiling the pattern. */
13985+# ifdef MBS_SUPPORT
13986+ if (MB_CUR_MAX != 1)
13987+ ret = wcs_regex_compile (pattern, strlen (pattern), syntax, preg);
13988+ else
13989+# endif
13990+ ret = byte_regex_compile (pattern, strlen (pattern), syntax, preg);
13991+
13992+ /* POSIX doesn't distinguish between an unmatched open-group and an
13993+ unmatched close-group: both are REG_EPAREN. */
13994+ if (ret == REG_ERPAREN) ret = REG_EPAREN;
13995+
13996+ if (ret == REG_NOERROR && preg->fastmap)
13997+ {
13998+ /* Compute the fastmap now, since regexec cannot modify the pattern
13999+ buffer. */
14000+ if (re_compile_fastmap (preg) == -2)
14001+ {
14002+ /* Some error occurred while computing the fastmap, just forget
14003+ about it. */
14004+ free (preg->fastmap);
14005+ preg->fastmap = NULL;
14006+ }
14007+ }
14008+
14009+ return (int) ret;
14010+}
14011+#ifdef _LIBC
14012+weak_alias (__regcomp, regcomp)
14013+#endif
14014+
14015+
14016+/* regexec searches for a given pattern, specified by PREG, in the
14017+ string STRING.
14018+
14019+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to
14020+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
14021+ least NMATCH elements, and we set them to the offsets of the
14022+ corresponding matched substrings.
14023+
14024+ EFLAGS specifies `execution flags' which affect matching: if
14025+ REG_NOTBOL is set, then ^ does not match at the beginning of the
14026+ string; if REG_NOTEOL is set, then $ does not match at the end.
14027+
14028+ We return 0 if we find a match and REG_NOMATCH if not. */
14029+
14030+int
14031+regexec (const regex_t *preg, const char *string, size_t nmatch,
14032+ regmatch_t pmatch[], int eflags)
14033+{
14034+ int ret;
14035+ struct re_registers regs;
14036+ regex_t private_preg;
14037+ int len = strlen (string);
14038+ boolean want_reg_info = !preg->no_sub && nmatch > 0;
14039+
14040+ private_preg = *preg;
14041+
14042+ private_preg.not_bol = !!(eflags & REG_NOTBOL);
14043+ private_preg.not_eol = !!(eflags & REG_NOTEOL);
14044+
14045+ /* The user has told us exactly how many registers to return
14046+ information about, via `nmatch'. We have to pass that on to the
14047+ matching routines. */
14048+ private_preg.regs_allocated = REGS_FIXED;
14049+
14050+ if (want_reg_info)
14051+ {
14052+ regs.num_regs = nmatch;
14053+ regs.start = TALLOC (nmatch * 2, regoff_t);
14054+ if (regs.start == NULL)
14055+ return (int) REG_NOMATCH;
14056+ regs.end = regs.start + nmatch;
14057+ }
14058+
14059+ /* Perform the searching operation. */
14060+ ret = re_search (&private_preg, string, len,
14061+ /* start: */ 0, /* range: */ len,
14062+ want_reg_info ? &regs : (struct re_registers *) 0);
14063+
14064+ /* Copy the register information to the POSIX structure. */
14065+ if (want_reg_info)
14066+ {
14067+ if (ret >= 0)
14068+ {
14069+ unsigned r;
14070+
14071+ for (r = 0; r < nmatch; r++)
14072+ {
14073+ pmatch[r].rm_so = regs.start[r];
14074+ pmatch[r].rm_eo = regs.end[r];
14075+ }
14076+ }
14077+
14078+ /* If we needed the temporary register info, free the space now. */
14079+ free (regs.start);
14080+ }
14081+
14082+ /* We want zero return to mean success, unlike `re_search'. */
14083+ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
14084+}
14085+#ifdef _LIBC
14086+/* EGLIBC: This is handled in regexec-compat.c. */
14087+/*weak_alias (__regexec, regexec)*/
14088+#include "regexec-compat.c"
14089+#endif
14090+
14091+
14092+/* Returns a message corresponding to an error code, ERRCODE, returned
14093+ from either regcomp or regexec. We don't use PREG here. */
14094+
14095+size_t
14096+regerror (int errcode, const regex_t *preg __attribute__ ((unused)),
14097+ char *errbuf, size_t errbuf_size)
14098+{
14099+ const char *msg;
14100+ size_t msg_size;
14101+
14102+ if (errcode < 0
14103+ || errcode >= (int) (sizeof (re_error_msgid)
14104+ / sizeof (re_error_msgid[0])))
14105+ /* Only error codes returned by the rest of the code should be passed
14106+ to this routine. If we are given anything else, or if other regex
14107+ code generates an invalid error code, then the program has a bug.
14108+ Dump core so we can fix it. */
14109+ abort ();
14110+
14111+ msg = gettext (re_error_msgid[errcode]);
14112+
14113+ msg_size = strlen (msg) + 1; /* Includes the null. */
14114+
14115+ if (errbuf_size != 0)
14116+ {
14117+ if (msg_size > errbuf_size)
14118+ {
14119+#if defined HAVE_MEMPCPY || defined _LIBC
14120+ *((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
14121+#else
14122+ memcpy (errbuf, msg, errbuf_size - 1);
14123+ errbuf[errbuf_size - 1] = 0;
14124+#endif
14125+ }
14126+ else
14127+ memcpy (errbuf, msg, msg_size);
14128+ }
14129+
14130+ return msg_size;
14131+}
14132+#ifdef _LIBC
14133+weak_alias (__regerror, regerror)
14134+#endif
14135+
14136+
14137+/* Free dynamically allocated space used by PREG. */
14138+
14139+void
14140+regfree (regex_t *preg)
14141+{
14142+ if (preg->buffer != NULL)
14143+ free (preg->buffer);
14144+ preg->buffer = NULL;
14145+
14146+ preg->allocated = 0;
14147+ preg->used = 0;
14148+
14149+ if (preg->fastmap != NULL)
14150+ free (preg->fastmap);
14151+ preg->fastmap = NULL;
14152+ preg->fastmap_accurate = 0;
14153+
14154+ if (preg->translate != NULL)
14155+ free (preg->translate);
14156+ preg->translate = NULL;
14157+}
14158+#ifdef _LIBC
14159+weak_alias (__regfree, regfree)
14160+#endif
14161+
14162+#endif /* not emacs */
14163+
14164+#endif /* not INSIDE_RECURSION */
14165+
14166+
14167+#undef STORE_NUMBER
14168+#undef STORE_NUMBER_AND_INCR
14169+#undef EXTRACT_NUMBER
14170+#undef EXTRACT_NUMBER_AND_INCR
14171+
14172+#undef DEBUG_PRINT_COMPILED_PATTERN
14173+#undef DEBUG_PRINT_DOUBLE_STRING
14174+
14175+#undef INIT_FAIL_STACK
14176+#undef RESET_FAIL_STACK
14177+#undef DOUBLE_FAIL_STACK
14178+#undef PUSH_PATTERN_OP
14179+#undef PUSH_FAILURE_POINTER
14180+#undef PUSH_FAILURE_INT
14181+#undef PUSH_FAILURE_ELT
14182+#undef POP_FAILURE_POINTER
14183+#undef POP_FAILURE_INT
14184+#undef POP_FAILURE_ELT
14185+#undef DEBUG_PUSH
14186+#undef DEBUG_POP
14187+#undef PUSH_FAILURE_POINT
14188+#undef POP_FAILURE_POINT
14189+
14190+#undef REG_UNSET_VALUE
14191+#undef REG_UNSET
14192+
14193+#undef PATFETCH
14194+#undef PATFETCH_RAW
14195+#undef PATUNFETCH
14196+#undef TRANSLATE
14197+
14198+#undef INIT_BUF_SIZE
14199+#undef GET_BUFFER_SPACE
14200+#undef BUF_PUSH
14201+#undef BUF_PUSH_2
14202+#undef BUF_PUSH_3
14203+#undef STORE_JUMP
14204+#undef STORE_JUMP2
14205+#undef INSERT_JUMP
14206+#undef INSERT_JUMP2
14207+#undef EXTEND_BUFFER
14208+#undef GET_UNSIGNED_NUMBER
14209+#undef FREE_STACK_RETURN
14210+
14211+# undef POINTER_TO_OFFSET
14212+# undef MATCHING_IN_FRST_STRING
14213+# undef PREFETCH
14214+# undef AT_STRINGS_BEG
14215+# undef AT_STRINGS_END
14216+# undef WORDCHAR_P
14217+# undef FREE_VAR
14218+# undef FREE_VARIABLES
14219+# undef NO_HIGHEST_ACTIVE_REG
14220+# undef NO_LOWEST_ACTIVE_REG
14221+
14222+# undef CHAR_T
14223+# undef UCHAR_T
14224+# undef COMPILED_BUFFER_VAR
14225+# undef OFFSET_ADDRESS_SIZE
14226+# undef CHAR_CLASS_SIZE
14227+# undef PREFIX
14228+# undef ARG_PREFIX
14229+# undef PUT_CHAR
14230+# undef BYTE
14231+# undef WCHAR
14232+
14233+# define DEFINED_ONCE
14234Index: git/pwd/Makefile
14235===================================================================
14236--- git.orig/pwd/Makefile 2014-08-29 20:00:53.316070587 -0700
14237+++ git/pwd/Makefile 2014-08-29 20:01:15.232070587 -0700
14238@@ -18,6 +18,8 @@
14239 #
14240 # Sub-makefile for pwd portion of the library.
14241 #
14242+include ../option-groups.mak
14243+
14244 subdir := pwd
14245
14246 include ../Makeconfig
14247Index: git/resolv/Makefile
14248===================================================================
14249--- git.orig/resolv/Makefile 2014-08-29 20:00:53.320070587 -0700
14250+++ git/resolv/Makefile 2014-08-29 20:01:15.232070587 -0700
14251@@ -18,6 +18,8 @@
14252 #
14253 # Sub-makefile for resolv portion of the library.
14254 #
14255+include ../option-groups.mak
14256+
14257 subdir := resolv
14258
14259 include ../Makeconfig
14260@@ -27,20 +29,21 @@
14261 arpa/nameser.h arpa/nameser_compat.h \
14262 sys/bitypes.h
14263
14264-routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
14265- res_hconf res_libc res-state
14266+routines-$(OPTION_EGLIBC_INET) \
14267+ += herror inet_addr inet_ntop inet_pton nsap_addr res_init \
14268+ res_hconf res_libc res-state
14269
14270-tests = tst-aton tst-leaks tst-inet_ntop
14271-xtests = tst-leaks2
14272+tests-$(OPTION_EGLIBC_INET) += tst-aton tst-leaks tst-inet_ntop
14273+xtests-$(OPTION_EGLIBC_INET) += tst-leaks2
14274
14275 generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
14276
14277-extra-libs := libresolv libnss_dns
14278+extra-libs-$(OPTION_EGLIBC_INET) += libresolv libnss_dns
14279 ifeq ($(have-thread-library),yes)
14280-extra-libs += libanl
14281-routines += gai_sigqueue
14282+extra-libs-$(OPTION_EGLIBC_INET_ANL) += libanl
14283+routines-$(OPTION_EGLIBC_INET) += gai_sigqueue
14284 endif
14285-extra-libs-others = $(extra-libs)
14286+extra-libs-others-y += $(extra-libs-y)
14287 libresolv-routines := gethnamaddr res_comp res_debug \
14288 res_data res_mkquery res_query res_send \
14289 inet_net_ntop inet_net_pton inet_neta base64 \
14290@@ -60,7 +63,7 @@
14291 static-only-routines += $(libnss_dns-routines) $(libresolv-routines)
14292 endif
14293
14294-ifeq (yesyes,$(build-shared)$(have-thread-library))
14295+ifeq (yesyesy,$(build-shared)$(have-thread-library)$(OPTION_EGLIBC_INET_ANL))
14296 tests: $(objpfx)ga_test
14297 endif
14298
14299Index: git/stdio-common/fxprintf.c
14300===================================================================
14301--- git.orig/stdio-common/fxprintf.c 2014-08-29 20:00:53.544070587 -0700
14302+++ git/stdio-common/fxprintf.c 2014-08-29 20:01:15.232070587 -0700
14303@@ -23,6 +23,7 @@
14304 #include <wchar.h>
14305 #include <string.h>
14306 #include <libioP.h>
14307+#include <gnu/option-groups.h>
14308
14309
14310 int
14311@@ -37,6 +38,7 @@
14312 int res;
14313 if (_IO_fwide (fp, 0) > 0)
14314 {
14315+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
14316 size_t len = strlen (fmt) + 1;
14317 wchar_t wfmt[len];
14318 for (size_t i = 0; i < len; ++i)
14319@@ -45,6 +47,9 @@
14320 wfmt[i] = fmt[i];
14321 }
14322 res = __vfwprintf (fp, wfmt, ap);
14323+#else
14324+ abort();
14325+#endif
14326 }
14327 else
14328 res = _IO_vfprintf (fp, fmt, ap);
14329Index: git/stdio-common/_i18n_number.h
14330===================================================================
14331--- git.orig/stdio-common/_i18n_number.h 2014-08-29 20:00:53.500070587 -0700
14332+++ git/stdio-common/_i18n_number.h 2014-08-29 20:01:15.232070587 -0700
14333@@ -19,10 +19,13 @@
14334 #include <stdbool.h>
14335 #include <wchar.h>
14336 #include <wctype.h>
14337+#include <gnu/option-groups.h>
14338
14339 #include "../locale/outdigits.h"
14340 #include "../locale/outdigitswc.h"
14341
14342+#if __OPTION_EGLIBC_LOCALE_CODE
14343+
14344 static CHAR_T *
14345 _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
14346 {
14347@@ -115,3 +118,13 @@
14348
14349 return w;
14350 }
14351+
14352+#else
14353+
14354+static CHAR_T *
14355+_i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
14356+{
14357+ return w;
14358+}
14359+
14360+#endif
14361Index: git/stdio-common/Makefile
14362===================================================================
14363--- git.orig/stdio-common/Makefile 2014-08-29 20:00:53.500070587 -0700
14364+++ git/stdio-common/Makefile 2014-08-29 20:01:15.232070587 -0700
14365@@ -18,6 +18,8 @@
14366 #
14367 # Specific makefile for stdio-common.
14368 #
14369+include ../option-groups.mak
14370+
14371 subdir := stdio-common
14372
14373 include ../Makeconfig
14374@@ -30,7 +32,7 @@
14375 vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex \
14376 reg-modifier reg-type \
14377 printf_size fprintf printf snprintf sprintf asprintf dprintf \
14378- vfwprintf vfscanf vfwscanf \
14379+ vfscanf \
14380 fscanf scanf sscanf \
14381 perror psignal \
14382 tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \
14383@@ -41,23 +43,37 @@
14384 isoc99_vsscanf \
14385 psiginfo
14386
14387-aux := errlist siglist printf-parsemb printf-parsewc fxprintf
14388+# Ideally, _itowa and itowa-digits would be in this option group as
14389+# well, but it is used unconditionally by printf_fp and printf_fphex,
14390+# and it didn't seem straightforward to disentangle it.
14391+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += \
14392+ vfwprintf vfwscanf
14393+
14394+aux := errlist siglist printf-parsemb fxprintf
14395+aux-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += printf-parsewc
14396
14397 tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
14398 temptest tst-fileno test-fwrite tst-ungetc tst-ferror \
14399 xbug errnobug \
14400 bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \
14401- tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \
14402+ tfformat tiformat tllformat tstdiomisc tst-printfsz \
14403 scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \
14404- scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \
14405- tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
14406- tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \
14407+ scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \
14408+ scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \
14409+ tst-fseek tst-fmemopen tst-gets \
14410+ tst-sprintf tst-rndseek tst-fdopen tst-fphex \
14411 tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
14412- tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
14413- bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
14414- scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
14415- bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \
14416- bug25 tst-printf-round bug26
14417+ tst-fwrite bug16 bug17 tst-sprintf2 bug18 \
14418+ bug19 tst-popen2 scanf14 scanf15 bug21 bug22 scanf16 scanf17 \
14419+ tst-setvbuf1 bug23 bug24 bug-vfprintf-nargs tst-sprintf3 bug25 \
14420+ tst-printf-round bug26
14421+
14422+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
14423+ += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping
14424+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
14425+ += tst-perror bug19a bug20 tst-long-dbl-fphex tst-fphex-wide
14426+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
14427+ += bug18a tst-swscanf tst-wc-printf
14428
14429 test-srcs = tst-unbputc tst-printf
14430
14431Index: git/stdio-common/printf_fp.c
14432===================================================================
14433--- git.orig/stdio-common/printf_fp.c 2014-08-29 20:00:53.548070587 -0700
14434+++ git/stdio-common/printf_fp.c 2014-08-29 20:01:15.232070587 -0700
14435@@ -39,6 +39,7 @@
14436 #include <unistd.h>
14437 #include <stdlib.h>
14438 #include <wchar.h>
14439+#include <gnu/option-groups.h>
14440 #include <stdbool.h>
14441 #include <rounding-mode.h>
14442
14443@@ -148,6 +149,10 @@
14444 wchar_t thousands_sep, int ngroups)
14445 internal_function;
14446
14447+/* Ideally, when OPTION_EGLIBC_LOCALE_CODE is disabled, this should do
14448+ all its work in ordinary characters, rather than doing it in wide
14449+ characters and then converting at the end. But that is a challenge
14450+ for another day. */
14451
14452 int
14453 ___printf_fp (FILE *fp,
14454@@ -206,7 +211,14 @@
14455 mp_limb_t cy;
14456
14457 /* Nonzero if this is output on a wide character stream. */
14458+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14459 int wide = info->wide;
14460+#else
14461+ /* This should never be called on a wide-oriented stream when
14462+ OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
14463+ be trusted to figure that out. */
14464+ const int wide = 0;
14465+#endif
14466
14467 /* Buffer in which we produce the output. */
14468 wchar_t *wbuffer = NULL;
14469@@ -258,6 +270,7 @@
14470
14471
14472 /* Figure out the decimal point character. */
14473+#if __OPTION_EGLIBC_LOCALE_CODE
14474 if (info->extra == 0)
14475 {
14476 decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
14477@@ -277,7 +290,13 @@
14478 /* The decimal point character must not be zero. */
14479 assert (*decimal != '\0');
14480 assert (decimalwc != L'\0');
14481+#else
14482+ /* Hard-code values from 'C' locale. */
14483+ decimal = ".";
14484+ decimalwc = L'.';
14485+#endif
14486
14487+#if __OPTION_EGLIBC_LOCALE_CODE
14488 if (info->group)
14489 {
14490 if (info->extra == 0)
14491@@ -321,6 +340,9 @@
14492 }
14493 else
14494 grouping = NULL;
14495+#else
14496+ grouping = NULL;
14497+#endif
14498
14499 /* Fetch the argument value. */
14500 #ifndef __NO_LONG_DOUBLE_MATH
14501Index: git/stdio-common/printf_fphex.c
14502===================================================================
14503--- git.orig/stdio-common/printf_fphex.c 2014-08-29 20:00:53.548070587 -0700
14504+++ git/stdio-common/printf_fphex.c 2014-08-29 20:01:15.232070587 -0700
14505@@ -28,6 +28,7 @@
14506 #include <_itoa.h>
14507 #include <_itowa.h>
14508 #include <locale/localeinfo.h>
14509+#include <gnu/option-groups.h>
14510 #include <stdbool.h>
14511 #include <rounding-mode.h>
14512
14513@@ -139,10 +140,18 @@
14514 int done = 0;
14515
14516 /* Nonzero if this is output on a wide character stream. */
14517+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14518 int wide = info->wide;
14519+#else
14520+ /* This should never be called on a wide-oriented stream when
14521+ OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
14522+ be trusted to figure that out. */
14523+ const int wide = 0;
14524+#endif
14525
14526
14527 /* Figure out the decimal point character. */
14528+#if __OPTION_EGLIBC_LOCALE_CODE
14529 if (info->extra == 0)
14530 {
14531 decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
14532@@ -156,6 +165,10 @@
14533 }
14534 /* The decimal point character must never be zero. */
14535 assert (*decimal != '\0' && decimalwc != L'\0');
14536+#else
14537+ decimal = ".";
14538+ decimalwc = L'.';
14539+#endif
14540
14541
14542 /* Fetch the argument value. */
14543Index: git/stdio-common/printf_size.c
14544===================================================================
14545--- git.orig/stdio-common/printf_size.c 2014-08-29 20:00:53.548070587 -0700
14546+++ git/stdio-common/printf_size.c 2014-08-29 20:01:15.232070587 -0700
14547@@ -23,6 +23,7 @@
14548 #include <math.h>
14549 #include <printf.h>
14550 #include <libioP.h>
14551+#include <gnu/option-groups.h>
14552
14553
14554 /* This defines make it possible to use the same code for GNU C library and
14555@@ -116,7 +117,14 @@
14556
14557 struct printf_info fp_info;
14558 int done = 0;
14559+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14560 int wide = info->wide;
14561+#else
14562+ /* This should never be called on a wide-oriented stream when
14563+ OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
14564+ be trusted to figure that out. */
14565+ const int wide = 0;
14566+#endif
14567 int res;
14568
14569 /* Fetch the argument value. */
14570Index: git/stdio-common/scanf14.c
14571===================================================================
14572--- git.orig/stdio-common/scanf14.c 2014-08-29 20:00:53.548070587 -0700
14573+++ git/stdio-common/scanf14.c 2014-08-29 20:01:15.232070587 -0700
14574@@ -2,6 +2,7 @@
14575 #include <stdlib.h>
14576 #include <string.h>
14577 #include <wchar.h>
14578+#include <gnu/option-groups.h>
14579
14580 #define FAIL() \
14581 do { \
14582@@ -36,6 +37,7 @@
14583 FAIL ();
14584 else if (d != 2.25 || memcmp (c, " x", 2) != 0)
14585 FAIL ();
14586+#if __OPTION_EGLIBC_LOCALE_CODE
14587 if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2)
14588 FAIL ();
14589 else
14590@@ -45,6 +47,7 @@
14591 memset (lsp, 'x', sizeof L"3.25");
14592 free (lsp);
14593 }
14594+#endif
14595 if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2)
14596 FAIL ();
14597 else
14598Index: git/stdio-common/tstdiomisc.c
14599===================================================================
14600--- git.orig/stdio-common/tstdiomisc.c 2014-08-29 20:00:53.584070587 -0700
14601+++ git/stdio-common/tstdiomisc.c 2014-08-29 20:01:15.232070587 -0700
14602@@ -3,6 +3,7 @@
14603 #include <stdio.h>
14604 #include <string.h>
14605 #include <wchar.h>
14606+#include <gnu/option-groups.h>
14607
14608 static int
14609 t1 (void)
14610@@ -125,6 +126,7 @@
14611 printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
14612 buf);
14613
14614+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14615 swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G",
14616 qnanval, qnanval, qnanval, qnanval,
14617 qnanval, qnanval, qnanval, qnanval);
14618@@ -162,6 +164,7 @@
14619 result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
14620 printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
14621 wbuf);
14622+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
14623
14624 lqnanval = NAN;
14625
14626@@ -206,6 +209,7 @@
14627 printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
14628 buf);
14629
14630+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14631 swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]),
14632 L"%La %LA %Le %LE %Lf %LF %Lg %LG",
14633 lqnanval, lqnanval, lqnanval, lqnanval,
14634@@ -250,6 +254,7 @@
14635 result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
14636 printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
14637 wbuf);
14638+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
14639
14640 return result;
14641 }
14642Index: git/stdio-common/tst-popen.c
14643===================================================================
14644--- git.orig/stdio-common/tst-popen.c 2014-08-29 20:00:53.576070587 -0700
14645+++ git/stdio-common/tst-popen.c 2014-08-29 20:01:15.232070587 -0700
14646@@ -19,6 +19,7 @@
14647 #include <stdio.h>
14648 #include <string.h>
14649 #include <wchar.h>
14650+#include <gnu/option-groups.h>
14651
14652 static int
14653 do_test (void)
14654@@ -34,12 +35,14 @@
14655 return 1;
14656 }
14657
14658+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
14659 /* POSIX says that pipe streams are byte-oriented. */
14660 if (fwide (f, 0) >= 0)
14661 {
14662 puts ("popen did not return byte-oriented stream");
14663 result = 1;
14664 }
14665+#endif
14666
14667 if (getline (&line, &len, f) != 5)
14668 {
14669Index: git/stdio-common/tst-sprintf.c
14670===================================================================
14671--- git.orig/stdio-common/tst-sprintf.c 2014-08-29 20:00:53.580070587 -0700
14672+++ git/stdio-common/tst-sprintf.c 2014-08-29 20:01:15.236070587 -0700
14673@@ -2,6 +2,7 @@
14674 #include <stdlib.h>
14675 #include <locale.h>
14676 #include <string.h>
14677+#include <gnu/option-groups.h>
14678
14679
14680 int
14681@@ -10,12 +11,14 @@
14682 char buf[100];
14683 int result = 0;
14684
14685+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14686 if (sprintf (buf, "%.0ls", L"foo") != 0
14687 || strlen (buf) != 0)
14688 {
14689 puts ("sprintf (buf, \"%.0ls\", L\"foo\") produced some output");
14690 result = 1;
14691 }
14692+#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
14693
14694 #define SIZE (1024*70000)
14695 #define STR(x) #x
14696Index: git/stdio-common/vfprintf.c
14697===================================================================
14698--- git.orig/stdio-common/vfprintf.c 2014-08-29 20:00:53.588070587 -0700
14699+++ git/stdio-common/vfprintf.c 2014-08-29 20:01:15.236070587 -0700
14700@@ -29,6 +29,7 @@
14701 #include <_itoa.h>
14702 #include <locale/localeinfo.h>
14703 #include <stdio.h>
14704+#include <gnu/option-groups.h>
14705
14706 /* This code is shared between the standard stdio implementation found
14707 in GNU C library and the libio implementation originally found in
14708@@ -138,6 +139,18 @@
14709 # define EOF WEOF
14710 #endif
14711
14712+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14713+# define MULTIBYTE_SUPPORT (1)
14714+#else
14715+# define MULTIBYTE_SUPPORT (0)
14716+#endif
14717+
14718+#if __OPTION_EGLIBC_LOCALE_CODE
14719+# define LOCALE_SUPPORT (1)
14720+#else
14721+# define LOCALE_SUPPORT (0)
14722+#endif
14723+
14724 #include "_i18n_number.h"
14725
14726 /* Include the shared code for parsing the format string. */
14727@@ -1123,8 +1136,11 @@
14728 # define process_string_arg(fspec) \
14729 LABEL (form_character): \
14730 /* Character. */ \
14731- if (is_long) \
14732- goto LABEL (form_wcharacter); \
14733+ if (is_long) \
14734+ { \
14735+ assert (MULTIBYTE_SUPPORT); \
14736+ goto LABEL (form_wcharacter); \
14737+ } \
14738 --width; /* Account for the character itself. */ \
14739 if (!left) \
14740 PAD (' '); \
14741@@ -1137,6 +1153,7 @@
14742 break; \
14743 \
14744 LABEL (form_wcharacter): \
14745+ assert (MULTIBYTE_SUPPORT); \
14746 { \
14747 /* Wide character. */ \
14748 char buf[MB_CUR_MAX]; \
14749@@ -1203,6 +1220,7 @@
14750 } \
14751 else \
14752 { \
14753+ assert (MULTIBYTE_SUPPORT); \
14754 const wchar_t *s2 = (const wchar_t *) string; \
14755 mbstate_t mbstate; \
14756 \
14757@@ -1403,7 +1421,9 @@
14758 LABEL (flag_quote):
14759 group = 1;
14760
14761- if (grouping == (const char *) -1)
14762+ if (! LOCALE_SUPPORT)
14763+ grouping = NULL;
14764+ else if (grouping == (const char *) -1)
14765 {
14766 #ifdef COMPILE_WPRINTF
14767 thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
14768@@ -1702,7 +1722,9 @@
14769 free (workstart);
14770 workstart = NULL;
14771
14772- if (grouping == (const char *) -1)
14773+ if (! LOCALE_SUPPORT)
14774+ grouping = NULL;
14775+ else if (grouping == (const char *) -1)
14776 {
14777 #ifdef COMPILE_WPRINTF
14778 thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
14779Index: git/stdio-common/vfscanf.c
14780===================================================================
14781--- git.orig/stdio-common/vfscanf.c 2014-08-29 20:00:53.588070587 -0700
14782+++ git/stdio-common/vfscanf.c 2014-08-29 20:01:15.236070587 -0700
14783@@ -29,6 +29,7 @@
14784 #include <wctype.h>
14785 #include <bits/libc-lock.h>
14786 #include <locale/localeinfo.h>
14787+#include <gnu/option-groups.h>
14788
14789 #ifdef __GNUC__
14790 # define HAVE_LONGLONG
14791@@ -133,6 +134,12 @@
14792 # define WINT_T int
14793 #endif
14794
14795+#if __OPTION_POSIX_C_LANG_WIDE_CHAR
14796+# define MULTIBYTE_SUPPORT (1)
14797+#else
14798+# define MULTIBYTE_SUPPORT (0)
14799+#endif
14800+
14801 #define encode_error() do { \
14802 errval = 4; \
14803 __set_errno (EILSEQ); \
14804@@ -316,24 +323,35 @@
14805 ARGCHECK (s, format);
14806
14807 {
14808-#ifndef COMPILE_WSCANF
14809+#if __OPTION_EGLIBC_LOCALE_CODE && !defined (COMPILE_WSCANF)
14810 struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
14811 #endif
14812
14813+#if __OPTION_EGLIBC_LOCALE_CODE
14814 /* Figure out the decimal point character. */
14815-#ifdef COMPILE_WSCANF
14816+# ifdef COMPILE_WSCANF
14817 decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
14818-#else
14819+# else
14820 decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
14821-#endif
14822+# endif
14823 /* Figure out the thousands separator character. */
14824-#ifdef COMPILE_WSCANF
14825+# ifdef COMPILE_WSCANF
14826 thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
14827-#else
14828+# else
14829 thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
14830 if (*thousands == '\0')
14831 thousands = NULL;
14832-#endif
14833+# endif
14834+#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
14835+ /* Hard-code values from the C locale. */
14836+# ifdef COMPILE_WSCANF
14837+ decimal = L'.';
14838+ thousands = L'\0';
14839+# else
14840+ decimal = ".";
14841+ thousands = NULL;
14842+# endif
14843+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
14844 }
14845
14846 /* Lock the stream. */
14847@@ -385,6 +403,8 @@
14848 #ifndef COMPILE_WSCANF
14849 if (!isascii ((unsigned char) *f))
14850 {
14851+ assert (MULTIBYTE_SUPPORT);
14852+
14853 /* Non-ASCII, may be a multibyte. */
14854 int len = __mbrlen (f, strlen (f), &state);
14855 if (len > 0)
14856@@ -830,6 +850,8 @@
14857 }
14858 /* FALLTHROUGH */
14859 case L_('C'):
14860+ assert (MULTIBYTE_SUPPORT);
14861+
14862 if (width == -1)
14863 width = 1;
14864
14865@@ -1172,6 +1194,8 @@
14866 /* FALLTHROUGH */
14867
14868 case L_('S'):
14869+ assert (MULTIBYTE_SUPPORT);
14870+
14871 {
14872 #ifndef COMPILE_WSCANF
14873 mbstate_t cstate;
14874@@ -1419,10 +1443,17 @@
14875 const char *mbdigits[10];
14876 const char *mbdigits_extended[10];
14877 #endif
14878+#if __OPTION_EGLIBC_LOCALE_CODE
14879 /* "to_inpunct" is a map from ASCII digits to their
14880 equivalent in locale. This is defined for locales
14881 which use an extra digits set. */
14882 wctrans_t map = __wctrans ("to_inpunct");
14883+#else
14884+ /* This will always be the case when
14885+ OPTION_EGLIBC_LOCALE_CODE is disabled, but the
14886+ compiler can't figure that out. */
14887+ wctrans_t map = NULL;
14888+#endif
14889 int n;
14890
14891 from_level = 0;
14892@@ -2088,6 +2119,7 @@
14893 --width;
14894 }
14895
14896+#if __OPTION_EGLIBC_LOCALE_CODE
14897 wctrans_t map;
14898 if (__builtin_expect ((flags & I18N) != 0, 0)
14899 /* Hexadecimal floats make no sense, fixing localized
14900@@ -2304,6 +2336,7 @@
14901 ;
14902 #endif
14903 }
14904+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
14905
14906 /* Have we read any character? If we try to read a number
14907 in hexadecimal notation and we have read only the `0x'
14908@@ -2343,7 +2376,10 @@
14909
14910 case L_('['): /* Character class. */
14911 if (flags & LONG)
14912- STRING_ARG (wstr, wchar_t, 100);
14913+ {
14914+ assert (MULTIBYTE_SUPPORT);
14915+ STRING_ARG (wstr, wchar_t, 100);
14916+ }
14917 else
14918 STRING_ARG (str, char, 100);
14919
14920@@ -2417,6 +2453,7 @@
14921 if (flags & LONG)
14922 {
14923 size_t now = read_in;
14924+ assert (MULTIBYTE_SUPPORT);
14925 #ifdef COMPILE_WSCANF
14926 if (__glibc_unlikely (inchar () == WEOF))
14927 input_error ();
14928Index: git/stdlib/Makefile
14929===================================================================
14930--- git.orig/stdlib/Makefile 2014-08-29 20:00:53.588070587 -0700
14931+++ git/stdlib/Makefile 2014-08-29 20:01:15.236070587 -0700
14932@@ -18,6 +18,8 @@
14933 #
14934 # Makefile for stdlib routines
14935 #
14936+include ../option-groups.mak
14937+
14938 subdir := stdlib
14939
14940 include ../Makeconfig
14941@@ -30,7 +32,7 @@
14942 alloca.h fmtmsg.h \
14943 bits/stdlib-bsearch.h
14944
14945-routines := \
14946+routines-y := \
14947 atof atoi atol atoll \
14948 abort \
14949 bsearch qsort msort \
14950@@ -39,7 +41,6 @@
14951 quick_exit at_quick_exit cxa_at_quick_exit cxa_thread_atexit_impl \
14952 abs labs llabs \
14953 div ldiv lldiv \
14954- mblen mbstowcs mbtowc wcstombs wctomb \
14955 random random_r rand rand_r \
14956 drand48 erand48 lrand48 nrand48 mrand48 jrand48 \
14957 srand48 seed48 lcong48 \
14958@@ -52,9 +53,18 @@
14959 strtof_l strtod_l strtold_l \
14960 system canonicalize \
14961 a64l l64a \
14962- rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg \
14963- strtoimax strtoumax wcstoimax wcstoumax \
14964+ getsubopt xpg_basename \
14965+ strtoimax strtoumax \
14966 getcontext setcontext makecontext swapcontext
14967+routines-$(OPTION_EGLIBC_LOCALE_CODE) += \
14968+ strfmon strfmon_l
14969+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += \
14970+ mblen mbstowcs mbtowc wcstombs wctomb \
14971+ wcstoimax wcstoumax
14972+ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP))
14973+routines-y += rpmatch
14974+endif
14975+routines-$(OPTION_EGLIBC_FMTMSG) += fmtmsg
14976 aux = grouping groupingwc tens_in_limb
14977
14978 # These routines will be omitted from the libc shared object.
14979@@ -62,20 +72,22 @@
14980 # linked against when the shared library will be used.
14981 static-only-routines = atexit at_quick_exit
14982
14983-test-srcs := tst-fmtmsg
14984-tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
14985+test-srcs-$(OPTION_EGLIBC_FMTMSG) := tst-fmtmsg
14986+tests := tst-strtol tst-strtod testrand testsort testdiv \
14987 test-canon test-canon2 tst-strtoll tst-environ \
14988 tst-xpg-basename tst-random tst-random2 tst-bsearch \
14989 tst-limits tst-rand48 bug-strtod tst-setcontext \
14990- test-a64l tst-qsort tst-system testmb2 bug-strtod2 \
14991- tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
14992- tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \
14993- tst-makecontext2 tst-strtod6 tst-unsetenv1 \
14994- tst-makecontext3 bug-getcontext bug-fmtmsg1 \
14995+ test-a64l tst-qsort tst-system bug-strtod2 \
14996+ tst-atof1 tst-atof2 tst-strtod2 tst-rand48-2 \
14997+ tst-makecontext tst-qsort2 tst-makecontext2 tst-strtod6 \
14998+ tst-unsetenv1 tst-makecontext3 bug-getcontext bug-fmtmsg1 \
14999 tst-secure-getenv tst-strtod-overflow tst-strtod-round \
15000 tst-tininess tst-strtod-underflow tst-tls-atexit
15001 tests-static := tst-secure-getenv
15002-
15003+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
15004+ += tst-strtod3 tst-strtod4 tst-strtod5 testmb2
15005+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
15006+ += testmb
15007 modules-names = tst-tls-atexit-lib
15008
15009 ifeq ($(build-shared),yes)
15010@@ -115,8 +127,10 @@
15011 tests-special += $(objpfx)isomac.out
15012
15013 ifeq ($(run-built-tests),yes)
15014+ifeq (y,$(OPTION_EGLIBC_FMTMSG))
15015 tests-special += $(objpfx)tst-fmtmsg.out
15016 endif
15017+endif
15018
15019 include ../Rules
15020
15021Index: git/stdlib/strtod_l.c
15022===================================================================
15023--- git.orig/stdlib/strtod_l.c 2014-08-29 20:00:53.648070587 -0700
15024+++ git/stdlib/strtod_l.c 2014-08-29 20:01:15.236070587 -0700
15025@@ -17,6 +17,7 @@
15026 License along with the GNU C Library; if not, see
15027 <http://www.gnu.org/licenses/>. */
15028
15029+#include <gnu/option-groups.h>
15030 #include <xlocale.h>
15031
15032 extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
15033@@ -548,6 +549,7 @@
15034 /* Used in several places. */
15035 int cnt;
15036
15037+#if __OPTION_EGLIBC_LOCALE_CODE
15038 struct __locale_data *current = loc->__locales[LC_NUMERIC];
15039
15040 if (__glibc_unlikely (group))
15041@@ -586,6 +588,17 @@
15042 decimal_len = strlen (decimal);
15043 assert (decimal_len > 0);
15044 #endif
15045+#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
15046+ /* Hard-code values from the 'C' locale. */
15047+ grouping = NULL;
15048+#ifdef USE_WIDE_CHAR
15049+ decimal = L'.';
15050+# define decimal_len 1
15051+#else
15052+ decimal = ".";
15053+ decimal_len = 1;
15054+#endif
15055+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
15056
15057 /* Prepare number representation. */
15058 exponent = 0;
15059Index: git/stdlib/tst-strtod.c
15060===================================================================
15061--- git.orig/stdlib/tst-strtod.c 2014-08-29 20:00:53.700070587 -0700
15062+++ git/stdlib/tst-strtod.c 2014-08-29 20:01:15.236070587 -0700
15063@@ -23,6 +23,7 @@
15064 #include <errno.h>
15065 #include <string.h>
15066 #include <math.h>
15067+#include <gnu/option-groups.h>
15068
15069 struct ltest
15070 {
15071@@ -176,7 +177,9 @@
15072
15073 status |= long_dbl ();
15074
15075+#if __OPTION_EGLIBC_LOCALE_CODE
15076 status |= locale_test ();
15077+#endif
15078
15079 return status ? EXIT_FAILURE : EXIT_SUCCESS;
15080 }
15081@@ -219,6 +222,7 @@
15082 return 0;
15083 }
15084
15085+#if __OPTION_EGLIBC_LOCALE_CODE
15086 /* Perform a few tests in a locale with thousands separators. */
15087 static int
15088 locale_test (void)
15089@@ -276,3 +280,4 @@
15090
15091 return result;
15092 }
15093+#endif /* __OPTION_EGLIBC_LOCALE_CODE */
15094Index: git/streams/Makefile
15095===================================================================
15096--- git.orig/streams/Makefile 2014-08-29 20:00:53.712070587 -0700
15097+++ git/streams/Makefile 2014-08-29 20:01:15.236070587 -0700
15098@@ -18,11 +18,14 @@
15099 #
15100 # Makefile for streams.
15101 #
15102+include ../option-groups.mak
15103+
15104 subdir := streams
15105
15106 include ../Makeconfig
15107
15108 headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
15109-routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach
15110+routines-$(OPTION_EGLIBC_STREAMS) \
15111+ += isastream getmsg getpmsg putmsg putpmsg fattach fdetach
15112
15113 include ../Rules
15114Index: git/string/Makefile
15115===================================================================
15116--- git.orig/string/Makefile 2014-08-29 20:00:53.716070587 -0700
15117+++ git/string/Makefile 2014-08-29 20:01:15.236070587 -0700
15118@@ -18,6 +18,8 @@
15119 #
15120 # Sub-makefile for string portion of library.
15121 #
15122+include ../option-groups.mak
15123+
15124 subdir := string
15125
15126 include ../Makeconfig
15127@@ -39,10 +41,12 @@
15128 $(addprefix argz-,append count create ctsep next \
15129 delete extract insert stringify \
15130 addsep replace) \
15131- envz basename \
15132+ basename \
15133 strcoll_l strxfrm_l string-inlines memrchr \
15134 xpg-strerror strerror_l
15135
15136+routines-$(OPTION_EGLIBC_ENVZ) += envz
15137+
15138 strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \
15139 stpcpy stpncpy strcat strchr strcmp strcpy strcspn \
15140 strlen strncmp strncpy strpbrk strrchr strspn memmem \
15141@@ -51,10 +55,12 @@
15142 tests := tester inl-tester noinl-tester testcopy test-ffs \
15143 tst-strlen stratcliff tst-svc tst-inlcall \
15144 bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \
15145- tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \
15146+ tst-strtok tst-strfry \
15147 bug-strtok1 $(addprefix test-,$(strop-tests)) \
15148- bug-envz1 tst-strxfrm2 tst-endian tst-svc2 \
15149- tst-strtok_r
15150+ tst-strxfrm2 tst-endian tst-svc2 tst-strtok_r
15151+tests-$(OPTION_EGLIBC_ENVZ) += bug-envz1
15152+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
15153+ += tst-strxfrm bug-strcoll1
15154
15155 xtests = tst-strcoll-overflow
15156
15157Index: git/string/strcoll_l.c
15158===================================================================
15159--- git.orig/string/strcoll_l.c 2014-08-29 20:00:53.744070587 -0700
15160+++ git/string/strcoll_l.c 2014-08-29 20:01:15.240070587 -0700
15161@@ -25,6 +25,7 @@
15162 #include <stdlib.h>
15163 #include <string.h>
15164 #include <sys/param.h>
15165+#include <gnu/option-groups.h>
15166
15167 #ifndef STRING_TYPE
15168 # define STRING_TYPE char
15169@@ -472,7 +473,11 @@
15170 STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
15171 {
15172 struct __locale_data *current = l->__locales[LC_COLLATE];
15173+#if __OPTION_EGLIBC_LOCALE_CODE
15174 uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
15175+#else
15176+ const uint_fast32_t nrules = 0;
15177+#endif
15178 /* We don't assign the following values right away since it might be
15179 unnecessary in case there are no rules. */
15180 const unsigned char *rulesets;
15181Index: git/string/strerror_l.c
15182===================================================================
15183--- git.orig/string/strerror_l.c 2014-08-29 20:00:53.744070587 -0700
15184+++ git/string/strerror_l.c 2014-08-29 20:01:15.240070587 -0700
15185@@ -21,6 +21,7 @@
15186 #include <stdlib.h>
15187 #include <string.h>
15188 #include <sys/param.h>
15189+#include <gnu/option-groups.h>
15190
15191
15192 static __thread char *last_value;
15193@@ -29,10 +30,14 @@
15194 static const char *
15195 translate (const char *str, locale_t loc)
15196 {
15197+#if __OPTION_EGLIBC_LOCALE_CODE
15198 locale_t oldloc = __uselocale (loc);
15199 const char *res = _(str);
15200 __uselocale (oldloc);
15201 return res;
15202+#else
15203+ return str;
15204+#endif
15205 }
15206
15207
15208Index: git/string/strxfrm_l.c
15209===================================================================
15210--- git.orig/string/strxfrm_l.c 2014-08-29 20:00:53.748070587 -0700
15211+++ git/string/strxfrm_l.c 2014-08-29 20:01:15.240070587 -0700
15212@@ -24,6 +24,7 @@
15213 #include <stdlib.h>
15214 #include <string.h>
15215 #include <sys/param.h>
15216+#include <gnu/option-groups.h>
15217
15218 #ifndef STRING_TYPE
15219 # define STRING_TYPE char
15220@@ -85,7 +86,11 @@
15221 STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
15222 {
15223 struct __locale_data *current = l->__locales[LC_COLLATE];
15224+#if __OPTION_EGLIBC_LOCALE_CODE
15225 uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
15226+#else
15227+ const uint_fast32_t nrules = 0;
15228+#endif
15229 /* We don't assign the following values right away since it might be
15230 unnecessary in case there are no rules. */
15231 const unsigned char *rulesets;
15232Index: git/string/test-strcmp.c
15233===================================================================
15234--- git.orig/string/test-strcmp.c 2014-08-29 20:00:53.752070587 -0700
15235+++ git/string/test-strcmp.c 2014-08-29 20:01:15.240070587 -0700
15236@@ -329,34 +329,6 @@
15237 FOR_EACH_IMPL (impl, 0)
15238 check_result (impl, s1 + i1, s2 + i2, exp_result);
15239 }
15240-
15241- /* Test cases where there are multiple zero bytes after the first. */
15242-
15243- for (size_t i = 0; i < 16 + 1; i++)
15244- {
15245- s1[i] = 0x00;
15246- s2[i] = 0x00;
15247- }
15248-
15249- for (size_t i = 0; i < 16; i++)
15250- {
15251- int exp_result;
15252-
15253- for (int val = 0x01; val < 0x100; val++)
15254- {
15255- for (size_t j = 0; j < i; j++)
15256- {
15257- s1[j] = val;
15258- s2[j] = val;
15259- }
15260-
15261- s2[i] = val;
15262-
15263- exp_result = SIMPLE_STRCMP (s1, s2);
15264- FOR_EACH_IMPL (impl, 0)
15265- check_result (impl, s1, s2, exp_result);
15266- }
15267- }
15268 }
15269
15270
15271Index: git/string/tst-strxfrm2.c
15272===================================================================
15273--- git.orig/string/tst-strxfrm2.c 2014-08-29 20:00:53.756070587 -0700
15274+++ git/string/tst-strxfrm2.c 2014-08-29 20:01:15.240070587 -0700
15275@@ -1,6 +1,7 @@
15276 #include <locale.h>
15277 #include <stdio.h>
15278 #include <string.h>
15279+#include <gnu/option-groups.h>
15280
15281 static int
15282 do_test (void)
15283@@ -38,6 +39,7 @@
15284 res = 1;
15285 }
15286
15287+#if __OPTION_EGLIBC_LOCALE_CODE
15288 if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL)
15289 {
15290 puts ("setlocale failed");
15291@@ -75,6 +77,7 @@
15292 res = 1;
15293 }
15294 }
15295+#endif
15296
15297 return res;
15298 }
15299Index: git/string/tst-strxfrm.c
15300===================================================================
15301--- git.orig/string/tst-strxfrm.c 2014-08-29 20:00:53.756070587 -0700
15302+++ git/string/tst-strxfrm.c 2014-08-29 20:01:15.240070587 -0700
15303@@ -3,6 +3,7 @@
15304 #include <stdio.h>
15305 #include <stdlib.h>
15306 #include <string.h>
15307+#include <gnu/option-groups.h>
15308
15309
15310 char const string[] = "";
15311@@ -64,8 +65,10 @@
15312 int result = 0;
15313
15314 result |= test ("C");
15315+#if __OPTION_EGLIBC_LOCALE_CODE
15316 result |= test ("en_US.ISO-8859-1");
15317 result |= test ("de_DE.UTF-8");
15318+#endif
15319
15320 return result;
15321 }
15322Index: git/sunrpc/Makefile
15323===================================================================
15324--- git.orig/sunrpc/Makefile 2014-08-29 20:00:53.760070587 -0700
15325+++ git/sunrpc/Makefile 2014-08-29 20:01:15.240070587 -0700
15326@@ -18,6 +18,8 @@
15327 #
15328 # Sub-makefile for sunrpc portion of the library.
15329 #
15330+include ../option-groups.mak
15331+
15332 subdir := sunrpc
15333
15334 include ../Makeconfig
15335@@ -55,7 +57,6 @@
15336 headers-not-in-tirpc = $(addprefix rpc/,key_prot.h rpc_des.h) \
15337 $(rpcsvc:%=rpcsvc/%) rpcsvc/bootparam.h
15338 headers = rpc/netdb.h
15339-install-others = $(inst_sysconfdir)/rpc
15340 generated += $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) $(rpcsvc:%.x=x%.stmp) \
15341 $(rpcsvc:%.x=rpcsvc/%.stmp) rpcgen
15342 generated-dirs += rpcsvc
15343@@ -65,18 +66,28 @@
15344 endif
15345
15346 ifeq ($(build-shared),yes)
15347-need-export-routines := auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
15348+need-export-routines-$(OPTION_EGLIBC_SUNRPC) += \
15349+ auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
15350 clnt_udp get_myaddr key_call netname pm_getport \
15351- rpc_thread svc svc_tcp svc_udp xcrypt xdr_array xdr \
15352+ rpc_thread svc svc_tcp svc_udp xdr_array xdr \
15353 xdr_intXX_t xdr_mem xdr_ref xdr_sizeof xdr_stdio \
15354 svc_run
15355
15356-routines := auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
15357+need-export-routines-y += xcrypt
15358+
15359+need-export-routines := $(need-export-routines-y)
15360+
15361+routines-$(OPTION_EGLIBC_SUNRPC) \
15362+ += auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
15363 rpc_dtable getrpcport pmap_clnt pm_getmaps pmap_prot pmap_prot2 \
15364 pmap_rmt rpc_prot rpc_common rpc_cmsg svc_auth svc_authux svc_raw \
15365 svc_simple xdr_float xdr_rec publickey authdes_prot \
15366- des_crypt des_impl des_soft key_prot openchild rtime svcauth_des \
15367- clnt_unix svc_unix create_xid $(need-export-routines)
15368+ key_prot openchild rtime svcauth_des \
15369+ clnt_unix svc_unix create_xid
15370+
15371+# xdecrypt is also used by nss/nss_files/files-key.c.
15372+routines-y += des_crypt des_impl des_soft $(need-export-routines)
15373+
15374 ifneq ($(link-obsolete-rpc),yes)
15375 # We only add the RPC for compatibility to libc.so.
15376 shared-only-routines = $(routines)
15377@@ -85,25 +96,28 @@
15378
15379 # We do not build rpcinfo anymore. It is not needed for a bootstrap
15380 # and not wanted on complete systems.
15381-# others := rpcinfo
15382-# install-sbin := rpcinfo
15383-install-bin := rpcgen
15384+# others-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
15385+# install-sbin-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
15386+install-bin-$(OPTION_EGLIBC_SUNRPC) += rpcgen
15387 rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \
15388 rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \
15389 rpc_tblout.o rpc_sample.o
15390-extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
15391-others += rpcgen
15392+extra-objs-$(OPTION_EGLIBC_SUNRPC) = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
15393+others-$(OPTION_EGLIBC_SUNRPC) += rpcgen
15394+
15395+install-others-$(OPTION_EGLIBC_SUNRPC) += $(inst_sysconfdir)/rpc
15396
15397-tests = tst-xdrmem tst-xdrmem2
15398-xtests := tst-getmyaddr
15399+tests-$(OPTION_EGLIBC_SUNRPC) = tst-xdrmem tst-xdrmem2
15400+xtests-$(OPTION_EGLIBC_SUNRPC) := tst-getmyaddr
15401
15402 ifeq ($(have-thread-library),yes)
15403-xtests += thrsvc
15404+xtests-$(OPTION_EGLIBC_SUNRPC) += thrsvc
15405 endif
15406
15407 headers += $(rpcsvc:%.x=rpcsvc/%.h)
15408-extra-libs := librpcsvc
15409-extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass.
15410+extra-libs-$(OPTION_EGLIBC_SUNRPC) += librpcsvc
15411+# Make it in `others' pass, not `lib' pass.
15412+extra-libs-others-y += $(extra-libs-y)
15413 librpcsvc-routines = $(rpcsvc:%.x=x%)
15414 librpcsvc-inhibit-o = .os # Build no shared rpcsvc library.
15415 omit-deps = $(librpcsvc-routines)
15416Index: git/sysdeps/generic/ldsodefs.h
15417===================================================================
15418--- git.orig/sysdeps/generic/ldsodefs.h 2014-08-29 20:00:53.904070587 -0700
15419+++ git/sysdeps/generic/ldsodefs.h 2014-08-29 20:01:15.240070587 -0700
15420@@ -425,6 +425,12 @@
15421 # undef __rtld_global_attribute__
15422 #endif
15423
15424+#if __OPTION_EGLIBC_RTLD_DEBUG
15425+# define GLRO_dl_debug_mask GLRO(dl_debug_mask)
15426+#else
15427+# define GLRO_dl_debug_mask 0
15428+#endif
15429+
15430 #ifndef SHARED
15431 # define GLRO(name) _##name
15432 #else
15433@@ -437,8 +443,10 @@
15434 {
15435 #endif
15436
15437+#if __OPTION_EGLIBC_RTLD_DEBUG
15438 /* If nonzero the appropriate debug information is printed. */
15439 EXTERN int _dl_debug_mask;
15440+#endif
15441 #define DL_DEBUG_LIBS (1 << 0)
15442 #define DL_DEBUG_IMPCALLS (1 << 1)
15443 #define DL_DEBUG_BINDINGS (1 << 2)
15444Index: git/sysdeps/gnu/Makefile
15445===================================================================
15446--- git.orig/sysdeps/gnu/Makefile 2014-08-29 20:00:53.924070587 -0700
15447+++ git/sysdeps/gnu/Makefile 2014-08-29 20:01:15.240070587 -0700
15448@@ -57,7 +57,8 @@
15449 endif
15450
15451 ifeq ($(subdir),login)
15452-sysdep_routines += setutxent getutxent endutxent getutxid getutxline \
15453+sysdep_routines-$(OPTION_EGLIBC_UTMPX) \
15454+ += setutxent getutxent endutxent getutxid getutxline \
15455 pututxline utmpxname updwtmpx getutmpx getutmp
15456
15457 sysdep_headers += utmpx.h bits/utmpx.h
15458Index: git/sysdeps/ieee754/ldbl-opt/Makefile
15459===================================================================
15460--- git.orig/sysdeps/ieee754/ldbl-opt/Makefile 2014-08-29 20:00:54.452070587 -0700
15461+++ git/sysdeps/ieee754/ldbl-opt/Makefile 2014-08-29 20:01:15.244070587 -0700
15462@@ -11,19 +11,18 @@
15463 routines += math_ldbl_opt nldbl-compat
15464
15465 extra-libs += libnldbl
15466-libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
15467+libnldbl-calls = asprintf dprintf fprintf fscanf iovfscanf \
15468 obstack_printf obstack_vprintf printf scanf snprintf \
15469- sprintf sscanf swprintf swscanf vasprintf vdprintf vfprintf \
15470- vfscanf vfwprintf vfwscanf vprintf vscanf vsnprintf \
15471- vsprintf vsscanf vswprintf vswscanf vwprintf vwscanf \
15472- wprintf wscanf printf_fp printf_size \
15473- fprintf_chk fwprintf_chk printf_chk snprintf_chk sprintf_chk \
15474- swprintf_chk vfprintf_chk vfwprintf_chk vprintf_chk \
15475- vsnprintf_chk vsprintf_chk vswprintf_chk vwprintf_chk \
15476- wprintf_chk asprintf_chk vasprintf_chk dprintf_chk \
15477+ sprintf sscanf vasprintf vdprintf vfprintf \
15478+ vfscanf vprintf vscanf vsnprintf \
15479+ vsprintf vsscanf \
15480+ printf_fp printf_size \
15481+ fprintf_chk printf_chk snprintf_chk sprintf_chk \
15482+ vfprintf_chk vprintf_chk \
15483+ vsnprintf_chk vsprintf_chk \
15484+ asprintf_chk vasprintf_chk dprintf_chk \
15485 vdprintf_chk obstack_printf_chk obstack_vprintf_chk \
15486 syslog syslog_chk vsyslog vsyslog_chk \
15487- strfmon strfmon_l \
15488 strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \
15489 qecvt qfcvt qgcvt qecvt_r qfcvt_r \
15490 isinf isnan finite signbit scalb log2 lgamma_r ceil \
15491@@ -38,9 +37,15 @@
15492 casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \
15493 cabs carg cimag creal clog10 \
15494 isoc99_scanf isoc99_fscanf isoc99_sscanf \
15495- isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
15496+ isoc99_vscanf isoc99_vfscanf isoc99_vsscanf
15497+libnldbl-calls-$(OPTION_EGLIBC_LOCALE_CODE) += strfmon strfmon_l
15498+libnldbl-calls-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += fwprintf fwscanf \
15499+ swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf \
15500+ vwprintf vwscanf wprintf wscanf fwprintf_chk swprintf_chk \
15501+ vfwprintf_chk vswprintf_chk vwprintf_chk wprintf_chk \
15502 isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
15503 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf
15504+libnldbl-calls += $(libnldbl-calls-y)
15505 libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
15506 libnldbl-inhibit-o = $(object-suffixes)
15507 libnldbl-static-only-routines = $(libnldbl-routines)
15508Index: git/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
15509===================================================================
15510--- git.orig/sysdeps/ieee754/ldbl-opt/nldbl-compat.c 2014-08-29 20:00:54.468070587 -0700
15511+++ git/sysdeps/ieee754/ldbl-opt/nldbl-compat.c 2014-08-29 20:01:15.244070587 -0700
15512@@ -26,6 +26,7 @@
15513 #include <locale/localeinfo.h>
15514 #include <sys/syslog.h>
15515 #include <bits/libc-lock.h>
15516+#include <gnu/option-groups.h>
15517
15518 #include "nldbl-compat.h"
15519
15520@@ -33,20 +34,14 @@
15521 libc_hidden_proto (__nldbl_vsscanf)
15522 libc_hidden_proto (__nldbl_vsprintf)
15523 libc_hidden_proto (__nldbl_vfscanf)
15524-libc_hidden_proto (__nldbl_vfwscanf)
15525 libc_hidden_proto (__nldbl_vdprintf)
15526-libc_hidden_proto (__nldbl_vswscanf)
15527-libc_hidden_proto (__nldbl_vfwprintf)
15528-libc_hidden_proto (__nldbl_vswprintf)
15529 libc_hidden_proto (__nldbl_vsnprintf)
15530 libc_hidden_proto (__nldbl_vasprintf)
15531 libc_hidden_proto (__nldbl_obstack_vprintf)
15532-libc_hidden_proto (__nldbl___vfwprintf_chk)
15533 libc_hidden_proto (__nldbl___vsnprintf_chk)
15534 libc_hidden_proto (__nldbl___vfprintf_chk)
15535 libc_hidden_proto (__nldbl___vsyslog_chk)
15536 libc_hidden_proto (__nldbl___vsprintf_chk)
15537-libc_hidden_proto (__nldbl___vswprintf_chk)
15538 libc_hidden_proto (__nldbl___vasprintf_chk)
15539 libc_hidden_proto (__nldbl___vdprintf_chk)
15540 libc_hidden_proto (__nldbl___obstack_vprintf_chk)
15541@@ -54,8 +49,17 @@
15542 libc_hidden_proto (__nldbl___vstrfmon_l)
15543 libc_hidden_proto (__nldbl___isoc99_vsscanf)
15544 libc_hidden_proto (__nldbl___isoc99_vfscanf)
15545+
15546+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15547+libc_hidden_proto (__nldbl_vfwscanf)
15548+libc_hidden_proto (__nldbl_vswscanf)
15549+libc_hidden_proto (__nldbl_vfwprintf)
15550+libc_hidden_proto (__nldbl_vswprintf)
15551+libc_hidden_proto (__nldbl___vfwprintf_chk)
15552+libc_hidden_proto (__nldbl___vswprintf_chk)
15553 libc_hidden_proto (__nldbl___isoc99_vswscanf)
15554 libc_hidden_proto (__nldbl___isoc99_vfwscanf)
15555+#endif
15556
15557 static void
15558 __nldbl_cleanup (void *arg)
15559@@ -117,6 +121,7 @@
15560 }
15561 weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf)
15562
15563+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15564 int
15565 attribute_compat_text_section weak_function
15566 __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...)
15567@@ -130,6 +135,7 @@
15568
15569 return done;
15570 }
15571+#endif
15572
15573 int
15574 attribute_compat_text_section
15575@@ -226,6 +232,7 @@
15576 return done;
15577 }
15578
15579+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15580 int
15581 attribute_compat_text_section
15582 __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
15583@@ -239,6 +246,7 @@
15584
15585 return done;
15586 }
15587+#endif
15588
15589 int
15590 attribute_compat_text_section weak_function
15591@@ -264,6 +272,7 @@
15592 }
15593 libc_hidden_def (__nldbl_vdprintf)
15594
15595+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15596 int
15597 attribute_compat_text_section weak_function
15598 __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
15599@@ -275,6 +284,7 @@
15600 return res;
15601 }
15602 libc_hidden_def (__nldbl_vfwprintf)
15603+#endif
15604
15605 int
15606 attribute_compat_text_section
15607@@ -297,6 +307,7 @@
15608 libc_hidden_def (__nldbl_vsnprintf)
15609 weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf)
15610
15611+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15612 int
15613 attribute_compat_text_section weak_function
15614 __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt,
15615@@ -330,6 +341,7 @@
15616
15617 return done;
15618 }
15619+#endif
15620
15621 int
15622 attribute_compat_text_section
15623@@ -419,6 +431,7 @@
15624 return done;
15625 }
15626
15627+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15628 int
15629 attribute_compat_text_section
15630 __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
15631@@ -491,6 +504,7 @@
15632
15633 return done;
15634 }
15635+#endif
15636
15637 int
15638 attribute_compat_text_section
15639@@ -506,6 +520,7 @@
15640 return done;
15641 }
15642
15643+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15644 int
15645 attribute_compat_text_section
15646 __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
15647@@ -519,6 +534,7 @@
15648
15649 return done;
15650 }
15651+#endif
15652
15653 int
15654 attribute_compat_text_section
15655@@ -563,6 +579,7 @@
15656 return done;
15657 }
15658
15659+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15660 int
15661 attribute_compat_text_section
15662 __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
15663@@ -577,6 +594,7 @@
15664
15665 return done;
15666 }
15667+#endif
15668
15669 int
15670 attribute_compat_text_section
15671@@ -590,6 +608,7 @@
15672 }
15673 libc_hidden_def (__nldbl___vfprintf_chk)
15674
15675+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15676 int
15677 attribute_compat_text_section
15678 __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
15679@@ -601,6 +620,7 @@
15680 return res;
15681 }
15682 libc_hidden_def (__nldbl___vfwprintf_chk)
15683+#endif
15684
15685 int
15686 attribute_compat_text_section
15687@@ -635,6 +655,7 @@
15688 }
15689 libc_hidden_def (__nldbl___vsprintf_chk)
15690
15691+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15692 int
15693 attribute_compat_text_section
15694 __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen,
15695@@ -668,6 +689,7 @@
15696
15697 return done;
15698 }
15699+#endif
15700
15701 int
15702 attribute_compat_text_section
15703@@ -775,6 +797,7 @@
15704 return ___printf_fp (fp, &info_no_ldbl, args);
15705 }
15706
15707+#if __OPTION_EGLIBC_LOCALE_CODE
15708 ssize_t
15709 attribute_compat_text_section
15710 __nldbl_strfmon (char *s, size_t maxsize, const char *format, ...)
15711@@ -829,6 +852,7 @@
15712 return res;
15713 }
15714 libc_hidden_def (__nldbl___vstrfmon_l)
15715+#endif
15716
15717 void
15718 attribute_compat_text_section
15719@@ -941,6 +965,7 @@
15720 return done;
15721 }
15722
15723+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15724 int
15725 attribute_compat_text_section
15726 __nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
15727@@ -1014,6 +1039,7 @@
15728
15729 return done;
15730 }
15731+#endif
15732
15733 #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
15734 compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0);
15735@@ -1057,6 +1083,7 @@
15736 compat_symbol (libc, __nldbl___strfmon_l, __strfmon_l, GLIBC_2_1);
15737 #endif
15738 #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_2)
15739+# if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15740 compat_symbol (libc, __nldbl_swprintf, swprintf, GLIBC_2_2);
15741 compat_symbol (libc, __nldbl_vwprintf, vwprintf, GLIBC_2_2);
15742 compat_symbol (libc, __nldbl_wprintf, wprintf, GLIBC_2_2);
15743@@ -1069,6 +1096,7 @@
15744 compat_symbol (libc, __nldbl_vswscanf, vswscanf, GLIBC_2_2);
15745 compat_symbol (libc, __nldbl_vwscanf, vwscanf, GLIBC_2_2);
15746 compat_symbol (libc, __nldbl_wscanf, wscanf, GLIBC_2_2);
15747+# endif
15748 #endif
15749 #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3)
15750 compat_symbol (libc, __nldbl_strfmon_l, strfmon_l, GLIBC_2_3);
15751Index: git/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
15752===================================================================
15753--- git.orig/sysdeps/ieee754/ldbl-opt/nldbl-compat.h 2014-08-29 20:00:54.468070587 -0700
15754+++ git/sysdeps/ieee754/ldbl-opt/nldbl-compat.h 2014-08-29 20:01:15.244070587 -0700
15755@@ -30,6 +30,7 @@
15756 #include <math.h>
15757 #include <monetary.h>
15758 #include <sys/syslog.h>
15759+#include <gnu/option-groups.h>
15760
15761
15762 /* Declare the __nldbl_NAME function the wrappers call that's in libc.so. */
15763@@ -37,19 +38,15 @@
15764
15765 NLDBL_DECL (_IO_vfscanf);
15766 NLDBL_DECL (vfscanf);
15767-NLDBL_DECL (vfwscanf);
15768 NLDBL_DECL (obstack_vprintf);
15769 NLDBL_DECL (vasprintf);
15770 NLDBL_DECL (dprintf);
15771 NLDBL_DECL (vdprintf);
15772 NLDBL_DECL (fprintf);
15773 NLDBL_DECL (vfprintf);
15774-NLDBL_DECL (vfwprintf);
15775 NLDBL_DECL (vsnprintf);
15776 NLDBL_DECL (vsprintf);
15777 NLDBL_DECL (vsscanf);
15778-NLDBL_DECL (vswprintf);
15779-NLDBL_DECL (vswscanf);
15780 NLDBL_DECL (__asprintf);
15781 NLDBL_DECL (asprintf);
15782 NLDBL_DECL (__printf_fp);
15783@@ -66,12 +63,18 @@
15784 NLDBL_DECL (__isoc99_vscanf);
15785 NLDBL_DECL (__isoc99_vfscanf);
15786 NLDBL_DECL (__isoc99_vsscanf);
15787+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15788+NLDBL_DECL (vfwscanf);
15789+NLDBL_DECL (vfwprintf);
15790+NLDBL_DECL (vswprintf);
15791+NLDBL_DECL (vswscanf);
15792 NLDBL_DECL (__isoc99_wscanf);
15793 NLDBL_DECL (__isoc99_fwscanf);
15794 NLDBL_DECL (__isoc99_swscanf);
15795 NLDBL_DECL (__isoc99_vwscanf);
15796 NLDBL_DECL (__isoc99_vfwscanf);
15797 NLDBL_DECL (__isoc99_vswscanf);
15798+#endif
15799
15800 /* This one does not exist in the normal interface, only
15801 __nldbl___vstrfmon really exists. */
15802@@ -82,22 +85,23 @@
15803 since we don't compile with _FORTIFY_SOURCE. */
15804 extern int __nldbl___vfprintf_chk (FILE *__restrict, int,
15805 const char *__restrict, _G_va_list);
15806-extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
15807- const wchar_t *__restrict, __gnuc_va_list);
15808 extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t,
15809 const char *__restrict, _G_va_list) __THROW;
15810 extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t,
15811 const char *__restrict, _G_va_list)
15812 __THROW;
15813-extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
15814- const wchar_t *__restrict, __gnuc_va_list)
15815- __THROW;
15816 extern int __nldbl___vasprintf_chk (char **, int, const char *, _G_va_list)
15817 __THROW;
15818 extern int __nldbl___vdprintf_chk (int, int, const char *, _G_va_list);
15819 extern int __nldbl___obstack_vprintf_chk (struct obstack *, int, const char *,
15820 _G_va_list) __THROW;
15821 extern void __nldbl___vsyslog_chk (int, int, const char *, va_list);
15822-
15823+#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
15824+extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
15825+ const wchar_t *__restrict, __gnuc_va_list);
15826+extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
15827+ const wchar_t *__restrict, __gnuc_va_list)
15828+ __THROW;
15829+#endif
15830
15831 #endif /* __NLDBL_COMPAT_H */
15832Index: git/sysdeps/unix/sysv/linux/gethostid.c
15833===================================================================
15834--- git.orig/sysdeps/unix/sysv/linux/gethostid.c 2014-08-29 20:00:58.840070587 -0700
15835+++ git/sysdeps/unix/sysv/linux/gethostid.c 2014-08-29 20:01:15.244070587 -0700
15836@@ -21,6 +21,7 @@
15837 #include <unistd.h>
15838 #include <netdb.h>
15839 #include <not-cancel.h>
15840+#include <gnu/option-groups.h>
15841
15842 #define HOSTIDFILE "/etc/hostid"
15843
15844@@ -89,6 +90,7 @@
15845 return id;
15846 }
15847
15848+#if __OPTION_EGLIBC_INET
15849 /* Getting from the file was not successful. An intelligent guess for
15850 a unique number of a host is its IP address. Return this. */
15851 if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0')
15852@@ -115,5 +117,9 @@
15853 /* For the return value to be not exactly the IP address we do some
15854 bit fiddling. */
15855 return (int32_t) (in.s_addr << 16 | in.s_addr >> 16);
15856+#else
15857+ /* Return an arbitrary value. */
15858+ return 0;
15859+#endif
15860 }
15861 #endif
15862Index: git/sysdeps/unix/sysv/linux/libc_fatal.c
15863===================================================================
15864--- git.orig/sysdeps/unix/sysv/linux/libc_fatal.c 2014-08-29 20:00:58.980070587 -0700
15865+++ git/sysdeps/unix/sysv/linux/libc_fatal.c 2014-08-29 20:01:15.244070587 -0700
15866@@ -23,6 +23,7 @@
15867 #include <string.h>
15868 #include <sys/mman.h>
15869 #include <sys/uio.h>
15870+#include <gnu/option-groups.h>
15871
15872 static bool
15873 writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
15874@@ -40,6 +41,7 @@
15875 static void
15876 backtrace_and_maps (int do_abort, bool written, int fd)
15877 {
15878+#if __OPTION_EGLIBC_BACKTRACE
15879 if (do_abort > 1 && written)
15880 {
15881 void *addrs[64];
15882@@ -62,6 +64,7 @@
15883 close_not_cancel_no_status (fd2);
15884 }
15885 }
15886+#endif /* __OPTION_EGLIBC_BACKTRACE */
15887 }
15888 #define BEFORE_ABORT backtrace_and_maps
15889
15890Index: git/time/Makefile
15891===================================================================
15892--- git.orig/time/Makefile 2014-08-29 20:00:59.504070587 -0700
15893+++ git/time/Makefile 2014-08-29 20:01:15.244070587 -0700
15894@@ -18,6 +18,8 @@
15895 #
15896 # Makefile for time routines
15897 #
15898+include ../option-groups.mak
15899+
15900 subdir := time
15901
15902 include ../Makeconfig
15903@@ -30,14 +32,20 @@
15904 tzfile getitimer setitimer \
15905 stime dysize timegm ftime \
15906 getdate strptime strptime_l \
15907- strftime wcsftime strftime_l wcsftime_l \
15908+ strftime strftime_l \
15909 timespec_get
15910-aux := era alt_digit lc-time-cleanup
15911+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
15912+ := wcsftime wcsftime_l
15913+aux-$(OPTION_EGLIBC_LOCALE_CODE) += alt_digit era lc-time-cleanup
15914
15915-tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
15916- tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
15917+tests := test_time clocktest tst-posixtz \
15918+ tst-getdate tst-mktime tst-mktime2 tst-strftime \
15919 tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
15920 tst-strptime3 bug-getdate1 tst-strptime-whitespace
15921+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
15922+ += tst-strptime tst-ftime_l
15923+tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
15924+ += tst_wcsftime
15925
15926 include ../Rules
15927
15928Index: git/time/strftime_l.c
15929===================================================================
15930--- git.orig/time/strftime_l.c 2014-08-29 20:00:59.528070587 -0700
15931+++ git/time/strftime_l.c 2014-08-29 20:01:15.244070587 -0700
15932@@ -35,6 +35,10 @@
15933 # include "../locale/localeinfo.h"
15934 #endif
15935
15936+#ifdef _LIBC
15937+# include <gnu/option-groups.h>
15938+#endif
15939+
15940 #if defined emacs && !defined HAVE_BCOPY
15941 # define HAVE_MEMCPY 1
15942 #endif
15943@@ -882,7 +886,7 @@
15944 case L_('C'):
15945 if (modifier == L_('E'))
15946 {
15947-#if HAVE_STRUCT_ERA_ENTRY
15948+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
15949 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
15950 if (era)
15951 {
15952@@ -955,7 +959,7 @@
15953
15954 if (modifier == L_('O') && 0 <= number_value)
15955 {
15956-#ifdef _NL_CURRENT
15957+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
15958 /* Get the locale specific alternate representation of
15959 the number NUMBER_VALUE. If none exist NULL is returned. */
15960 const CHAR_T *cp = nl_get_alt_digit (number_value
15961@@ -1260,7 +1264,7 @@
15962 case L_('Y'):
15963 if (modifier == 'E')
15964 {
15965-#if HAVE_STRUCT_ERA_ENTRY
15966+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
15967 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
15968 if (era)
15969 {
15970@@ -1285,7 +1289,7 @@
15971 case L_('y'):
15972 if (modifier == L_('E'))
15973 {
15974-#if HAVE_STRUCT_ERA_ENTRY
15975+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
15976 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
15977 if (era)
15978 {
15979Index: git/time/strptime_l.c
15980===================================================================
15981--- git.orig/time/strptime_l.c 2014-08-29 20:00:59.528070587 -0700
15982+++ git/time/strptime_l.c 2014-08-29 20:01:15.244070587 -0700
15983@@ -29,6 +29,7 @@
15984
15985 #ifdef _LIBC
15986 # define HAVE_LOCALTIME_R 0
15987+# include <gnu/option-groups.h>
15988 # include "../locale/localeinfo.h"
15989 #endif
15990
15991@@ -84,7 +85,7 @@
15992 if (val < from || val > to) \
15993 return NULL; \
15994 } while (0)
15995-#ifdef _NL_CURRENT
15996+#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
15997 # define get_alt_number(from, to, n) \
15998 ({ \
15999 __label__ do_normal; \
16000@@ -820,6 +821,7 @@
16001 s.want_xday = 1;
16002 break;
16003 case 'C':
16004+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16005 if (s.decided != raw)
16006 {
16007 if (s.era_cnt >= 0)
16008@@ -856,10 +858,12 @@
16009
16010 s.decided = raw;
16011 }
16012+#endif
16013 /* The C locale has no era information, so use the
16014 normal representation. */
16015 goto match_century;
16016 case 'y':
16017+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16018 if (s.decided != raw)
16019 {
16020 get_number(0, 9999, 4);
16021@@ -918,9 +922,10 @@
16022
16023 s.decided = raw;
16024 }
16025-
16026+#endif
16027 goto match_year_in_century;
16028 case 'Y':
16029+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16030 if (s.decided != raw)
16031 {
16032 num_eras = _NL_CURRENT_WORD (LC_TIME,
16033@@ -948,6 +953,7 @@
16034
16035 s.decided = raw;
16036 }
16037+#endif
16038 get_number (0, 9999, 4);
16039 tm->tm_year = val - 1900;
16040 s.want_century = 0;
16041@@ -1118,6 +1124,7 @@
16042 tm->tm_year = (s.century - 19) * 100;
16043 }
16044
16045+#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
16046 if (s.era_cnt != -1)
16047 {
16048 era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);
16049@@ -1132,6 +1139,7 @@
16050 tm->tm_year = era->start_date[0];
16051 }
16052 else
16053+#endif
16054 if (s.want_era)
16055 {
16056 /* No era found but we have seen an E modifier. Rectify some
16057Index: git/timezone/Makefile
16058===================================================================
16059--- git.orig/timezone/Makefile 2014-08-29 20:01:14.044070587 -0700
16060+++ git/timezone/Makefile 2014-08-29 20:01:15.244070587 -0700
16061@@ -115,7 +115,7 @@
16062
16063 $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
16064 sed -e 's|/bin/bash|/bin/sh|' \
16065- -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
16066+ -e '/TZDIR=/s|\$$(pwd)|$(zonedir)|' \
16067 -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
16068 -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \
16069 -e '/REPORT_BUGS_TO=/s|=.*|="$(REPORT_BUGS_TO)"|' \
16070Index: git/wcsmbs/Makefile
16071===================================================================
16072--- git.orig/wcsmbs/Makefile 2014-08-29 20:00:59.548070587 -0700
16073+++ git/wcsmbs/Makefile 2014-08-29 20:01:15.244070587 -0700
16074@@ -18,15 +18,21 @@
16075 #
16076 # Sub-makefile for wcsmbs portion of the library.
16077 #
16078+include ../option-groups.mak
16079+
16080 subdir := wcsmbs
16081
16082 include ../Makeconfig
16083
16084 headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h
16085
16086-routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
16087+# These functions are used by printf_fp.c, even in the plain case; see
16088+# comments there for OPTION_EGLIBC_LOCALE_CODE.
16089+routines := wmemcpy wmemset
16090+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16091+ := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
16092 wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
16093- wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy wmempcpy \
16094+ wmemcmp wmemmove wcpcpy wcpncpy wmempcpy \
16095 btowc wctob mbsinit \
16096 mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
16097 mbsnrtowcs wcsnrtombs wcsnlen wcschrnul \
16098@@ -38,14 +44,19 @@
16099 wcscoll_l wcsxfrm_l \
16100 wcscasecmp wcsncase wcscasecmp_l wcsncase_l \
16101 wcsmbsload mbsrtowcs_l \
16102- isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
16103 isoc99_swscanf isoc99_vswscanf \
16104 mbrtoc16 c16rtomb
16105+routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
16106+ += isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf
16107
16108 strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy
16109-tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
16110- tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
16111- tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests))
16112+tests := tst-wchar-h
16113+tests-$(OPTION_EGLIBC_LOCALE_CODE) \
16114+ += tst-btowc tst-mbrtowc tst-mbrtowc2 tst-wcrtomb tst-c16c32-1
16115+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16116+ += tst-wcstof wcsmbs-tst1 tst-wcsnlen \
16117+ tst-wcpncpy tst-mbsrtowcs \
16118+ wcsatcliff $(addprefix test-,$(strop-tests))
16119 tests-ifunc := $(strop-tests:%=test-%-ifunc)
16120 tests += $(tests-ifunc)
16121
16122Index: git/wcsmbs/wcsmbsload.c
16123===================================================================
16124--- git.orig/wcsmbs/wcsmbsload.c 2014-08-29 20:00:59.580070587 -0700
16125+++ git/wcsmbs/wcsmbsload.c 2014-08-29 20:01:15.248070587 -0700
16126@@ -21,6 +21,7 @@
16127 #include <limits.h>
16128 #include <stdlib.h>
16129 #include <string.h>
16130+#include <gnu/option-groups.h>
16131
16132 #include <locale/localeinfo.h>
16133 #include <wcsmbsload.h>
16134@@ -143,6 +144,7 @@
16135 })
16136
16137
16138+#if __OPTION_EGLIBC_LOCALE_CODE
16139 /* Some of the functions here must not be used while setlocale is called. */
16140 __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
16141
16142@@ -211,6 +213,17 @@
16143
16144 __libc_rwlock_unlock (__libc_setlocale_lock);
16145 }
16146+#else
16147+void
16148+internal_function
16149+__wcsmbs_load_conv (struct __locale_data *new_category)
16150+{
16151+ /* When OPTION_EGLIBC_LOCALE_CODE is disabled, we should never reach
16152+ this point: there is no way to change locales, so every locale
16153+ passed to get_gconv_fcts should be _nl_C_LC_CTYPE. */
16154+ abort ();
16155+}
16156+#endif
16157
16158
16159 /* Clone the current conversion function set. */
16160Index: git/wctype/Makefile
16161===================================================================
16162--- git.orig/wctype/Makefile 2014-08-29 20:00:59.584070587 -0700
16163+++ git/wctype/Makefile 2014-08-29 20:01:15.248070587 -0700
16164@@ -18,14 +18,20 @@
16165 #
16166 # Sub-makefile for wctype portion of the library.
16167 #
16168+include ../option-groups.mak
16169+
16170 subdir := wctype
16171
16172 include ../Makeconfig
16173
16174 headers := wctype.h
16175-routines := wcfuncs wctype iswctype wctrans towctrans \
16176- wcfuncs_l wctype_l iswctype_l wctrans_l towctrans_l
16177+routines := wctrans towctrans towctrans_l
16178+routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16179+ := wcfuncs wctype iswctype \
16180+ wcfuncs_l wctype_l iswctype_l wctrans_l
16181
16182-tests := test_wctype test_wcfuncs bug-wctypeh
16183+tests :=
16184+tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
16185+ += test_wctype test_wcfuncs bug-wctypeh
16186
16187 include ../Rules
16188Index: git/sysdeps/nptl/Makefile
16189===================================================================
16190--- git.orig/sysdeps/nptl/Makefile 2014-08-29 20:00:58.036070587 -0700
16191+++ git/sysdeps/nptl/Makefile 2014-08-29 20:01:15.248070587 -0700
16192@@ -18,6 +18,9 @@
16193
16194 ifeq ($(subdir),nptl)
16195 libpthread-sysdep_routines += errno-loc
16196+ifeq ($(OPTION_EGLIBC_BIG_MACROS),n)
16197+sysdep_routines += small-macros-fns
16198+endif
16199 endif
16200
16201 ifeq ($(subdir),rt)
16202Index: git/sysdeps/nptl/bits/libc-lock.h
16203===================================================================
16204--- git.orig/sysdeps/nptl/bits/libc-lock.h 2014-08-29 20:00:58.036070587 -0700
16205+++ git/sysdeps/nptl/bits/libc-lock.h 2014-08-29 20:01:15.248070587 -0700
16206@@ -24,6 +24,14 @@
16207 #include <stddef.h>
16208
16209
16210+#ifdef _LIBC
16211+# include <lowlevellock.h>
16212+# include <tls.h>
16213+# include <pthread-functions.h>
16214+# include <errno.h> /* For EBUSY. */
16215+# include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */
16216+#endif
16217+
16218 /* Mutex type. */
16219 #if defined _LIBC || defined _IO_MTSAFE_IO
16220 # if (defined NOT_IN_libc && !defined IS_IN_libpthread) || !defined _LIBC
16221@@ -87,6 +95,14 @@
16222
16223 /* Lock the recursive named lock variable. */
16224 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
16225+# if __OPTION_EGLIBC_BIG_MACROS != 1
16226+/* EGLIBC: Declare wrapper function for a big macro if either
16227+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16228+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16229+extern void __libc_lock_lock_recursive_fn (__libc_lock_recursive_t *);
16230+libc_hidden_proto (__libc_lock_lock_recursive_fn);
16231+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16232+# if __OPTION_EGLIBC_BIG_MACROS
16233 # define __libc_lock_lock_recursive(NAME) \
16234 do { \
16235 void *self = THREAD_SELF; \
16236@@ -97,6 +113,10 @@
16237 } \
16238 ++(NAME).cnt; \
16239 } while (0)
16240+# else
16241+# define __libc_lock_lock_recursive(NAME) \
16242+ __libc_lock_lock_recursive_fn (&(NAME))
16243+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16244 #else
16245 # define __libc_lock_lock_recursive(NAME) \
16246 __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
16247@@ -104,6 +124,14 @@
16248
16249 /* Try to lock the recursive named lock variable. */
16250 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
16251+# if __OPTION_EGLIBC_BIG_MACROS != 1
16252+/* EGLIBC: Declare wrapper function for a big macro if either
16253+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16254+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16255+extern int __libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *);
16256+libc_hidden_proto (__libc_lock_trylock_recursive_fn);
16257+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16258+# if __OPTION_EGLIBC_BIG_MACROS
16259 # define __libc_lock_trylock_recursive(NAME) \
16260 ({ \
16261 int result = 0; \
16262@@ -122,6 +150,10 @@
16263 ++(NAME).cnt; \
16264 result; \
16265 })
16266+# else
16267+# define __libc_lock_trylock_recursive(NAME) \
16268+ __libc_lock_trylock_recursive_fn (&(NAME))
16269+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16270 #else
16271 # define __libc_lock_trylock_recursive(NAME) \
16272 __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0)
16273@@ -129,6 +161,14 @@
16274
16275 /* Unlock the recursive named lock variable. */
16276 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
16277+# if __OPTION_EGLIBC_BIG_MACROS != 1
16278+/* EGLIBC: Declare wrapper function for a big macro if either
16279+ !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
16280+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16281+extern void __libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *);
16282+libc_hidden_proto (__libc_lock_unlock_recursive_fn);
16283+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16284+# if __OPTION_EGLIBC_BIG_MACROS
16285 /* We do no error checking here. */
16286 # define __libc_lock_unlock_recursive(NAME) \
16287 do { \
16288@@ -138,6 +178,10 @@
16289 lll_unlock ((NAME).lock, LLL_PRIVATE); \
16290 } \
16291 } while (0)
16292+# else
16293+# define __libc_lock_unlock_recursive(NAME) \
16294+ __libc_lock_unlock_recursive_fn (&(NAME))
16295+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16296 #else
16297 # define __libc_lock_unlock_recursive(NAME) \
16298 __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
16299Index: git/sysdeps/nptl/bits/libc-lockP.h
16300===================================================================
16301--- git.orig/sysdeps/nptl/bits/libc-lockP.h 2014-08-29 20:00:58.044070587 -0700
16302+++ git/sysdeps/nptl/bits/libc-lockP.h 2014-08-29 20:01:15.248070587 -0700
16303@@ -33,6 +33,8 @@
16304 #include <lowlevellock.h>
16305 #include <tls.h>
16306 #include <pthread-functions.h>
16307+#include <errno.h> /* For EBUSY. */
16308+#include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS. */
16309
16310 /* Mutex type. */
16311 #if defined NOT_IN_libc && !defined IS_IN_libpthread
16312@@ -159,10 +161,22 @@
16313
16314 /* Lock the named lock variable. */
16315 #if !defined NOT_IN_libc || defined IS_IN_libpthread
16316-# ifndef __libc_lock_lock
16317-# define __libc_lock_lock(NAME) \
16318+# if __OPTION_EGLIBC_BIG_MACROS != 1
16319+/* EGLIBC: Declare wrapper function for a big macro if either
16320+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16321+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16322+extern void __libc_lock_lock_fn (__libc_lock_t *);
16323+libc_hidden_proto (__libc_lock_lock_fn);
16324+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16325+# if __OPTION_EGLIBC_BIG_MACROS
16326+# ifndef __libc_lock_lock
16327+# define __libc_lock_lock(NAME) \
16328 ({ lll_lock (NAME, LLL_PRIVATE); 0; })
16329-# endif
16330+# endif
16331+# else
16332+# define __libc_lock_lock(NAME) \
16333+ __libc_lock_lock_fn (&(NAME))
16334+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16335 #else
16336 # undef __libc_lock_lock
16337 # define __libc_lock_lock(NAME) \
16338@@ -175,10 +189,22 @@
16339
16340 /* Try to lock the named lock variable. */
16341 #if !defined NOT_IN_libc || defined IS_IN_libpthread
16342-# ifndef __libc_lock_trylock
16343-# define __libc_lock_trylock(NAME) \
16344+# if __OPTION_EGLIBC_BIG_MACROS != 1
16345+/* EGLIBC: Declare wrapper function for a big macro if either
16346+ !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
16347+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16348+extern int __libc_lock_trylock_fn (__libc_lock_t *);
16349+libc_hidden_proto (__libc_lock_trylock_fn);
16350+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16351+# if __OPTION_EGLIBC_BIG_MACROS
16352+# ifndef __libc_lock_trylock
16353+# define __libc_lock_trylock(NAME) \
16354 lll_trylock (NAME)
16355-# endif
16356+# endif
16357+# else
16358+# define __libc_lock_trylock(NAME) \
16359+ __libc_lock_trylock_fn (&(NAME))
16360+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16361 #else
16362 # undef __libc_lock_trylock
16363 # define __libc_lock_trylock(NAME) \
16364@@ -194,8 +220,20 @@
16365
16366 /* Unlock the named lock variable. */
16367 #if !defined NOT_IN_libc || defined IS_IN_libpthread
16368+# if __OPTION_EGLIBC_BIG_MACROS != 1
16369+/* EGLIBC: Declare wrapper function for a big macro if either
16370+ !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
16371+ small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2). */
16372+extern void __libc_lock_unlock_fn (__libc_lock_t *);
16373+libc_hidden_proto (__libc_lock_unlock_fn);
16374+# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
16375+# if __OPTION_EGLIBC_BIG_MACROS
16376 # define __libc_lock_unlock(NAME) \
16377 lll_unlock (NAME, LLL_PRIVATE)
16378+# else
16379+# define __libc_lock_unlock(NAME) \
16380+ __libc_lock_unlock_fn (&(NAME))
16381+# endif /* __OPTION_EGLIBC_BIG_MACROS */
16382 #else
16383 # define __libc_lock_unlock(NAME) \
16384 __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
16385Index: git/sysdeps/nptl/small-macros-fns.c
16386===================================================================
16387--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16388+++ git/sysdeps/nptl/small-macros-fns.c 2014-08-29 20:01:15.248070587 -0700
16389@@ -0,0 +1,72 @@
16390+/* EGLIBC: function wrappers for big macros.
16391+ Copyright (C) 2009 Free Software Foundation, Inc.
16392+ This file is part of the GNU C Library.
16393+
16394+ The GNU C Library is free software; you can redistribute it and/or
16395+ modify it under the terms of the GNU Lesser General Public License as
16396+ published by the Free Software Foundation; either version 2.1 of the
16397+ License, or (at your option) any later version.
16398+
16399+ The GNU C Library is distributed in the hope that it will be useful,
16400+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16401+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16402+ Lesser General Public License for more details.
16403+
16404+ You should have received a copy of the GNU Lesser General Public
16405+ License along with the GNU C Library; see the file COPYING.LIB. If not,
16406+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16407+ Boston, MA 02111-1307, USA. */
16408+
16409+#include <gnu/option-groups.h>
16410+
16411+/* Handle macros from ./bits/libc-lock.h. */
16412+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
16413+
16414+/* Get the macros for function bodies through a back door. */
16415+# undef __OPTION_EGLIBC_BIG_MACROS
16416+# define __OPTION_EGLIBC_BIG_MACROS 2
16417+# include <bits/libc-lock.h>
16418+
16419+void
16420+__libc_lock_lock_fn (__libc_lock_t *name)
16421+{
16422+ __libc_lock_lock (*name);
16423+}
16424+libc_hidden_def (__libc_lock_lock_fn);
16425+
16426+void
16427+__libc_lock_lock_recursive_fn (__libc_lock_recursive_t *name)
16428+{
16429+ __libc_lock_lock_recursive (*name);
16430+}
16431+libc_hidden_def (__libc_lock_lock_recursive_fn);
16432+
16433+int
16434+__libc_lock_trylock_fn (__libc_lock_t *name)
16435+{
16436+ return __libc_lock_trylock (*name);
16437+}
16438+libc_hidden_def (__libc_lock_trylock_fn);
16439+
16440+int
16441+__libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *name)
16442+{
16443+ return __libc_lock_trylock_recursive (*name);
16444+}
16445+libc_hidden_def (__libc_lock_trylock_recursive_fn);
16446+
16447+void
16448+__libc_lock_unlock_fn (__libc_lock_t *name)
16449+{
16450+ __libc_lock_unlock (*name);
16451+}
16452+libc_hidden_def (__libc_lock_unlock_fn);
16453+
16454+void
16455+__libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *name)
16456+{
16457+ __libc_lock_unlock_recursive (*name);
16458+}
16459+libc_hidden_def (__libc_lock_unlock_recursive_fn);
16460+
16461+#endif /*defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)*/
16462Index: git/include/libc-symbols.h
16463===================================================================
16464--- git.orig/include/libc-symbols.h 2014-08-29 20:00:47.144070587 -0700
16465+++ git/include/libc-symbols.h 2014-08-29 20:01:15.248070587 -0700
16466@@ -60,8 +60,11 @@
16467 /* Define these macros for the benefit of portable GNU code that wants to check
16468 them. Of course, STDC_HEADERS is never false when building libc! */
16469 #define STDC_HEADERS 1
16470-#define HAVE_MBSTATE_T 1
16471-#define HAVE_MBSRTOWCS 1
16472+
16473+#if __OPTION_EGLIBC_LOCALE_CODE
16474+# define HAVE_MBSTATE_T 1
16475+# define HAVE_MBSRTOWCS 1
16476+#endif
16477 #define HAVE_LIBINTL_H 1
16478 #define HAVE_WCTYPE_H 1
16479 #define HAVE_ISWCTYPE 1
16480Index: git/crypt/crypt_common.c
16481===================================================================
16482--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16483+++ git/crypt/crypt_common.c 2014-08-29 20:01:15.248070587 -0700
16484@@ -0,0 +1,42 @@
16485+/*
16486+ * crypt: crypt(3) implementation
16487+ *
16488+ * Copyright (C) 1991-2014 Free Software Foundation, Inc.
16489+ *
16490+ * This library is free software; you can redistribute it and/or
16491+ * modify it under the terms of the GNU Lesser General Public
16492+ * License as published by the Free Software Foundation; either
16493+ * version 2.1 of the License, or (at your option) any later version.
16494+ *
16495+ * This library is distributed in the hope that it will be useful,
16496+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16497+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16498+ * Lesser General Public License for more details.
16499+ *
16500+ * You should have received a copy of the GNU Lesser General Public
16501+ * License along with this library; see the file COPYING.LIB. If not,
16502+ * see <http://www.gnu.org/licenses/>.
16503+ *
16504+ * General Support routines
16505+ *
16506+ */
16507+
16508+#include "crypt-private.h"
16509+
16510+/* Table with characters for base64 transformation. */
16511+static const char b64t[64] =
16512+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
16513+
16514+void
16515+__b64_from_24bit (char **cp, int *buflen,
16516+ unsigned int b2, unsigned int b1, unsigned int b0,
16517+ int n)
16518+{
16519+ unsigned int w = (b2 << 16) | (b1 << 8) | b0;
16520+ while (n-- > 0 && (*buflen) > 0)
16521+ {
16522+ *(*cp)++ = b64t[w & 0x3f];
16523+ --(*buflen);
16524+ w >>= 6;
16525+ }
16526+}
16527Index: git/crypt/crypt_util.c
16528===================================================================
16529--- git.orig/crypt/crypt_util.c 2014-08-29 20:00:43.028070587 -0700
16530+++ git/crypt/crypt_util.c 2014-08-29 20:01:15.248070587 -0700
16531@@ -242,10 +242,6 @@
16532 */
16533 static ufc_long efp[16][64][2];
16534
16535-/* Table with characters for base64 transformation. */
16536-static const char b64t[64] =
16537-"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
16538-
16539 /*
16540 * For use by the old, non-reentrant routines
16541 * (crypt/encrypt/setkey)
16542@@ -949,17 +945,3 @@
16543 {
16544 __setkey_r(__key, &_ufc_foobar);
16545 }
16546-
16547-void
16548-__b64_from_24bit (char **cp, int *buflen,
16549- unsigned int b2, unsigned int b1, unsigned int b0,
16550- int n)
16551-{
16552- unsigned int w = (b2 << 16) | (b1 << 8) | b0;
16553- while (n-- > 0 && (*buflen) > 0)
16554- {
16555- *(*cp)++ = b64t[w & 0x3f];
16556- --(*buflen);
16557- w >>= 6;
16558- }
16559-}
16560Index: git/sysdeps/arm/Makefile
16561===================================================================
16562--- git.orig/sysdeps/arm/Makefile 2014-08-29 20:29:37.000000000 -0700
16563+++ git/sysdeps/arm/Makefile 2014-08-29 20:31:09.904070587 -0700
16564@@ -37,10 +37,13 @@
16565 # get offset to rtld_global._dl_hwcap
16566 gen-as-const-headers += rtld-global-offsets.sym tlsdesc.sym
16567 aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math
16568-aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \
16569+aeabi_routines = aeabi_assert aeabi_errno_addr \
16570 aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \
16571 aeabi_memmove aeabi_memset \
16572 aeabi_read_tp libc-aeabi_read_tp
16573+ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
16574+aeabi_routines += aeabi_localeconv
16575+endif
16576
16577 sysdep_routines += $(aeabi_constants) $(aeabi_routines)
16578 static-only-routines += $(aeabi_constants) aeabi_read_tp