about summary refs log tree commit diff
path: root/REORG.TODO/string
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/string')
-rw-r--r--REORG.TODO/string/Depend1
-rw-r--r--REORG.TODO/string/Makefile109
-rw-r--r--REORG.TODO/string/Versions88
-rw-r--r--REORG.TODO/string/_strerror.c74
-rw-r--r--REORG.TODO/string/argz-addsep.c58
-rw-r--r--REORG.TODO/string/argz-append.c49
-rw-r--r--REORG.TODO/string/argz-count.c38
-rw-r--r--REORG.TODO/string/argz-create.c53
-rw-r--r--REORG.TODO/string/argz-ctsep.c70
-rw-r--r--REORG.TODO/string/argz-delete.c41
-rw-r--r--REORG.TODO/string/argz-extract.c36
-rw-r--r--REORG.TODO/string/argz-insert.c63
-rw-r--r--REORG.TODO/string/argz-next.c39
-rw-r--r--REORG.TODO/string/argz-replace.c134
-rw-r--r--REORG.TODO/string/argz-stringify.c40
-rw-r--r--REORG.TODO/string/argz.h182
-rw-r--r--REORG.TODO/string/basename.c29
-rw-r--r--REORG.TODO/string/bcopy.c24
-rw-r--r--REORG.TODO/string/bits/string2.h119
-rw-r--r--REORG.TODO/string/bits/string3.h156
-rw-r--r--REORG.TODO/string/bits/strings_fortified.h34
-rw-r--r--REORG.TODO/string/bug-envz1.c75
-rw-r--r--REORG.TODO/string/bug-strcoll1.c24
-rw-r--r--REORG.TODO/string/bug-strcoll2.c91
-rw-r--r--REORG.TODO/string/bug-strncat1.c31
-rw-r--r--REORG.TODO/string/bug-strpbrk1.c19
-rw-r--r--REORG.TODO/string/bug-strspn1.c19
-rw-r--r--REORG.TODO/string/bug-strtok1.c44
-rw-r--r--REORG.TODO/string/byteswap.h39
-rw-r--r--REORG.TODO/string/bzero.c29
-rw-r--r--REORG.TODO/string/endian.h97
-rw-r--r--REORG.TODO/string/envz.c172
-rw-r--r--REORG.TODO/string/envz.h73
-rw-r--r--REORG.TODO/string/explicit_bzero.c38
-rw-r--r--REORG.TODO/string/ffs.c54
-rw-r--r--REORG.TODO/string/ffsll.c40
-rw-r--r--REORG.TODO/string/inl-tester.c6
-rw-r--r--REORG.TODO/string/memccpy.c42
-rw-r--r--REORG.TODO/string/memchr.c162
-rw-r--r--REORG.TODO/string/memcmp.c364
-rw-r--r--REORG.TODO/string/memcpy.c60
-rw-r--r--REORG.TODO/string/memfrob.c29
-rw-r--r--REORG.TODO/string/memmem.c81
-rw-r--r--REORG.TODO/string/memmove.c115
-rw-r--r--REORG.TODO/string/memory.h33
-rw-r--r--REORG.TODO/string/mempcpy.c39
-rw-r--r--REORG.TODO/string/memrchr.c200
-rw-r--r--REORG.TODO/string/memset.c88
-rw-r--r--REORG.TODO/string/noinl-tester.c4
-rw-r--r--REORG.TODO/string/rawmemchr.c41
-rw-r--r--REORG.TODO/string/stpcpy.c41
-rw-r--r--REORG.TODO/string/stpncpy.c51
-rw-r--r--REORG.TODO/string/str-two-way.h527
-rw-r--r--REORG.TODO/string/stratcliff.c561
-rw-r--r--REORG.TODO/string/strcasecmp.c67
-rw-r--r--REORG.TODO/string/strcasecmp_l.c22
-rw-r--r--REORG.TODO/string/strcasestr.c104
-rw-r--r--REORG.TODO/string/strcat.c33
-rw-r--r--REORG.TODO/string/strchr.c185
-rw-r--r--REORG.TODO/string/strchrnul.c166
-rw-r--r--REORG.TODO/string/strcmp.c47
-rw-r--r--REORG.TODO/string/strcoll.c39
-rw-r--r--REORG.TODO/string/strcoll_l.c363
-rw-r--r--REORG.TODO/string/strcpy.c33
-rw-r--r--REORG.TODO/string/strcspn.c72
-rw-r--r--REORG.TODO/string/strdup.c54
-rw-r--r--REORG.TODO/string/strerror.c43
-rw-r--r--REORG.TODO/string/strerror_l.c71
-rw-r--r--REORG.TODO/string/strfry.c52
-rw-r--r--REORG.TODO/string/string-inlines.c570
-rw-r--r--REORG.TODO/string/string.h544
-rw-r--r--REORG.TODO/string/strings.h147
-rw-r--r--REORG.TODO/string/strlen.c109
-rw-r--r--REORG.TODO/string/strncase.c69
-rw-r--r--REORG.TODO/string/strncase_l.c24
-rw-r--r--REORG.TODO/string/strncat.c39
-rw-r--r--REORG.TODO/string/strncmp.c74
-rw-r--r--REORG.TODO/string/strncpy.c34
-rw-r--r--REORG.TODO/string/strndup.c56
-rw-r--r--REORG.TODO/string/strnlen.c166
-rw-r--r--REORG.TODO/string/strpbrk.c33
-rw-r--r--REORG.TODO/string/strrchr.c53
-rw-r--r--REORG.TODO/string/strsep.c49
-rw-r--r--REORG.TODO/string/strsignal.c125
-rw-r--r--REORG.TODO/string/strspn.c76
-rw-r--r--REORG.TODO/string/strstr.c92
-rw-r--r--REORG.TODO/string/strtok.c35
-rw-r--r--REORG.TODO/string/strtok_r.c79
-rw-r--r--REORG.TODO/string/strverscmp.c107
-rw-r--r--REORG.TODO/string/strxfrm.c32
-rw-r--r--REORG.TODO/string/strxfrm_l.c747
-rw-r--r--REORG.TODO/string/swab.c33
-rw-r--r--REORG.TODO/string/test-bcopy.c20
-rw-r--r--REORG.TODO/string/test-bzero.c19
-rw-r--r--REORG.TODO/string/test-endian-types.c49
-rw-r--r--REORG.TODO/string/test-explicit_bzero.c20
-rw-r--r--REORG.TODO/string/test-ffs.c65
-rw-r--r--REORG.TODO/string/test-memccpy.c269
-rw-r--r--REORG.TODO/string/test-memchr.c227
-rw-r--r--REORG.TODO/string/test-memcmp.c525
-rw-r--r--REORG.TODO/string/test-memcpy.c259
-rw-r--r--REORG.TODO/string/test-memmem.c184
-rw-r--r--REORG.TODO/string/test-memmove.c290
-rw-r--r--REORG.TODO/string/test-mempcpy.c38
-rw-r--r--REORG.TODO/string/test-memrchr.c186
-rw-r--r--REORG.TODO/string/test-memset.c267
-rw-r--r--REORG.TODO/string/test-rawmemchr.c165
-rw-r--r--REORG.TODO/string/test-stpcpy.c52
-rw-r--r--REORG.TODO/string/test-stpncpy.c79
-rw-r--r--REORG.TODO/string/test-strcasecmp.c270
-rw-r--r--REORG.TODO/string/test-strcasestr.c194
-rw-r--r--REORG.TODO/string/test-strcat.c272
-rw-r--r--REORG.TODO/string/test-strchr.c296
-rw-r--r--REORG.TODO/string/test-strchrnul.c21
-rw-r--r--REORG.TODO/string/test-strcmp.c409
-rw-r--r--REORG.TODO/string/test-strcpy.c245
-rw-r--r--REORG.TODO/string/test-strcspn.c81
-rw-r--r--REORG.TODO/string/test-string.h219
-rw-r--r--REORG.TODO/string/test-strlen.c167
-rw-r--r--REORG.TODO/string/test-strncasecmp.c353
-rw-r--r--REORG.TODO/string/test-strncat.c322
-rw-r--r--REORG.TODO/string/test-strncmp.c479
-rw-r--r--REORG.TODO/string/test-strncpy.c323
-rw-r--r--REORG.TODO/string/test-strnlen.c248
-rw-r--r--REORG.TODO/string/test-strpbrk.c267
-rw-r--r--REORG.TODO/string/test-strrchr.c247
-rw-r--r--REORG.TODO/string/test-strspn.c245
-rw-r--r--REORG.TODO/string/test-strstr.c212
-rw-r--r--REORG.TODO/string/testcopy.c107
-rw-r--r--REORG.TODO/string/tester.c1685
-rw-r--r--REORG.TODO/string/tst-bswap.c75
-rw-r--r--REORG.TODO/string/tst-cmp.c212
-rw-r--r--REORG.TODO/string/tst-endian.c134
-rw-r--r--REORG.TODO/string/tst-inlcall.c84
-rw-r--r--REORG.TODO/string/tst-strcoll-overflow.c54
-rw-r--r--REORG.TODO/string/tst-strfry.c14
-rw-r--r--REORG.TODO/string/tst-strlen.c57
-rw-r--r--REORG.TODO/string/tst-strtok.c25
-rw-r--r--REORG.TODO/string/tst-strtok_r.c38
-rw-r--r--REORG.TODO/string/tst-strxfrm.c73
-rw-r--r--REORG.TODO/string/tst-strxfrm2.c84
-rw-r--r--REORG.TODO/string/tst-svc.c47
-rw-r--r--REORG.TODO/string/tst-svc.expect33
-rw-r--r--REORG.TODO/string/tst-svc.input33
-rw-r--r--REORG.TODO/string/tst-svc2.c61
-rw-r--r--REORG.TODO/string/tst-xbzero-opt.c298
-rw-r--r--REORG.TODO/string/wordcopy.c416
-rw-r--r--REORG.TODO/string/xpg-strerror.c53
148 files changed, 20537 insertions, 0 deletions
diff --git a/REORG.TODO/string/Depend b/REORG.TODO/string/Depend
new file mode 100644
index 0000000000..f3e1156a4e
--- /dev/null
+++ b/REORG.TODO/string/Depend
@@ -0,0 +1 @@
+localedata
diff --git a/REORG.TODO/string/Makefile b/REORG.TODO/string/Makefile
new file mode 100644
index 0000000000..f317d02a8c
--- /dev/null
+++ b/REORG.TODO/string/Makefile
@@ -0,0 +1,109 @@
+# Copyright (C) 1991-2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+#
+#	Sub-makefile for string portion of library.
+#
+subdir	:= string
+
+include ../Makeconfig
+
+headers	:= string.h strings.h memory.h endian.h bits/endian.h \
+	   argz.h envz.h byteswap.h bits/byteswap.h bits/byteswap-16.h \
+	   bits/string.h bits/string2.h bits/string3.h \
+	   bits/strings_fortified.h bits/uintn-identity.h
+
+routines	:= strcat strchr strcmp strcoll strcpy strcspn		\
+		   strverscmp strdup strndup				\
+		   strerror _strerror strlen strnlen			\
+		   strncat strncmp strncpy				\
+		   strrchr strpbrk strsignal strspn strstr strtok	\
+		   strtok_r strxfrm memchr memcmp memmove memset	\
+		   mempcpy bcopy bzero ffs ffsll stpcpy stpncpy		\
+		   strcasecmp strncase strcasecmp_l strncase_l		\
+		   memccpy memcpy wordcopy strsep strcasestr		\
+		   swab strfry memfrob memmem rawmemchr strchrnul	\
+		   $(addprefix argz-,append count create ctsep next	\
+				     delete extract insert stringify	\
+				     addsep replace)			\
+		   envz basename					\
+		   strcoll_l strxfrm_l string-inlines memrchr		\
+		   xpg-strerror strerror_l explicit_bzero
+
+strop-tests	:= memchr memcmp memcpy memmove mempcpy memset memccpy	\
+		   stpcpy stpncpy strcat strchr strcmp strcpy strcspn	\
+		   strlen strncmp strncpy strpbrk strrchr strspn memmem	\
+		   strstr strcasestr strnlen strcasecmp strncasecmp	\
+		   strncat rawmemchr strchrnul bcopy bzero memrchr	\
+		   explicit_bzero
+tests		:= tester inl-tester noinl-tester testcopy test-ffs	\
+		   tst-strlen stratcliff tst-svc tst-inlcall		\
+		   bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap	\
+		   tst-strtok tst-strxfrm bug-strcoll1 tst-strfry	\
+		   bug-strtok1 $(addprefix test-,$(strop-tests))	\
+		   bug-envz1 tst-strxfrm2 tst-endian tst-svc2		\
+		   tst-strtok_r bug-strcoll2 tst-cmp tst-xbzero-opt	\
+		   test-endian-types
+
+# This test allocates a lot of memory and can run for a long time.
+xtests = tst-strcoll-overflow
+
+ifeq ($(run-built-tests),yes)
+tests-special += $(objpfx)tst-svc-cmp.out
+endif
+
+include ../Rules
+
+CFLAGS-inl-tester.c = -fno-builtin
+CFLAGS-noinl-tester.c = -fno-builtin
+CFLAGS-tst-strlen.c = -fno-builtin
+CFLAGS-stratcliff.c = -fno-builtin
+CFLAGS-test-ffs.c = -fno-builtin
+CFLAGS-tst-inlcall.c = -fno-builtin
+CFLAGS-tst-xbzero-opt.c = -O3
+# BZ 21006: Resolve all functions but at least explicit_bzero at startup.
+# Otherwise the test fails on s390x as the memcpy in prepare_test_buffer is
+# done by loading r4 / r5 with the test_pattern and using store multiple
+# instruction to store r4 / r5 to buf.  If explicit_bzero would be resolved in
+# setup_explicit_clear, r4 / r5 would be stored to stack by _dl_runtime_resolve
+# and the call to memmem in count_test_patterns will find a hit of the
+# test_pattern on the stack.
+LDFLAGS-tst-xbzero-opt = -z now
+
+# Called during TLS initialization.
+CFLAGS-memcpy.c = $(no-stack-protector)
+CFLAGS-wordcopy.c = $(no-stack-protector)
+
+ifeq ($(run-built-tests),yes)
+$(objpfx)tst-svc-cmp.out: tst-svc.expect $(objpfx)tst-svc.out
+	cmp $^ > $@; \
+	$(evaluate-test)
+
+LOCALES := de_DE.UTF-8 en_US.ISO-8859-1 en_US.UTF-8 \
+           tr_TR.ISO-8859-9 tr_TR.UTF-8 cs_CZ.UTF-8 \
+	   da_DK.ISO-8859-1 en_GB.UTF-8
+include ../gen-locales.mk
+
+$(objpfx)test-strcasecmp.out: $(gen-locales)
+$(objpfx)test-strncasecmp.out: $(gen-locales)
+$(objpfx)tst-strxfrm.out: $(gen-locales)
+$(objpfx)tst-strxfrm2.out: $(gen-locales)
+# bug-strcoll2 needs cs_CZ.UTF-8 and da_DK.ISO-8859-1.
+$(objpfx)bug-strcoll2.out: $(gen-locales)
+$(objpfx)tst-strcoll-overflow.out: $(gen-locales)
+
+endif
diff --git a/REORG.TODO/string/Versions b/REORG.TODO/string/Versions
new file mode 100644
index 0000000000..9b709d12a9
--- /dev/null
+++ b/REORG.TODO/string/Versions
@@ -0,0 +1,88 @@
+libc {
+  GLIBC_2.0 {
+    # functions with required interface outside normal name space
+    __argz_count; __argz_stringify; __argz_next;
+
+    # functions used in inline functions or macros
+    __bzero; __strtok_r;
+
+    # functions used in other libraries
+    __ffs; __mempcpy; __stpncpy; __stpcpy; __strcasecmp; __strdup;
+    __strerror_r;
+
+    # a*
+    argz_add; argz_add_sep; argz_append; argz_count; argz_create;
+    argz_create_sep; argz_delete; argz_extract; argz_insert; argz_next;
+    argz_replace; argz_stringify;
+
+    # b*
+    basename; bcmp; bcopy; bzero;
+
+    # e*
+    envz_add; envz_entry; envz_get; envz_merge; envz_remove;
+    envz_strip;
+
+    # f*
+    ffs;
+
+    # i*
+    index;
+
+    # m*
+    memccpy; memchr; memcmp; memcpy; memfrob; memmem; memmove; memset;
+
+    # r*
+    rindex;
+
+    # s*
+    stpcpy; stpncpy; strcasecmp; strcat; strchr; strcmp; strcoll; strcpy;
+    strcspn; strdup; strerror; strerror_r; strfry; strlen; strncasecmp;
+    strncat; strncmp; strncpy; strndup; strnlen; strpbrk; strrchr; strsep;
+    strsignal; strspn; strstr; strtok; strtok_r; strxfrm; swab;
+  }
+  GLIBC_2.1 {
+    # functions used in macros and other libraries
+    __rawmemchr; __strcasestr;
+
+    # f*
+    ffsl; ffsll;
+
+    # m*
+    mempcpy;
+
+    # r*
+    rawmemchr;
+
+    # s*
+    strcasestr; strverscmp;
+  }
+  GLIBC_2.1.1 {
+    # extern inline functions used by <bits/string2.h>
+    __mempcpy_small; __stpcpy_small; __strcspn_c1; __strcspn_c2; __strcspn_c3;
+    __strcpy_small; __strspn_c1; __strspn_c2; __strspn_c3; __strpbrk_c2;
+    __strpbrk_c3; __strsep_1c; __strsep_2c; __strsep_3c; __strsep_g;
+    __strtok_r_1c;
+
+    # s*
+    strchrnul; __strverscmp;
+  }
+  GLIBC_2.2 {
+    # functions used in macros.
+    __strndup;
+
+    # m*
+    memrchr;
+  }
+  GLIBC_2.3.4 {
+    # x*
+    __xpg_strerror_r;
+  }
+  GLIBC_2.6 {
+    strerror_l;
+  }
+  GLIBC_2.24 {
+  }
+  GLIBC_2.25 {
+    explicit_bzero;
+  }
+}
diff --git a/REORG.TODO/string/_strerror.c b/REORG.TODO/string/_strerror.c
new file mode 100644
index 0000000000..4d3a52d906
--- /dev/null
+++ b/REORG.TODO/string/_strerror.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <_itoa.h>
+
+/* It is critical here that we always use the `dcgettext' function for
+   the message translation.  Since <libintl.h> only defines the macro
+   `dgettext' to use `dcgettext' for optimizing programs this is not
+   always guaranteed.  */
+#ifndef dgettext
+# include <locale.h>		/* We need LC_MESSAGES.  */
+# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES)
+#endif
+
+/* Return a string describing the errno code in ERRNUM.  */
+char *
+__strerror_r (int errnum, char *buf, size_t buflen)
+{
+  if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal
+			|| _sys_errlist_internal[errnum] == NULL, 0))
+    {
+      /* Buffer we use to print the number in.  For a maximum size for
+	 `int' of 8 bytes we never need more than 20 digits.  */
+      char numbuf[21];
+      const char *unk = _("Unknown error ");
+      size_t unklen = strlen (unk);
+      char *p, *q;
+      bool negative = errnum < 0;
+
+      numbuf[20] = '\0';
+      p = _itoa_word (abs (errnum), &numbuf[20], 10, 0);
+
+      /* Now construct the result while taking care for the destination
+	 buffer size.  */
+      q = __mempcpy (buf, unk, MIN (unklen, buflen));
+      if (negative && unklen < buflen)
+	{
+	  *q++ = '-';
+	  ++unklen;
+	}
+      if (unklen < buflen)
+	memcpy (q, p, MIN ((size_t) (&numbuf[21] - p), buflen - unklen));
+
+      /* Terminate the string in any case.  */
+      if (buflen > 0)
+	buf[buflen - 1] = '\0';
+
+      return buf;
+    }
+
+  return (char *) _(_sys_errlist_internal[errnum]);
+}
+weak_alias (__strerror_r, strerror_r)
+libc_hidden_def (__strerror_r)
diff --git a/REORG.TODO/string/argz-addsep.c b/REORG.TODO/string/argz-addsep.c
new file mode 100644
index 0000000000..eab6d3ef17
--- /dev/null
+++ b/REORG.TODO/string/argz-addsep.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+error_t
+__argz_add_sep (char **argz, size_t *argz_len, const char *string, int delim)
+{
+  size_t nlen = strlen (string) + 1;
+
+  if (nlen > 1)
+    {
+      const char *rp;
+      char *wp;
+
+      *argz = (char *) realloc (*argz, *argz_len + nlen);
+      if (*argz == NULL)
+	return ENOMEM;
+
+      wp = *argz + *argz_len;
+      rp = string;
+      do
+	if (*rp == delim)
+	  {
+	    if (wp > *argz && wp[-1] != '\0')
+	      *wp++ = '\0';
+	    else
+	      --nlen;
+	  }
+	else
+	  *wp++ = *rp;
+      while (*rp++ != '\0');
+
+      *argz_len += nlen;
+    }
+
+  return 0;
+}
+weak_alias (__argz_add_sep, argz_add_sep)
diff --git a/REORG.TODO/string/argz-append.c b/REORG.TODO/string/argz-append.c
new file mode 100644
index 0000000000..09015016e6
--- /dev/null
+++ b/REORG.TODO/string/argz-append.c
@@ -0,0 +1,49 @@
+/* Routines for dealing with '\0' separated arg vectors.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Add BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN.  */
+error_t
+__argz_append (char **argz, size_t *argz_len, const char *buf, size_t buf_len)
+{
+  size_t new_argz_len = *argz_len + buf_len;
+  char *new_argz = realloc (*argz, new_argz_len);
+  if (new_argz)
+    {
+      memcpy (new_argz + *argz_len, buf, buf_len);
+      *argz = new_argz;
+      *argz_len = new_argz_len;
+      return 0;
+    }
+  else
+    return ENOMEM;
+}
+weak_alias (__argz_append, argz_append)
+
+/* Add STR to the argz vector in ARGZ & ARGZ_LEN.  This should be moved into
+   argz.c in libshouldbelibc.  */
+error_t
+__argz_add (char **argz, size_t *argz_len, const char *str)
+{
+  return __argz_append (argz, argz_len, str, strlen (str) + 1);
+}
+weak_alias (__argz_add, argz_add)
diff --git a/REORG.TODO/string/argz-count.c b/REORG.TODO/string/argz-count.c
new file mode 100644
index 0000000000..64e2e69b12
--- /dev/null
+++ b/REORG.TODO/string/argz-count.c
@@ -0,0 +1,38 @@
+/* Routines for dealing with '\0' separated arg vectors.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+#include <string.h>
+
+/* Returns the number of strings in ARGZ.  */
+size_t
+__argz_count (const char *argz, size_t len)
+{
+  size_t count = 0;
+  while (len > 0)
+    {
+      size_t part_len = strlen(argz);
+      argz += part_len + 1;
+      len -= part_len + 1;
+      count++;
+    }
+  return count;
+}
+libc_hidden_def (__argz_count)
+weak_alias (__argz_count, argz_count)
diff --git a/REORG.TODO/string/argz-create.c b/REORG.TODO/string/argz-create.c
new file mode 100644
index 0000000000..f7d429b5b6
--- /dev/null
+++ b/REORG.TODO/string/argz-create.c
@@ -0,0 +1,53 @@
+/* Routines for dealing with '\0' separated arg vectors.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Make a '\0' separated arg vector from a unix argv vector, returning it in
+   ARGZ, and the total length in LEN.  If a memory allocation error occurs,
+   ENOMEM is returned, otherwise 0.  */
+error_t
+__argz_create (char *const argv[], char **argz, size_t *len)
+{
+  int argc;
+  size_t tlen = 0;
+  char *const *ap;
+  char *p;
+
+  for (argc = 0; argv[argc] != NULL; ++argc)
+    tlen += strlen (argv[argc]) + 1;
+
+  if (tlen == 0)
+    *argz = NULL;
+  else
+    {
+      *argz = malloc (tlen);
+      if (*argz == NULL)
+	return ENOMEM;
+
+      for (p = *argz, ap = argv; *ap; ++ap, ++p)
+	p = __stpcpy (p, *ap);
+    }
+  *len = tlen;
+
+  return 0;
+}
+weak_alias (__argz_create, argz_create)
diff --git a/REORG.TODO/string/argz-ctsep.c b/REORG.TODO/string/argz-ctsep.c
new file mode 100644
index 0000000000..7fc1511a4b
--- /dev/null
+++ b/REORG.TODO/string/argz-ctsep.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+error_t
+__argz_create_sep (const char *string, int delim, char **argz, size_t *len)
+{
+  size_t nlen = strlen (string) + 1;
+
+  if (nlen > 1)
+    {
+      const char *rp;
+      char *wp;
+
+      *argz = (char *) malloc (nlen);
+      if (*argz == NULL)
+	return ENOMEM;
+
+      rp = string;
+      wp = *argz;
+      do
+	if (*rp == delim)
+	  {
+	    if (wp > *argz && wp[-1] != '\0')
+	      *wp++ = '\0';
+	    else
+	      --nlen;
+	  }
+	else
+	  *wp++ = *rp;
+      while (*rp++ != '\0');
+
+      if (nlen == 0)
+	{
+	  free (*argz);
+	  *argz = NULL;
+	  *len = 0;
+	}
+
+      *len = nlen;
+    }
+  else
+    {
+      *argz = NULL;
+      *len = 0;
+    }
+
+  return 0;
+}
+weak_alias (__argz_create_sep, argz_create_sep)
diff --git a/REORG.TODO/string/argz-delete.c b/REORG.TODO/string/argz-delete.c
new file mode 100644
index 0000000000..183ac0d43c
--- /dev/null
+++ b/REORG.TODO/string/argz-delete.c
@@ -0,0 +1,41 @@
+/* Routines for dealing with '\0' separated arg vectors.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.org>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Delete ENTRY from ARGZ & ARGZ_LEN, if any.  */
+void
+argz_delete (char **argz, size_t *argz_len, char *entry)
+{
+  if (entry)
+    /* Get rid of the old value for NAME.  */
+    {
+      size_t entry_len = strlen (entry) + 1;
+      *argz_len -= entry_len;
+      memmove (entry, entry + entry_len, *argz_len - (entry - *argz));
+      if (*argz_len == 0)
+	{
+	  free (*argz);
+	  *argz = 0;
+	}
+    }
+}
+libc_hidden_def (argz_delete)
diff --git a/REORG.TODO/string/argz-extract.c b/REORG.TODO/string/argz-extract.c
new file mode 100644
index 0000000000..13345e894f
--- /dev/null
+++ b/REORG.TODO/string/argz-extract.c
@@ -0,0 +1,36 @@
+/* Routines for dealing with '\0' separated arg vectors.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.org>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+
+/* Puts pointers to each string in ARGZ, plus a terminating 0 element, into
+   ARGV, which must be large enough to hold them all.  */
+void
+__argz_extract (const char *argz, size_t len, char **argv)
+{
+  while (len > 0)
+    {
+      size_t part_len = strlen (argz);
+      *argv++ = (char *) argz;
+      argz += part_len + 1;
+      len -= part_len + 1;
+    }
+  *argv = 0;
+}
+weak_alias (__argz_extract, argz_extract)
diff --git a/REORG.TODO/string/argz-insert.c b/REORG.TODO/string/argz-insert.c
new file mode 100644
index 0000000000..e4c78407ff
--- /dev/null
+++ b/REORG.TODO/string/argz-insert.c
@@ -0,0 +1,63 @@
+/* Routines for dealing with '\0' separated arg vectors.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
+   existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
+   Since ARGZ's first entry is the same as ARGZ, argz_insert (ARGZ, ARGZ_LEN,
+   ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ.  If BEFORE is not
+   in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
+   ARGZ, ENOMEM is returned, else 0.  */
+error_t
+__argz_insert (char **argz, size_t *argz_len, char *before, const char *entry)
+{
+  if (! before)
+    return __argz_add (argz, argz_len, entry);
+
+  if (before < *argz || before >= *argz + *argz_len)
+    return EINVAL;
+
+  if (before > *argz)
+    /* Make sure before is actually the beginning of an entry.  */
+    while (before[-1])
+      before--;
+
+  {
+    size_t after_before = *argz_len - (before - *argz);
+    size_t entry_len = strlen  (entry) + 1;
+    size_t new_argz_len = *argz_len + entry_len;
+    char *new_argz = realloc (*argz, new_argz_len);
+
+    if (new_argz)
+      {
+	before = new_argz + (before - *argz);
+	memmove (before + entry_len, before, after_before);
+	memmove (before, entry, entry_len);
+	*argz = new_argz;
+	*argz_len = new_argz_len;
+	return 0;
+      }
+    else
+      return ENOMEM;
+  }
+}
+weak_alias (__argz_insert, argz_insert)
diff --git a/REORG.TODO/string/argz-next.c b/REORG.TODO/string/argz-next.c
new file mode 100644
index 0000000000..9c2fa33cc2
--- /dev/null
+++ b/REORG.TODO/string/argz-next.c
@@ -0,0 +1,39 @@
+/* Iterate through the elements of an argz block.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.org>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+#include <string.h>
+
+char *
+__argz_next (const char *argz, size_t argz_len, const char *entry)
+{
+  if (entry)
+    {
+      if (entry < argz + argz_len)
+	entry = strchr (entry, '\0') + 1;
+
+      return entry >= argz + argz_len ? NULL : (char *) entry;
+    }
+  else
+    if (argz_len > 0)
+      return (char *) argz;
+    else
+      return NULL;
+}
+weak_alias (__argz_next, argz_next)
diff --git a/REORG.TODO/string/argz-replace.c b/REORG.TODO/string/argz-replace.c
new file mode 100644
index 0000000000..6464e9bdbb
--- /dev/null
+++ b/REORG.TODO/string/argz-replace.c
@@ -0,0 +1,134 @@
+/* String replacement in an argz vector
+   Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <argz.h>
+
+/* Append BUF, of length BUF_LEN to *TO, of length *TO_LEN, reallocating and
+   updating *TO & *TO_LEN appropriately.  If an allocation error occurs,
+   *TO's old value is freed, and *TO is set to 0.  */
+static void
+str_append (char **to, size_t *to_len, const char *buf, const size_t buf_len)
+{
+  size_t new_len = *to_len + buf_len;
+  char *new_to = realloc (*to, new_len + 1);
+
+  if (new_to)
+    {
+      *((char *) __mempcpy (new_to + *to_len, buf, buf_len)) = '\0';
+      *to = new_to;
+      *to_len = new_len;
+    }
+  else
+    {
+      free (*to);
+      *to = 0;
+    }
+}
+
+/* Replace any occurrences of the string STR in ARGZ with WITH, reallocating
+   ARGZ as necessary.  If REPLACE_COUNT is non-zero, *REPLACE_COUNT will be
+   incremented by number of replacements performed.  */
+error_t
+__argz_replace (char **argz, size_t *argz_len, const char *str, const char *with,
+		unsigned *replace_count)
+{
+  error_t err = 0;
+
+  if (str && *str)
+    {
+      char *arg = 0;
+      char *src = *argz;
+      size_t src_len = *argz_len;
+      char *dst = 0;
+      size_t dst_len = 0;
+      int delayed_copy = 1;	/* True while we've avoided copying anything.  */
+      size_t str_len = strlen (str), with_len = strlen (with);
+
+      while (!err && (arg = argz_next (src, src_len, arg)))
+	{
+	  char *match = strstr (arg, str);
+	  if (match)
+	    {
+	      char *from = match + str_len;
+	      size_t to_len = match - arg;
+	      char *to = __strndup (arg, to_len);
+
+	      while (to && from)
+		{
+		  str_append (&to, &to_len, with, with_len);
+		  if (to)
+		    {
+		      match = strstr (from, str);
+		      if (match)
+			{
+			  str_append (&to, &to_len, from, match - from);
+			  from = match + str_len;
+			}
+		      else
+			{
+			  str_append (&to, &to_len, from, strlen (from));
+			  from = 0;
+			}
+		    }
+		}
+
+	      if (to)
+		{
+		  if (delayed_copy)
+		    /* We avoided copying SRC to DST until we found a match;
+                       now that we've done so, copy everything from the start
+                       of SRC.  */
+		    {
+		      if (arg > src)
+			err = __argz_append (&dst, &dst_len, src, (arg - src));
+		      delayed_copy = 0;
+		    }
+		  if (! err)
+		    err = __argz_add (&dst, &dst_len, to);
+		  free (to);
+		}
+	      else
+		err = ENOMEM;
+
+	      if (replace_count)
+		(*replace_count)++;
+	    }
+	  else if (! delayed_copy)
+	    err = __argz_add (&dst, &dst_len, arg);
+	}
+
+      if (! err)
+	{
+	  if (! delayed_copy)
+	    /* We never found any instances of str.  */
+	    {
+	      free (src);
+	      *argz = dst;
+	      *argz_len = dst_len;
+	    }
+	}
+      else if (dst_len > 0)
+	free (dst);
+    }
+
+  return err;
+}
+weak_alias (__argz_replace, argz_replace)
diff --git a/REORG.TODO/string/argz-stringify.c b/REORG.TODO/string/argz-stringify.c
new file mode 100644
index 0000000000..5499264d38
--- /dev/null
+++ b/REORG.TODO/string/argz-stringify.c
@@ -0,0 +1,40 @@
+/* Routines for dealing with '\0' separated arg vectors.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.org>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <argz.h>
+#include <string.h>
+
+/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
+   except the last into the character SEP.  */
+void
+__argz_stringify (char *argz, size_t len, int sep)
+{
+  if (len > 0)
+    while (1)
+      {
+	size_t part_len = __strnlen (argz, len);
+	argz += part_len;
+	len -= part_len;
+	if (len-- <= 1)		/* includes final '\0' we want to stop at */
+	  break;
+	*argz++ = sep;
+      }
+}
+libc_hidden_def (__argz_stringify)
+weak_alias (__argz_stringify, argz_stringify)
diff --git a/REORG.TODO/string/argz.h b/REORG.TODO/string/argz.h
new file mode 100644
index 0000000000..f9d0ac9950
--- /dev/null
+++ b/REORG.TODO/string/argz.h
@@ -0,0 +1,182 @@
+/* Routines for dealing with '\0' separated arg vectors.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ARGZ_H
+#define _ARGZ_H	1
+
+#include <features.h>
+
+#define __need_error_t
+#include <errno.h>
+#include <string.h>		/* Need size_t, and strchr is called below.  */
+
+#ifndef __error_t_defined
+typedef int error_t;
+#endif
+
+
+__BEGIN_DECLS
+
+/* Make a '\0' separated arg vector from a unix argv vector, returning it in
+   ARGZ, and the total length in LEN.  If a memory allocation error occurs,
+   ENOMEM is returned, otherwise 0.  The result can be destroyed using free. */
+extern error_t __argz_create (char *const __argv[], char **__restrict __argz,
+			      size_t *__restrict __len) __THROW;
+extern error_t argz_create (char *const __argv[], char **__restrict __argz,
+			    size_t *__restrict __len) __THROW;
+
+/* Make a '\0' separated arg vector from a SEP separated list in
+   STRING, returning it in ARGZ, and the total length in LEN.  If a
+   memory allocation error occurs, ENOMEM is returned, otherwise 0.
+   The result can be destroyed using free.  */
+extern error_t __argz_create_sep (const char *__restrict __string,
+				  int __sep, char **__restrict __argz,
+				  size_t *__restrict __len) __THROW;
+extern error_t argz_create_sep (const char *__restrict __string,
+				int __sep, char **__restrict __argz,
+				size_t *__restrict __len) __THROW;
+
+/* Returns the number of strings in ARGZ.  */
+extern size_t __argz_count (const char *__argz, size_t __len)
+     __THROW __attribute_pure__;
+extern size_t argz_count (const char *__argz, size_t __len)
+     __THROW __attribute_pure__;
+
+/* Puts pointers to each string in ARGZ into ARGV, which must be large enough
+   to hold them all.  */
+extern void __argz_extract (const char *__restrict __argz, size_t __len,
+			    char **__restrict __argv) __THROW;
+extern void argz_extract (const char *__restrict __argz, size_t __len,
+			  char **__restrict __argv) __THROW;
+
+/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
+   except the last into the character SEP.  */
+extern void __argz_stringify (char *__argz, size_t __len, int __sep) __THROW;
+extern void argz_stringify (char *__argz, size_t __len, int __sep) __THROW;
+
+/* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN.  */
+extern error_t __argz_append (char **__restrict __argz,
+			      size_t *__restrict __argz_len,
+			      const char *__restrict __buf, size_t __buf_len)
+     __THROW;
+extern error_t argz_append (char **__restrict __argz,
+			    size_t *__restrict __argz_len,
+			    const char *__restrict __buf, size_t __buf_len)
+     __THROW;
+
+/* Append STR to the argz vector in ARGZ & ARGZ_LEN.  */
+extern error_t __argz_add (char **__restrict __argz,
+			   size_t *__restrict __argz_len,
+			   const char *__restrict __str) __THROW;
+extern error_t argz_add (char **__restrict __argz,
+			 size_t *__restrict __argz_len,
+			 const char *__restrict __str) __THROW;
+
+/* Append SEP separated list in STRING to the argz vector in ARGZ &
+   ARGZ_LEN.  */
+extern error_t __argz_add_sep (char **__restrict __argz,
+			       size_t *__restrict __argz_len,
+			       const char *__restrict __string, int __delim)
+     __THROW;
+extern error_t argz_add_sep (char **__restrict __argz,
+			     size_t *__restrict __argz_len,
+			     const char *__restrict __string, int __delim)
+     __THROW;
+
+/* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there.  */
+extern void __argz_delete (char **__restrict __argz,
+			   size_t *__restrict __argz_len,
+			   char *__restrict __entry) __THROW;
+extern void argz_delete (char **__restrict __argz,
+			 size_t *__restrict __argz_len,
+			 char *__restrict __entry) __THROW;
+
+/* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
+   existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
+   Since ARGZ's first entry is the same as ARGZ, argz_insert (ARGZ, ARGZ_LEN,
+   ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ.  If BEFORE is not
+   in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
+   ARGZ, ENOMEM is returned, else 0.  */
+extern error_t __argz_insert (char **__restrict __argz,
+			      size_t *__restrict __argz_len,
+			      char *__restrict __before,
+			      const char *__restrict __entry) __THROW;
+extern error_t argz_insert (char **__restrict __argz,
+			    size_t *__restrict __argz_len,
+			    char *__restrict __before,
+			    const char *__restrict __entry) __THROW;
+
+/* Replace any occurrences of the string STR in ARGZ with WITH, reallocating
+   ARGZ as necessary.  If REPLACE_COUNT is non-zero, *REPLACE_COUNT will be
+   incremented by number of replacements performed.  */
+extern error_t __argz_replace (char **__restrict __argz,
+			       size_t *__restrict __argz_len,
+			       const char *__restrict __str,
+			       const char *__restrict __with,
+			       unsigned int *__restrict __replace_count);
+extern error_t argz_replace (char **__restrict __argz,
+			     size_t *__restrict __argz_len,
+			     const char *__restrict __str,
+			     const char *__restrict __with,
+			     unsigned int *__restrict __replace_count);
+
+/* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there
+   are no more.  If entry is NULL, then the first entry is returned.  This
+   behavior allows two convenient iteration styles:
+
+    char *entry = 0;
+    while ((entry = argz_next (argz, argz_len, entry)))
+      ...;
+
+   or
+
+    char *entry;
+    for (entry = argz; entry; entry = argz_next (argz, argz_len, entry))
+      ...;
+*/
+extern char *__argz_next (const char *__restrict __argz, size_t __argz_len,
+			  const char *__restrict __entry) __THROW;
+extern char *argz_next (const char *__restrict __argz, size_t __argz_len,
+			const char *__restrict __entry) __THROW;
+
+#ifdef __USE_EXTERN_INLINES
+__extern_inline char *
+__NTH (__argz_next (const char *__argz, size_t __argz_len,
+		    const char *__entry))
+{
+  if (__entry)
+    {
+      if (__entry < __argz + __argz_len)
+	__entry = strchr (__entry, '\0') + 1;
+
+      return __entry >= __argz + __argz_len ? (char *) NULL : (char *) __entry;
+    }
+  else
+    return __argz_len > 0 ? (char *) __argz : 0;
+}
+__extern_inline char *
+__NTH (argz_next (const char *__argz, size_t __argz_len,
+		  const char *__entry))
+{
+  return __argz_next (__argz, __argz_len, __entry);
+}
+#endif /* Use extern inlines.  */
+
+__END_DECLS
+
+#endif /* argz.h */
diff --git a/REORG.TODO/string/basename.c b/REORG.TODO/string/basename.c
new file mode 100644
index 0000000000..0f379680b7
--- /dev/null
+++ b/REORG.TODO/string/basename.c
@@ -0,0 +1,29 @@
+/* Return the name-within-directory of a file name.
+   Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+char *
+__basename (const char *filename)
+{
+  char *p = strrchr (filename, '/');
+  return p ? p + 1 : (char *) filename;
+}
+libc_hidden_def (__basename)
+weak_alias (__basename, basename)
+libc_hidden_weak (basename)
diff --git a/REORG.TODO/string/bcopy.c b/REORG.TODO/string/bcopy.c
new file mode 100644
index 0000000000..24fe494fec
--- /dev/null
+++ b/REORG.TODO/string/bcopy.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+void
+bcopy (const void *src, void *dest, size_t len)
+{
+  memmove (dest, src, len);
+}
diff --git a/REORG.TODO/string/bits/string2.h b/REORG.TODO/string/bits/string2.h
new file mode 100644
index 0000000000..6a26e2bc68
--- /dev/null
+++ b/REORG.TODO/string/bits/string2.h
@@ -0,0 +1,119 @@
+/* Machine-independant string function optimizations.
+   Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _STRING_H
+# error "Never use <bits/string2.h> directly; include <string.h> instead."
+#endif
+
+#ifndef __NO_STRING_INLINES
+
+/* Unlike the definitions in the header <bits/string.h> the
+   definitions contained here are not optimized down to assembler
+   level.  Those optimizations are not always a good idea since this
+   means the code size increases a lot.  Instead the definitions here
+   optimize some functions in a way which do not dramatically
+   increase the code size and which do not use assembler.  The main
+   trick is to use GCC's `__builtin_constant_p' function.
+
+   Every function XXX which has a defined version in
+   <bits/string.h> must be accompanied by a symbol _HAVE_STRING_ARCH_XXX
+   to make sure we don't get redefinitions.
+
+   We must use here macros instead of inline functions since the
+   trick won't work with the latter.  */
+
+#ifndef __STRING_INLINE
+# ifdef __cplusplus
+#  define __STRING_INLINE inline
+# else
+#  define __STRING_INLINE __extern_inline
+# endif
+#endif
+
+/* Dereferencing a pointer arg to run sizeof on it fails for the void
+   pointer case, so we use this instead.
+   Note that __x is evaluated twice. */
+#define __string2_1bptr_p(__x) \
+  ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1)
+
+/* Set N bytes of S to 0.  */
+#if !defined _HAVE_STRING_ARCH_memset
+# define __bzero(s, n) __builtin_memset (s, '\0', n)
+#endif
+
+
+/* Copy SRC to DEST, returning pointer to final NUL byte.  */
+#ifdef __USE_GNU
+# ifndef _HAVE_STRING_ARCH_stpcpy
+#  define __stpcpy(dest, src) __builtin_stpcpy (dest, src)
+/* In glibc we use this function frequently but for namespace reasons
+   we have to use the name `__stpcpy'.  */
+#  define stpcpy(dest, src) __stpcpy (dest, src)
+# endif
+#endif
+
+
+/* Copy no more than N characters of SRC to DEST.  */
+#ifndef _HAVE_STRING_ARCH_strncpy
+# define strncpy(dest, src, n) __builtin_strncpy (dest, src, n)
+#endif
+
+
+/* Append no more than N characters from SRC onto DEST.  */
+#ifndef _HAVE_STRING_ARCH_strncat
+# ifdef _USE_STRING_ARCH_strchr
+#  define strncat(dest, src, n) \
+  (__extension__ ({ char *__dest = (dest);				      \
+		    __builtin_constant_p (src) && __builtin_constant_p (n)    \
+		    ? (strlen (src) < ((size_t) (n))			      \
+		       ? strcat (__dest, src)				      \
+		       : (*((char *) __mempcpy (strchr (__dest, '\0'),	      \
+						src, n)) = '\0', __dest))     \
+		    : strncat (dest, src, n); }))
+# else
+#  define strncat(dest, src, n) __builtin_strncat (dest, src, n)
+# endif
+#endif
+
+
+/* Return the length of the initial segment of S which
+   consists entirely of characters not in REJECT.  */
+#ifndef _HAVE_STRING_ARCH_strcspn
+# define strcspn(s, reject) __builtin_strcspn (s, reject)
+#endif
+
+
+/* Return the length of the initial segment of S which
+   consists entirely of characters in ACCEPT.  */
+#ifndef _HAVE_STRING_ARCH_strspn
+# define strspn(s, accept) __builtin_strspn (s, accept)
+#endif
+
+
+/* Find the first occurrence in S of any character in ACCEPT.  */
+#ifndef _HAVE_STRING_ARCH_strpbrk
+# define strpbrk(s, accept) __builtin_strpbrk (s, accept)
+#endif
+
+
+#ifndef _FORCE_INLINES
+# undef __STRING_INLINE
+#endif
+
+#endif /* No string inlines.  */
diff --git a/REORG.TODO/string/bits/string3.h b/REORG.TODO/string/bits/string3.h
new file mode 100644
index 0000000000..738226d49b
--- /dev/null
+++ b/REORG.TODO/string/bits/string3.h
@@ -0,0 +1,156 @@
+/* Copyright (C) 2004-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _STRING_H
+# error "Never use <bits/string3.h> directly; include <string.h> instead."
+#endif
+
+#if !__GNUC_PREREQ (5,0)
+__warndecl (__warn_memset_zero_len,
+	    "memset used with constant zero length parameter; this could be due to transposed parameters");
+#endif
+
+#ifndef __cplusplus
+/* XXX This is temporarily.  We should not redefine any of the symbols
+   and instead integrate the error checking into the original
+   definitions.  */
+# undef memcpy
+# undef memmove
+# undef memset
+# undef strcat
+# undef strcpy
+# undef strncat
+# undef strncpy
+# ifdef __USE_GNU
+#  undef mempcpy
+#  undef stpcpy
+# endif
+# ifdef __USE_MISC
+#  undef bcopy
+#  undef bzero
+# endif
+#endif
+
+
+__fortify_function void *
+__NTH (memcpy (void *__restrict __dest, const void *__restrict __src,
+	       size_t __len))
+{
+  return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
+}
+
+__fortify_function void *
+__NTH (memmove (void *__dest, const void *__src, size_t __len))
+{
+  return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
+}
+
+#ifdef __USE_GNU
+__fortify_function void *
+__NTH (mempcpy (void *__restrict __dest, const void *__restrict __src,
+		size_t __len))
+{
+  return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest));
+}
+#endif
+
+
+/* The first two tests here help to catch a somewhat common problem
+   where the second and third parameter are transposed.  This is
+   especially problematic if the intended fill value is zero.  In this
+   case no work is done at all.  We detect these problems by referring
+   non-existing functions.  */
+__fortify_function void *
+__NTH (memset (void *__dest, int __ch, size_t __len))
+{
+  /* GCC-5.0 and newer implements these checks in the compiler, so we don't
+     need them here.  */
+#if !__GNUC_PREREQ (5,0)
+  if (__builtin_constant_p (__len) && __len == 0
+      && (!__builtin_constant_p (__ch) || __ch != 0))
+    {
+      __warn_memset_zero_len ();
+      return __dest;
+    }
+#endif
+  return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
+}
+
+#ifdef __USE_MISC
+# include <bits/strings_fortified.h>
+
+void __explicit_bzero_chk (void *__dest, size_t __len, size_t __destlen)
+  __THROW __nonnull ((1));
+
+__fortify_function void
+__NTH (explicit_bzero (void *__dest, size_t __len))
+{
+  __explicit_bzero_chk (__dest, __len, __bos0 (__dest));
+}
+#endif
+
+__fortify_function char *
+__NTH (strcpy (char *__restrict __dest, const char *__restrict __src))
+{
+  return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
+}
+
+#ifdef __USE_GNU
+__fortify_function char *
+__NTH (stpcpy (char *__restrict __dest, const char *__restrict __src))
+{
+  return __builtin___stpcpy_chk (__dest, __src, __bos (__dest));
+}
+#endif
+
+
+__fortify_function char *
+__NTH (strncpy (char *__restrict __dest, const char *__restrict __src,
+		size_t __len))
+{
+  return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
+}
+
+/* XXX We have no corresponding builtin yet.  */
+extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
+			    size_t __destlen) __THROW;
+extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src,
+					       size_t __n), stpncpy);
+
+__fortify_function char *
+__NTH (stpncpy (char *__dest, const char *__src, size_t __n))
+{
+  if (__bos (__dest) != (size_t) -1
+      && (!__builtin_constant_p (__n) || __n > __bos (__dest)))
+    return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
+  return __stpncpy_alias (__dest, __src, __n);
+}
+
+
+__fortify_function char *
+__NTH (strcat (char *__restrict __dest, const char *__restrict __src))
+{
+  return __builtin___strcat_chk (__dest, __src, __bos (__dest));
+}
+
+
+__fortify_function char *
+__NTH (strncat (char *__restrict __dest, const char *__restrict __src,
+		size_t __len))
+{
+  return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
+}
diff --git a/REORG.TODO/string/bits/strings_fortified.h b/REORG.TODO/string/bits/strings_fortified.h
new file mode 100644
index 0000000000..411e7863d6
--- /dev/null
+++ b/REORG.TODO/string/bits/strings_fortified.h
@@ -0,0 +1,34 @@
+/* Fortify macros for strings.h functions.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef __STRINGS_FORTIFIED
+# define __STRINGS_FORTIFIED 1
+
+__fortify_function void
+__NTH (bcopy (const void *__src, void *__dest, size_t __len))
+{
+  (void) __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
+}
+
+__fortify_function void
+__NTH (bzero (void *__dest, size_t __len))
+{
+  (void) __builtin___memset_chk (__dest, '\0', __len, __bos0 (__dest));
+}
+
+#endif
diff --git a/REORG.TODO/string/bug-envz1.c b/REORG.TODO/string/bug-envz1.c
new file mode 100644
index 0000000000..931a0559fe
--- /dev/null
+++ b/REORG.TODO/string/bug-envz1.c
@@ -0,0 +1,75 @@
+/* Test for bug BZ #2703.  */
+#include <stdio.h>
+#include <envz.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const struct
+{
+  const char *s;
+  int in_result;
+} strs[] =
+{
+  { "a=1", 1 },
+  { "b=2", 1 },
+  { "(*)", 0 },
+  { "(*)", 0 },
+  { "e=5", 1 },
+  { "f=", 1 },
+  { "(*)", 0 },
+  { "h=8", 1 },
+  { "i=9", 1 },
+  { "j", 0 }
+};
+
+#define nstrs (sizeof (strs) / sizeof (strs[0]))
+
+
+int
+do_test (void)
+{
+
+  size_t size = 0;
+  char *str = malloc (100);
+  if (str == NULL)
+    {
+      puts ("out of memory");
+      return 1;
+    }
+
+  char **argz = &str;
+
+  for (int i = 0; i < nstrs; ++i)
+    argz_add_sep (argz, &size, strs[i].s, '\0');
+
+  printf ("calling envz_strip with size=%zu\n", size);
+  envz_strip (argz, &size);
+
+  int result = 0;
+  printf ("new size=%zu\n", size);
+  for (int i = 0; i < nstrs; ++i)
+    if (strs[i].in_result)
+      {
+        char name[2];
+        name[0] = strs[i].s[0];
+        name[1] = '\0';
+
+        char *e = envz_entry (*argz, size, name);
+        if (e == NULL)
+          {
+            printf ("entry '%s' not found\n", name);
+            result = 1;
+          }
+        else if (strcmp (e, strs[i].s) != 0)
+          {
+            printf ("entry '%s' does not match: is '%s', expected '%s'\n",
+                    name, e, strs[i].s);
+            result = 1;
+          }
+      }
+
+  free (*argz);
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/bug-strcoll1.c b/REORG.TODO/string/bug-strcoll1.c
new file mode 100644
index 0000000000..b6510d926f
--- /dev/null
+++ b/REORG.TODO/string/bug-strcoll1.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+
+int
+main (void)
+{
+  const char t1[] = "0-0-0-0-0-0-0-0-0-0.COM";
+  const char t2[] = "00000-00000.COM";
+  int res1;
+  int res2;
+
+  setlocale (LC_ALL, "en_US.ISO-8859-1");
+
+  res1 = strcoll (t1, t2);
+  printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, res1);
+  res2 = strcoll (t2, t1);
+  printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, res2);
+
+  return ((res1 == 0 && res2 != 0)
+	  || (res1 != 0 && res2 == 0)
+	  || (res1 < 0 && res2 < 0)
+	  || (res1 > 0 && res2 > 0));
+}
diff --git a/REORG.TODO/string/bug-strcoll2.c b/REORG.TODO/string/bug-strcoll2.c
new file mode 100644
index 0000000000..ff33007df6
--- /dev/null
+++ b/REORG.TODO/string/bug-strcoll2.c
@@ -0,0 +1,91 @@
+/* Bug 18589: sort-test.sh fails at random.
+   Copyright (C) 2015-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+
+/* An incorrect strcoll optimization resulted in incorrect
+   results from strcoll for cs_CZ and da_DK.  */
+
+int
+test_cs_CZ (void)
+{
+  const char t1[] = "config";
+  const char t2[] = "choose";
+  if (setlocale (LC_ALL, "cs_CZ.UTF-8") == NULL)
+    {
+      perror ("setlocale");
+      return 1;
+    }
+  /* In Czech the digraph ch sorts after c, therefore we expect
+     config to sort before choose.  */
+  int a = strcoll (t1, t2);
+  int b = strcoll (t2, t1);
+  printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a);
+  printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b);
+  if (a < 0 && b > 0)
+    {
+      puts ("PASS: config < choose");
+      return 0;
+    }
+  else
+    {
+      puts ("FAIL: Wrong sorting in cs_CZ.UTF-8.");
+      return 1;
+    }
+}
+
+int
+test_da_DK (void)
+{
+  const char t1[] = "AS";
+  const char t2[] = "AA";
+  if (setlocale (LC_ALL, "da_DK.ISO-8859-1") == NULL)
+    {
+      perror ("setlocale");
+      return 1;
+    }
+  /* AA should be treated as the last letter of the Danish alphabet,
+     hence sorting after AS.  */
+  int a = strcoll (t1, t2);
+  int b = strcoll (t2, t1);
+  printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a);
+  printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b);
+  if (a < 0 && b > 0)
+    {
+      puts ("PASS: AS < AA");
+      return 0;
+    }
+  else
+    {
+      puts ("FAIL: Wrong sorting in da_DK.ISO-8859-1");
+      return 1;
+    }
+}
+
+int
+do_test (void)
+{
+  int err = 0;
+  err |= test_cs_CZ ();
+  err |= test_da_DK ();
+  return err;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/bug-strncat1.c b/REORG.TODO/string/bug-strncat1.c
new file mode 100644
index 0000000000..f1b5c37c5c
--- /dev/null
+++ b/REORG.TODO/string/bug-strncat1.c
@@ -0,0 +1,31 @@
+/* Test case by Joseph S. Myers <jsm28@cam.ac.uk>.  */
+#undef __USE_STRING_INLINES
+#define __USE_STRING_INLINES
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char d[3] = "\0\1\2";
+
+int
+main (void)
+{
+  strncat (d, "\5\6", 1);
+  if (d[0] != '\5')
+    {
+      puts ("d[0] != '\\5'");
+      exit (1);
+    }
+  if (d[1] != '\0')
+    {
+      puts ("d[1] != '\\0'");
+      exit (1);
+    }
+  if (d[2] != '\2')
+    {
+      puts ("d[2] != '\\2'");
+      exit (1);
+    }
+
+  return 0;
+}
diff --git a/REORG.TODO/string/bug-strpbrk1.c b/REORG.TODO/string/bug-strpbrk1.c
new file mode 100644
index 0000000000..28238b0f50
--- /dev/null
+++ b/REORG.TODO/string/bug-strpbrk1.c
@@ -0,0 +1,19 @@
+/* Test case by Joseph S. Myers <jsm28@cam.ac.uk>.  */
+#undef __USE_STRING_INLINES
+#define __USE_STRING_INLINES
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+  const char *a = "abc";
+  const char *b = a;
+
+  strpbrk (b++, "");
+  if (b != a + 1)
+    return 1;
+
+  return 0;
+}
diff --git a/REORG.TODO/string/bug-strspn1.c b/REORG.TODO/string/bug-strspn1.c
new file mode 100644
index 0000000000..a657bafc43
--- /dev/null
+++ b/REORG.TODO/string/bug-strspn1.c
@@ -0,0 +1,19 @@
+/* Test case by Joseph S. Myers <jsm28@cam.ac.uk>.  */
+#undef __USE_STRING_INLINES
+#define __USE_STRING_INLINES
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+  const char *a = "abc";
+  const char *b = a;
+
+  strspn (b++, "");
+  if (b != a + 1)
+    return 1;
+
+  return 0;
+}
diff --git a/REORG.TODO/string/bug-strtok1.c b/REORG.TODO/string/bug-strtok1.c
new file mode 100644
index 0000000000..a47b2f3531
--- /dev/null
+++ b/REORG.TODO/string/bug-strtok1.c
@@ -0,0 +1,44 @@
+/* See BZ #2126.  */
+#include <string.h>
+#include <stdio.h>
+
+int
+do_test (void)
+{
+  const char str[] = "axaaba";
+  char *token;
+  char *cp;
+  char *l;
+  int result = 0;
+
+  puts ("test strtok");
+  cp = strdupa (str);
+  printf ("cp = %p, len = %zu\n", cp, strlen (cp));
+  token = strtok (cp, "ab");
+  result |= token == NULL || strcmp (token, "x");
+  printf ("token: %s (%d)\n", token ? token : "NULL", result);
+  token = strtok(0, "ab");
+  result |= token != NULL;
+  printf ("token: %s (%d)\n", token ? token : "NULL", result);
+  token = strtok(0, "a");
+  result |= token != NULL;
+  printf ("token: %s (%d)\n", token ? token : "NULL", result);
+
+  puts ("test strtok_r");
+  cp = strdupa (str);
+  size_t len = strlen (cp);
+  printf ("cp = %p, len = %zu\n", cp, len);
+  token = strtok_r (cp, "ab", &l);
+  result |= token == NULL || strcmp (token, "x");
+  printf ("token: %s, next = %p (%d)\n", token ? token : "NULL", l, result);
+  token = strtok_r(0, "ab", &l);
+  result |= token != NULL || l != cp + len;
+  printf ("token: %s, next = %p (%d)\n", token ? token : "NULL", l, result);
+  token = strtok_r(0, "a", &l);
+  result |= token != NULL || l != cp + len;
+  printf ("token: %s,  next = %p (%d)\n", token ? token : "NULL", l, result);
+
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/byteswap.h b/REORG.TODO/string/byteswap.h
new file mode 100644
index 0000000000..4ec8ac7713
--- /dev/null
+++ b/REORG.TODO/string/byteswap.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BYTESWAP_H
+#define _BYTESWAP_H	1
+
+#include <features.h>
+
+/* Get the machine specific, optimized definitions.  */
+#include <bits/byteswap.h>
+
+
+/* The following definitions must all be macros since otherwise some
+   of the possible optimizations are not possible.  */
+
+/* Return a value with all bytes in the 16 bit argument swapped.  */
+#define bswap_16(x) __bswap_16 (x)
+
+/* Return a value with all bytes in the 32 bit argument swapped.  */
+#define bswap_32(x) __bswap_32 (x)
+
+/* Return a value with all bytes in the 64 bit argument swapped.  */
+#define bswap_64(x) __bswap_64 (x)
+
+#endif /* byteswap.h */
diff --git a/REORG.TODO/string/bzero.c b/REORG.TODO/string/bzero.c
new file mode 100644
index 0000000000..9de1f89d10
--- /dev/null
+++ b/REORG.TODO/string/bzero.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#undef __bzero
+
+/* Set N bytes of S to 0.  */
+void
+__bzero (void *s, size_t len)
+{
+  memset (s, '\0', len);
+}
+weak_alias (__bzero, bzero)
diff --git a/REORG.TODO/string/endian.h b/REORG.TODO/string/endian.h
new file mode 100644
index 0000000000..dcc9a65df7
--- /dev/null
+++ b/REORG.TODO/string/endian.h
@@ -0,0 +1,97 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_ENDIAN_H
+#define	_ENDIAN_H	1
+
+#include <features.h>
+
+/* Definitions for byte order, according to significance of bytes,
+   from low addresses to high addresses.  The value is what you get by
+   putting '4' in the most significant byte, '3' in the second most
+   significant byte, '2' in the second least significant byte, and '1'
+   in the least significant byte, and then writing down one digit for
+   each byte, starting with the byte at the lowest address at the left,
+   and proceeding to the byte with the highest address at the right.  */
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+#define	__PDP_ENDIAN	3412
+
+/* This file defines `__BYTE_ORDER' for the particular machine.  */
+#include <bits/endian.h>
+
+/* Some machines may need to use a different endianness for floating point
+   values.  */
+#ifndef __FLOAT_WORD_ORDER
+# define __FLOAT_WORD_ORDER __BYTE_ORDER
+#endif
+
+#ifdef	__USE_MISC
+# define LITTLE_ENDIAN	__LITTLE_ENDIAN
+# define BIG_ENDIAN	__BIG_ENDIAN
+# define PDP_ENDIAN	__PDP_ENDIAN
+# define BYTE_ORDER	__BYTE_ORDER
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define __LONG_LONG_PAIR(HI, LO) LO, HI
+#elif __BYTE_ORDER == __BIG_ENDIAN
+# define __LONG_LONG_PAIR(HI, LO) HI, LO
+#endif
+
+
+#if defined __USE_MISC && !defined __ASSEMBLER__
+/* Conversion interfaces.  */
+# include <bits/byteswap.h>
+# include <bits/uintn-identity.h>
+
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#  define htobe16(x) __bswap_16 (x)
+#  define htole16(x) __uint16_identity (x)
+#  define be16toh(x) __bswap_16 (x)
+#  define le16toh(x) __uint16_identity (x)
+
+#  define htobe32(x) __bswap_32 (x)
+#  define htole32(x) __uint32_identity (x)
+#  define be32toh(x) __bswap_32 (x)
+#  define le32toh(x) __uint32_identity (x)
+
+#  define htobe64(x) __bswap_64 (x)
+#  define htole64(x) __uint64_identity (x)
+#  define be64toh(x) __bswap_64 (x)
+#  define le64toh(x) __uint64_identity (x)
+
+# else
+#  define htobe16(x) __uint16_identity (x)
+#  define htole16(x) __bswap_16 (x)
+#  define be16toh(x) __uint16_identity (x)
+#  define le16toh(x) __bswap_16 (x)
+
+#  define htobe32(x) __uint32_identity (x)
+#  define htole32(x) __bswap_32 (x)
+#  define be32toh(x) __uint32_identity (x)
+#  define le32toh(x) __bswap_32 (x)
+
+#  define htobe64(x) __uint64_identity (x)
+#  define htole64(x) __bswap_64 (x)
+#  define be64toh(x) __uint64_identity (x)
+#  define le64toh(x) __bswap_64 (x)
+# endif
+#endif
+
+#endif	/* endian.h */
diff --git a/REORG.TODO/string/envz.c b/REORG.TODO/string/envz.c
new file mode 100644
index 0000000000..02fb5cc28a
--- /dev/null
+++ b/REORG.TODO/string/envz.c
@@ -0,0 +1,172 @@
+/* Routines for dealing with '\0' separated environment vectors
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.org>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <malloc.h>
+#include <string.h>
+
+#include <envz.h>
+
+/* The character separating names from values in an envz.  */
+#define SEP '='
+
+/* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none.
+   If NAME contains the separator character, only the portion before it is
+   used in the comparison.  */
+char *
+envz_entry (const char *envz, size_t envz_len, const char *name)
+{
+  while (envz_len)
+    {
+      const char *p = name;
+      const char *entry = envz;	/* Start of this entry. */
+
+      /* See how far NAME and ENTRY match.  */
+      while (envz_len && *p == *envz && *p && *p != SEP)
+	p++, envz++, envz_len--;
+
+      if ((*envz == '\0' || *envz == SEP) && (*p == '\0' || *p == SEP))
+	/* Bingo! */
+	return (char *) entry;
+
+      /* No match, skip to the next entry.  */
+      while (envz_len && *envz)
+	envz++, envz_len--;
+      if (envz_len)
+	envz++, envz_len--;	/* skip '\0' */
+    }
+
+  return 0;
+}
+libc_hidden_def (envz_entry)
+
+/* Returns a pointer to the value portion of the entry in ENVZ for NAME, or 0
+   if there is none.  */
+char *
+envz_get (const char *envz, size_t envz_len, const char *name)
+{
+  char *entry = envz_entry (envz, envz_len, name);
+  if (entry)
+    {
+      while (*entry && *entry != SEP)
+	entry++;
+      if (*entry)
+	entry++;
+      else
+	entry = 0;		/* A null entry.  */
+    }
+  return entry;
+}
+
+/* Remove the entry for NAME from ENVZ & ENVZ_LEN, if any.  */
+void
+envz_remove (char **envz, size_t *envz_len, const char *name)
+{
+  char *entry = envz_entry (*envz, *envz_len, name);
+  if (entry)
+    argz_delete (envz, envz_len, entry);
+}
+libc_hidden_def (envz_remove)
+
+/* Adds an entry for NAME with value VALUE to ENVZ & ENVZ_LEN.  If an entry
+   with the same name already exists in ENVZ, it is removed.  If VALUE is
+   NULL, then the new entry will a special null one, for which envz_get will
+   return NULL, although envz_entry will still return an entry; this is handy
+   because when merging with another envz, the null entry can override an
+   entry in the other one.  Null entries can be removed with envz_strip ().  */
+error_t
+envz_add (char **envz, size_t *envz_len, const char *name, const char *value)
+{
+  envz_remove (envz, envz_len, name);
+
+  if (value)
+    /* Add the new value, if there is one.  */
+    {
+      size_t name_len = strlen (name);
+      size_t value_len = strlen (value);
+      size_t old_envz_len = *envz_len;
+      size_t new_envz_len = old_envz_len + name_len + 1 + value_len + 1;
+      char *new_envz = realloc (*envz, new_envz_len);
+
+      if (new_envz)
+	{
+	  memcpy (new_envz + old_envz_len, name, name_len);
+	  new_envz[old_envz_len + name_len] = SEP;
+	  memcpy (new_envz + old_envz_len + name_len + 1, value, value_len);
+	  new_envz[new_envz_len - 1] = 0;
+
+	  *envz = new_envz;
+	  *envz_len = new_envz_len;
+
+	  return 0;
+	}
+      else
+	return ENOMEM;
+    }
+  else
+    /* Add a null entry.  */
+    return __argz_add (envz, envz_len, name);
+}
+
+/* Adds each entry in ENVZ2 to ENVZ & ENVZ_LEN, as if with envz_add().  If
+   OVERRIDE is true, then values in ENVZ2 will supersede those with the same
+   name in ENV, otherwise not.  */
+error_t
+envz_merge (char **envz, size_t *envz_len, const char *envz2,
+	    size_t envz2_len, int override)
+{
+  error_t err = 0;
+
+  while (envz2_len && ! err)
+    {
+      char *old = envz_entry (*envz, *envz_len, envz2);
+      size_t new_len = strlen (envz2) + 1;
+
+      if (! old)
+	err = __argz_append (envz, envz_len, envz2, new_len);
+      else if (override)
+	{
+	  argz_delete (envz, envz_len, old);
+	  err = __argz_append (envz, envz_len, envz2, new_len);
+	}
+
+      envz2 += new_len;
+      envz2_len -= new_len;
+    }
+
+  return err;
+}
+
+/* Remove null entries.  */
+void
+envz_strip (char **envz, size_t *envz_len)
+{
+  char *entry = *envz;
+  size_t left = *envz_len;
+  while (left)
+    {
+      size_t entry_len = strlen (entry) + 1;
+      left -= entry_len;
+      if (! strchr (entry, SEP))
+	/* Null entry. */
+	memmove (entry, entry + entry_len, left);
+      else
+	entry += entry_len;
+    }
+  *envz_len = entry - *envz;
+}
diff --git a/REORG.TODO/string/envz.h b/REORG.TODO/string/envz.h
new file mode 100644
index 0000000000..330cdd3d8a
--- /dev/null
+++ b/REORG.TODO/string/envz.h
@@ -0,0 +1,73 @@
+/* Routines for dealing with '\0' separated environment vectors
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ENVZ_H
+#define _ENVZ_H	1
+
+#include <features.h>
+
+#include <errno.h>
+
+/* Envz's are argz's too, and should be created etc., using the same
+   routines.  */
+#include <argz.h>
+
+__BEGIN_DECLS
+
+/* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none.  */
+extern char *envz_entry (const char *__restrict __envz, size_t __envz_len,
+			 const char *__restrict __name)
+     __THROW __attribute_pure__;
+
+/* Returns a pointer to the value portion of the entry in ENVZ for NAME, or 0
+   if there is none.  */
+extern char *envz_get (const char *__restrict __envz, size_t __envz_len,
+		       const char *__restrict __name)
+     __THROW __attribute_pure__;
+
+/* Adds an entry for NAME with value VALUE to ENVZ & ENVZ_LEN.  If an entry
+   with the same name already exists in ENVZ, it is removed.  If VALUE is
+   NULL, then the new entry will a special null one, for which envz_get will
+   return NULL, although envz_entry will still return an entry; this is handy
+   because when merging with another envz, the null entry can override an
+   entry in the other one.  Null entries can be removed with envz_strip ().  */
+extern error_t envz_add (char **__restrict __envz,
+			 size_t *__restrict __envz_len,
+			 const char *__restrict __name,
+			 const char *__restrict __value) __THROW;
+
+/* Adds each entry in ENVZ2 to ENVZ & ENVZ_LEN, as if with envz_add().  If
+   OVERRIDE is true, then values in ENVZ2 will supersede those with the same
+   name in ENV, otherwise not.  */
+extern error_t envz_merge (char **__restrict __envz,
+			   size_t *__restrict __envz_len,
+			   const char *__restrict __envz2,
+			   size_t __envz2_len, int __override) __THROW;
+
+/* Remove the entry for NAME from ENVZ & ENVZ_LEN, if any.  */
+extern void envz_remove (char **__restrict __envz,
+			 size_t *__restrict __envz_len,
+			 const char *__restrict __name) __THROW;
+
+/* Remove null entries.  */
+extern void envz_strip (char **__restrict __envz,
+			size_t *__restrict __envz_len) __THROW;
+
+__END_DECLS
+
+#endif /* envz.h */
diff --git a/REORG.TODO/string/explicit_bzero.c b/REORG.TODO/string/explicit_bzero.c
new file mode 100644
index 0000000000..8dadf45ea8
--- /dev/null
+++ b/REORG.TODO/string/explicit_bzero.c
@@ -0,0 +1,38 @@
+/* Erasure of sensitive data, generic implementation.
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* An assembler implementation of explicit_bzero can be created as an
+   assembler alias of an optimized bzero implementation.
+   Architecture-specific implementations also need to define
+   __explicit_bzero_chk.  */
+
+#include <string.h>
+
+/* glibc-internal users use __explicit_bzero_chk, and explicit_bzero
+   redirects to that.  */
+#undef explicit_bzero
+
+/* Set LEN bytes of S to 0.  The compiler will not delete a call to
+   this function, even if S is dead after the call.  */
+void
+explicit_bzero (void *s, size_t len)
+{
+  memset (s, '\0', len);
+  /* Compiler barrier.  */
+  asm volatile ("" ::: "memory");
+}
diff --git a/REORG.TODO/string/ffs.c b/REORG.TODO/string/ffs.c
new file mode 100644
index 0000000000..367cbbfb84
--- /dev/null
+++ b/REORG.TODO/string/ffs.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <limits.h>
+#define ffsl __something_else
+#include <string.h>
+
+#undef	ffs
+
+/* Find the first bit set in I.  */
+int
+__ffs (int i)
+{
+  static const unsigned char table[] =
+    {
+      0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+      6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+      7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+      7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+    };
+  unsigned int a;
+  unsigned int x = i & -i;
+
+  a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ?  16 : 24);
+
+  return table[x >> a] + a;
+}
+weak_alias (__ffs, ffs)
+libc_hidden_def (__ffs)
+libc_hidden_builtin_def (ffs)
+
+#if ULONG_MAX == UINT_MAX
+#undef ffsl
+weak_alias (__ffs, ffsl)
+#endif
diff --git a/REORG.TODO/string/ffsll.c b/REORG.TODO/string/ffsll.c
new file mode 100644
index 0000000000..5e403ef938
--- /dev/null
+++ b/REORG.TODO/string/ffsll.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <limits.h>
+#define ffsl __something_else
+#include <string.h>
+
+#undef	ffsll
+
+/* Find the first bit set in I.  */
+int
+ffsll (long long int i)
+{
+  unsigned long long int x = i & -i;
+
+  if (x <= 0xffffffff)
+    return ffs (i);
+  else
+    return 32 + ffs (i >> 32);
+}
+
+#if ULONG_MAX != UINT_MAX
+#undef ffsl
+weak_alias (ffsll, ffsl)
+#endif
diff --git a/REORG.TODO/string/inl-tester.c b/REORG.TODO/string/inl-tester.c
new file mode 100644
index 0000000000..88528e5ed8
--- /dev/null
+++ b/REORG.TODO/string/inl-tester.c
@@ -0,0 +1,6 @@
+/* We want to test the inline functions here.  */
+
+#define DO_STRING_INLINES
+#undef __USE_STRING_INLINES
+#define __USE_STRING_INLINES 1
+#include "tester.c"
diff --git a/REORG.TODO/string/memccpy.c b/REORG.TODO/string/memccpy.c
new file mode 100644
index 0000000000..605a453a69
--- /dev/null
+++ b/REORG.TODO/string/memccpy.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#undef __memccpy
+#undef memccpy
+
+#ifdef MEMCCPY
+# define __memccpy MEMCCPY
+#endif
+
+/* Copy no more than N bytes of SRC to DEST, stopping when C is found.
+   Return the position in DEST one byte past where C was copied, or
+   NULL if C was not found in the first N bytes of SRC.  */
+void *
+__memccpy (void *dest, const void *src, int c, size_t n)
+{
+  void *p = memchr (src, c, n);
+
+  if (p != NULL)
+    return __mempcpy (dest, src, p - src + 1);
+
+  memcpy (dest, src, n);
+  return NULL;
+}
+
+weak_alias (__memccpy, memccpy)
diff --git a/REORG.TODO/string/memchr.c b/REORG.TODO/string/memchr.c
new file mode 100644
index 0000000000..f6708fd917
--- /dev/null
+++ b/REORG.TODO/string/memchr.c
@@ -0,0 +1,162 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+   with help from Dan Sahlin (dan@sics.se) and
+   commentary by Jim Blandy (jimb@ai.mit.edu);
+   adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+   and implemented by Roland McGrath (roland@ai.mit.edu).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <stddef.h>
+
+#include <limits.h>
+
+#undef __memchr
+#ifdef _LIBC
+# undef memchr
+#endif
+
+#ifndef weak_alias
+# define __memchr memchr
+#endif
+
+#ifndef MEMCHR
+# define MEMCHR __memchr
+#endif
+
+/* Search no more than N bytes of S for C.  */
+void *
+MEMCHR (void const *s, int c_in, size_t n)
+{
+  /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
+     long instead of a 64-bit uintmax_t tends to give better
+     performance.  On 64-bit hardware, unsigned long is generally 64
+     bits already.  Change this typedef to experiment with
+     performance.  */
+  typedef unsigned long int longword;
+
+  const unsigned char *char_ptr;
+  const longword *longword_ptr;
+  longword repeated_one;
+  longword repeated_c;
+  unsigned char c;
+
+  c = (unsigned char) c_in;
+
+  /* Handle the first few bytes by reading one byte at a time.
+     Do this until CHAR_PTR is aligned on a longword boundary.  */
+  for (char_ptr = (const unsigned char *) s;
+       n > 0 && (size_t) char_ptr % sizeof (longword) != 0;
+       --n, ++char_ptr)
+    if (*char_ptr == c)
+      return (void *) char_ptr;
+
+  longword_ptr = (const longword *) char_ptr;
+
+  /* All these elucidatory comments refer to 4-byte longwords,
+     but the theory applies equally well to any size longwords.  */
+
+  /* Compute auxiliary longword values:
+     repeated_one is a value which has a 1 in every byte.
+     repeated_c has c in every byte.  */
+  repeated_one = 0x01010101;
+  repeated_c = c | (c << 8);
+  repeated_c |= repeated_c << 16;
+  if (0xffffffffU < (longword) -1)
+    {
+      repeated_one |= repeated_one << 31 << 1;
+      repeated_c |= repeated_c << 31 << 1;
+      if (8 < sizeof (longword))
+	{
+	  size_t i;
+
+	  for (i = 64; i < sizeof (longword) * 8; i *= 2)
+	    {
+	      repeated_one |= repeated_one << i;
+	      repeated_c |= repeated_c << i;
+	    }
+	}
+    }
+
+  /* Instead of the traditional loop which tests each byte, we will test a
+     longword at a time.  The tricky part is testing if *any of the four*
+     bytes in the longword in question are equal to c.  We first use an xor
+     with repeated_c.  This reduces the task to testing whether *any of the
+     four* bytes in longword1 is zero.
+
+     We compute tmp =
+       ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
+     That is, we perform the following operations:
+       1. Subtract repeated_one.
+       2. & ~longword1.
+       3. & a mask consisting of 0x80 in every byte.
+     Consider what happens in each byte:
+       - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
+	 and step 3 transforms it into 0x80.  A carry can also be propagated
+	 to more significant bytes.
+       - If a byte of longword1 is nonzero, let its lowest 1 bit be at
+	 position k (0 <= k <= 7); so the lowest k bits are 0.  After step 1,
+	 the byte ends in a single bit of value 0 and k bits of value 1.
+	 After step 2, the result is just k bits of value 1: 2^k - 1.  After
+	 step 3, the result is 0.  And no carry is produced.
+     So, if longword1 has only non-zero bytes, tmp is zero.
+     Whereas if longword1 has a zero byte, call j the position of the least
+     significant zero byte.  Then the result has a zero at positions 0, ...,
+     j-1 and a 0x80 at position j.  We cannot predict the result at the more
+     significant bytes (positions j+1..3), but it does not matter since we
+     already have a non-zero bit at position 8*j+7.
+
+     So, the test whether any byte in longword1 is zero is equivalent to
+     testing whether tmp is nonzero.  */
+
+  while (n >= sizeof (longword))
+    {
+      longword longword1 = *longword_ptr ^ repeated_c;
+
+      if ((((longword1 - repeated_one) & ~longword1)
+	   & (repeated_one << 7)) != 0)
+	break;
+      longword_ptr++;
+      n -= sizeof (longword);
+    }
+
+  char_ptr = (const unsigned char *) longword_ptr;
+
+  /* At this point, we know that either n < sizeof (longword), or one of the
+     sizeof (longword) bytes starting at char_ptr is == c.  On little-endian
+     machines, we could determine the first such byte without any further
+     memory accesses, just by looking at the tmp result from the last loop
+     iteration.  But this does not work on big-endian machines.  Choose code
+     that works in both cases.  */
+
+  for (; n > 0; --n, ++char_ptr)
+    {
+      if (*char_ptr == c)
+	return (void *) char_ptr;
+    }
+
+  return NULL;
+}
+#ifdef weak_alias
+weak_alias (__memchr, memchr)
+#endif
+libc_hidden_builtin_def (memchr)
diff --git a/REORG.TODO/string/memcmp.c b/REORG.TODO/string/memcmp.c
new file mode 100644
index 0000000000..c53ab3185d
--- /dev/null
+++ b/REORG.TODO/string/memcmp.c
@@ -0,0 +1,364 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#undef	__ptr_t
+#define __ptr_t	void *
+
+#if defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#endif
+
+#undef memcmp
+
+#ifndef MEMCMP
+# define MEMCMP memcmp
+#endif
+
+#ifdef _LIBC
+
+# include <memcopy.h>
+# include <endian.h>
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  define WORDS_BIGENDIAN
+# endif
+
+#else	/* Not in the GNU C library.  */
+
+# include <sys/types.h>
+
+/* Type to use for aligned memory operations.
+   This should normally be the biggest type supported by a single load
+   and store.  Must be an unsigned type.  */
+# define op_t	unsigned long int
+# define OPSIZ	(sizeof(op_t))
+
+/* Threshold value for when to enter the unrolled loops.  */
+# define OP_T_THRES	16
+
+/* Type to use for unaligned operations.  */
+typedef unsigned char byte;
+
+# ifndef WORDS_BIGENDIAN
+#  define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
+# else
+#  define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
+# endif
+
+#endif	/* In the GNU C library.  */
+
+#ifdef WORDS_BIGENDIAN
+# define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1)
+#else
+# define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b))
+#endif
+
+/* BE VERY CAREFUL IF YOU CHANGE THIS CODE!  */
+
+/* The strategy of this memcmp is:
+
+   1. Compare bytes until one of the block pointers is aligned.
+
+   2. Compare using memcmp_common_alignment or
+      memcmp_not_common_alignment, regarding the alignment of the other
+      block after the initial byte operations.  The maximum number of
+      full words (of type op_t) are compared in this way.
+
+   3. Compare the few remaining bytes.  */
+
+#ifndef WORDS_BIGENDIAN
+/* memcmp_bytes -- Compare A and B bytewise in the byte order of the machine.
+   A and B are known to be different.
+   This is needed only on little-endian machines.  */
+
+static int memcmp_bytes (op_t, op_t) __THROW;
+
+static int
+memcmp_bytes (op_t a, op_t b)
+{
+  long int srcp1 = (long int) &a;
+  long int srcp2 = (long int) &b;
+  op_t a0, b0;
+
+  do
+    {
+      a0 = ((byte *) srcp1)[0];
+      b0 = ((byte *) srcp2)[0];
+      srcp1 += 1;
+      srcp2 += 1;
+    }
+  while (a0 == b0);
+  return a0 - b0;
+}
+#endif
+
+static int memcmp_common_alignment (long, long, size_t) __THROW;
+
+/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t'
+   objects (not LEN bytes!).  Both SRCP1 and SRCP2 should be aligned for
+   memory operations on `op_t's.  */
+static int
+memcmp_common_alignment (long int srcp1, long int srcp2, size_t len)
+{
+  op_t a0, a1;
+  op_t b0, b1;
+
+  switch (len % 4)
+    {
+    default: /* Avoid warning about uninitialized local variables.  */
+    case 2:
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      srcp1 -= 2 * OPSIZ;
+      srcp2 -= 2 * OPSIZ;
+      len += 2;
+      goto do1;
+    case 3:
+      a1 = ((op_t *) srcp1)[0];
+      b1 = ((op_t *) srcp2)[0];
+      srcp1 -= OPSIZ;
+      srcp2 -= OPSIZ;
+      len += 1;
+      goto do2;
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	return 0;
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      goto do3;
+    case 1:
+      a1 = ((op_t *) srcp1)[0];
+      b1 = ((op_t *) srcp2)[0];
+      srcp1 += OPSIZ;
+      srcp2 += OPSIZ;
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	goto do0;
+      /* Fall through.  */
+    }
+
+  do
+    {
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      if (a1 != b1)
+	return CMP_LT_OR_GT (a1, b1);
+
+    do3:
+      a1 = ((op_t *) srcp1)[1];
+      b1 = ((op_t *) srcp2)[1];
+      if (a0 != b0)
+	return CMP_LT_OR_GT (a0, b0);
+
+    do2:
+      a0 = ((op_t *) srcp1)[2];
+      b0 = ((op_t *) srcp2)[2];
+      if (a1 != b1)
+	return CMP_LT_OR_GT (a1, b1);
+
+    do1:
+      a1 = ((op_t *) srcp1)[3];
+      b1 = ((op_t *) srcp2)[3];
+      if (a0 != b0)
+	return CMP_LT_OR_GT (a0, b0);
+
+      srcp1 += 4 * OPSIZ;
+      srcp2 += 4 * OPSIZ;
+      len -= 4;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  if (a1 != b1)
+    return CMP_LT_OR_GT (a1, b1);
+  return 0;
+}
+
+static int memcmp_not_common_alignment (long, long, size_t) __THROW;
+
+/* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
+   `op_t' objects (not LEN bytes!).  SRCP2 should be aligned for memory
+   operations on `op_t', but SRCP1 *should be unaligned*.  */
+static int
+memcmp_not_common_alignment (long int srcp1, long int srcp2, size_t len)
+{
+  op_t a0, a1, a2, a3;
+  op_t b0, b1, b2, b3;
+  op_t x;
+  int shl, shr;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp1 to make it aligned for comparison.  */
+
+  shl = 8 * (srcp1 % OPSIZ);
+  shr = 8 * OPSIZ - shl;
+
+  /* Make SRCP1 aligned by rounding it down to the beginning of the `op_t'
+     it points in the middle of.  */
+  srcp1 &= -OPSIZ;
+
+  switch (len % 4)
+    {
+    default: /* Avoid warning about uninitialized local variables.  */
+    case 2:
+      a1 = ((op_t *) srcp1)[0];
+      a2 = ((op_t *) srcp1)[1];
+      b2 = ((op_t *) srcp2)[0];
+      srcp1 -= 1 * OPSIZ;
+      srcp2 -= 2 * OPSIZ;
+      len += 2;
+      goto do1;
+    case 3:
+      a0 = ((op_t *) srcp1)[0];
+      a1 = ((op_t *) srcp1)[1];
+      b1 = ((op_t *) srcp2)[0];
+      srcp2 -= 1 * OPSIZ;
+      len += 1;
+      goto do2;
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	return 0;
+      a3 = ((op_t *) srcp1)[0];
+      a0 = ((op_t *) srcp1)[1];
+      b0 = ((op_t *) srcp2)[0];
+      srcp1 += 1 * OPSIZ;
+      goto do3;
+    case 1:
+      a2 = ((op_t *) srcp1)[0];
+      a3 = ((op_t *) srcp1)[1];
+      b3 = ((op_t *) srcp2)[0];
+      srcp1 += 2 * OPSIZ;
+      srcp2 += 1 * OPSIZ;
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	goto do0;
+      /* Fall through.  */
+    }
+
+  do
+    {
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      x = MERGE(a2, shl, a3, shr);
+      if (x != b3)
+	return CMP_LT_OR_GT (x, b3);
+
+    do3:
+      a1 = ((op_t *) srcp1)[1];
+      b1 = ((op_t *) srcp2)[1];
+      x = MERGE(a3, shl, a0, shr);
+      if (x != b0)
+	return CMP_LT_OR_GT (x, b0);
+
+    do2:
+      a2 = ((op_t *) srcp1)[2];
+      b2 = ((op_t *) srcp2)[2];
+      x = MERGE(a0, shl, a1, shr);
+      if (x != b1)
+	return CMP_LT_OR_GT (x, b1);
+
+    do1:
+      a3 = ((op_t *) srcp1)[3];
+      b3 = ((op_t *) srcp2)[3];
+      x = MERGE(a1, shl, a2, shr);
+      if (x != b2)
+	return CMP_LT_OR_GT (x, b2);
+
+      srcp1 += 4 * OPSIZ;
+      srcp2 += 4 * OPSIZ;
+      len -= 4;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  x = MERGE(a2, shl, a3, shr);
+  if (x != b3)
+    return CMP_LT_OR_GT (x, b3);
+  return 0;
+}
+
+int
+MEMCMP (const __ptr_t s1, const __ptr_t s2, size_t len)
+{
+  op_t a0;
+  op_t b0;
+  long int srcp1 = (long int) s1;
+  long int srcp2 = (long int) s2;
+  op_t res;
+
+  if (len >= OP_T_THRES)
+    {
+      /* There are at least some bytes to compare.  No need to test
+	 for LEN == 0 in this alignment loop.  */
+      while (srcp2 % OPSIZ != 0)
+	{
+	  a0 = ((byte *) srcp1)[0];
+	  b0 = ((byte *) srcp2)[0];
+	  srcp1 += 1;
+	  srcp2 += 1;
+	  res = a0 - b0;
+	  if (res != 0)
+	    return res;
+	  len -= 1;
+	}
+
+      /* SRCP2 is now aligned for memory operations on `op_t'.
+	 SRCP1 alignment determines if we can do a simple,
+	 aligned compare or need to shuffle bits.  */
+
+      if (srcp1 % OPSIZ == 0)
+	res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ);
+      else
+	res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ);
+      if (res != 0)
+	return res;
+
+      /* Number of bytes remaining in the interval [0..OPSIZ-1].  */
+      srcp1 += len & -OPSIZ;
+      srcp2 += len & -OPSIZ;
+      len %= OPSIZ;
+    }
+
+  /* There are just a few bytes to compare.  Use byte memory operations.  */
+  while (len != 0)
+    {
+      a0 = ((byte *) srcp1)[0];
+      b0 = ((byte *) srcp2)[0];
+      srcp1 += 1;
+      srcp2 += 1;
+      res = a0 - b0;
+      if (res != 0)
+	return res;
+      len -= 1;
+    }
+
+  return 0;
+}
+libc_hidden_builtin_def(memcmp)
+#ifdef weak_alias
+# undef bcmp
+weak_alias (memcmp, bcmp)
+#endif
diff --git a/REORG.TODO/string/memcpy.c b/REORG.TODO/string/memcpy.c
new file mode 100644
index 0000000000..974f65ef94
--- /dev/null
+++ b/REORG.TODO/string/memcpy.c
@@ -0,0 +1,60 @@
+/* Copy memory to memory until the specified number of bytes
+   has been copied.  Overlap is NOT handled correctly.
+   Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <memcopy.h>
+
+#undef memcpy
+
+void *
+memcpy (void *dstpp, const void *srcpp, size_t len)
+{
+  unsigned long int dstp = (long int) dstpp;
+  unsigned long int srcp = (long int) srcpp;
+
+  /* Copy from the beginning to the end.  */
+
+  /* If there not too few bytes to copy, use word copy.  */
+  if (len >= OP_T_THRES)
+    {
+      /* Copy just a few bytes to make DSTP aligned.  */
+      len -= (-dstp) % OPSIZ;
+      BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+      /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
+	 as much as possible.  */
+
+      PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+      /* Copy from SRCP to DSTP taking advantage of the known alignment of
+	 DSTP.  Number of bytes remaining is put in the third argument,
+	 i.e. in LEN.  This number may vary from machine to machine.  */
+
+      WORD_COPY_FWD (dstp, srcp, len, len);
+
+      /* Fall out and copy the tail.  */
+    }
+
+  /* There are just a few bytes to copy.  Use byte memory operations.  */
+  BYTE_COPY_FWD (dstp, srcp, len);
+
+  return dstpp;
+}
+libc_hidden_builtin_def (memcpy)
diff --git a/REORG.TODO/string/memfrob.c b/REORG.TODO/string/memfrob.c
new file mode 100644
index 0000000000..91e162e28f
--- /dev/null
+++ b/REORG.TODO/string/memfrob.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+void *
+memfrob (void *s, size_t n)
+{
+  char *p = (char *) s;
+
+  while (n-- > 0)
+    *p++ ^= 42;
+
+  return s;
+}
diff --git a/REORG.TODO/string/memmem.c b/REORG.TODO/string/memmem.c
new file mode 100644
index 0000000000..54fca4966d
--- /dev/null
+++ b/REORG.TODO/string/memmem.c
@@ -0,0 +1,81 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This particular implementation was written by Eric Blake, 2008.  */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+/* Specification of memmem.  */
+#include <string.h>
+
+#ifndef _LIBC
+# define __builtin_expect(expr, val)   (expr)
+# define __memmem	memmem
+#endif
+
+#define RETURN_TYPE void *
+#define AVAILABLE(h, h_l, j, n_l) ((j) <= (h_l) - (n_l))
+#include "str-two-way.h"
+
+#undef memmem
+
+/* Return the first occurrence of NEEDLE in HAYSTACK.  Return HAYSTACK
+   if NEEDLE_LEN is 0, otherwise NULL if NEEDLE is not found in
+   HAYSTACK.  */
+void *
+__memmem (const void *haystack_start, size_t haystack_len,
+	  const void *needle_start, size_t needle_len)
+{
+  /* Abstract memory is considered to be an array of 'unsigned char' values,
+     not an array of 'char' values.  See ISO C 99 section 6.2.6.1.  */
+  const unsigned char *haystack = (const unsigned char *) haystack_start;
+  const unsigned char *needle = (const unsigned char *) needle_start;
+
+  if (needle_len == 0)
+    /* The first occurrence of the empty string is deemed to occur at
+       the beginning of the string.  */
+    return (void *) haystack;
+
+  /* Sanity check, otherwise the loop might search through the whole
+     memory.  */
+  if (__glibc_unlikely (haystack_len < needle_len))
+    return NULL;
+
+  /* Use optimizations in memchr when possible, to reduce the search
+     size of haystack using a linear algorithm with a smaller
+     coefficient.  However, avoid memchr for long needles, since we
+     can often achieve sublinear performance.  */
+  if (needle_len < LONG_NEEDLE_THRESHOLD)
+    {
+      haystack = memchr (haystack, *needle, haystack_len);
+      if (!haystack || __builtin_expect (needle_len == 1, 0))
+	return (void *) haystack;
+      haystack_len -= haystack - (const unsigned char *) haystack_start;
+      if (haystack_len < needle_len)
+	return NULL;
+      return two_way_short_needle (haystack, haystack_len, needle, needle_len);
+    }
+  else
+    return two_way_long_needle (haystack, haystack_len, needle, needle_len);
+}
+libc_hidden_def (__memmem)
+weak_alias (__memmem, memmem)
+libc_hidden_weak (memmem)
+
+#undef LONG_NEEDLE_THRESHOLD
diff --git a/REORG.TODO/string/memmove.c b/REORG.TODO/string/memmove.c
new file mode 100644
index 0000000000..d8c2116b01
--- /dev/null
+++ b/REORG.TODO/string/memmove.c
@@ -0,0 +1,115 @@
+/* Copy memory to memory until the specified number of bytes
+   has been copied.  Overlap is handled correctly.
+   Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <memcopy.h>
+
+/* All this is so that bcopy.c can #include
+   this file after defining some things.  */
+#ifndef	a1
+#define	a1	dest	/* First arg is DEST.  */
+#define	a1const
+#define	a2	src	/* Second arg is SRC.  */
+#define	a2const	const
+#undef memmove
+#endif
+#if	!defined(RETURN) || !defined(rettype)
+#define	RETURN(s)	return (s)	/* Return DEST.  */
+#define	rettype		void *
+#endif
+
+#ifndef MEMMOVE
+#define MEMMOVE memmove
+#endif
+
+rettype
+inhibit_loop_to_libcall
+MEMMOVE (a1const void *a1, a2const void *a2, size_t len)
+{
+  unsigned long int dstp = (long int) dest;
+  unsigned long int srcp = (long int) src;
+
+  /* This test makes the forward copying code be used whenever possible.
+     Reduces the working set.  */
+  if (dstp - srcp >= len)	/* *Unsigned* compare!  */
+    {
+      /* Copy from the beginning to the end.  */
+
+#if MEMCPY_OK_FOR_FWD_MEMMOVE
+      dest = memcpy (dest, src, len);
+#else
+      /* If there not too few bytes to copy, use word copy.  */
+      if (len >= OP_T_THRES)
+	{
+	  /* Copy just a few bytes to make DSTP aligned.  */
+	  len -= (-dstp) % OPSIZ;
+	  BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+	  /* Copy whole pages from SRCP to DSTP by virtual address
+	     manipulation, as much as possible.  */
+
+	  PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+	  /* Copy from SRCP to DSTP taking advantage of the known
+	     alignment of DSTP.  Number of bytes remaining is put
+	     in the third argument, i.e. in LEN.  This number may
+	     vary from machine to machine.  */
+
+	  WORD_COPY_FWD (dstp, srcp, len, len);
+
+	  /* Fall out and copy the tail.  */
+	}
+
+      /* There are just a few bytes to copy.  Use byte memory operations.  */
+      BYTE_COPY_FWD (dstp, srcp, len);
+#endif /* MEMCPY_OK_FOR_FWD_MEMMOVE */
+    }
+  else
+    {
+      /* Copy from the end to the beginning.  */
+      srcp += len;
+      dstp += len;
+
+      /* If there not too few bytes to copy, use word copy.  */
+      if (len >= OP_T_THRES)
+	{
+	  /* Copy just a few bytes to make DSTP aligned.  */
+	  len -= dstp % OPSIZ;
+	  BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);
+
+	  /* Copy from SRCP to DSTP taking advantage of the known
+	     alignment of DSTP.  Number of bytes remaining is put
+	     in the third argument, i.e. in LEN.  This number may
+	     vary from machine to machine.  */
+
+	  WORD_COPY_BWD (dstp, srcp, len, len);
+
+	  /* Fall out and copy the tail.  */
+	}
+
+      /* There are just a few bytes to copy.  Use byte memory operations.  */
+      BYTE_COPY_BWD (dstp, srcp, len);
+    }
+
+  RETURN (dest);
+}
+#ifndef memmove
+libc_hidden_builtin_def (memmove)
+#endif
diff --git a/REORG.TODO/string/memory.h b/REORG.TODO/string/memory.h
new file mode 100644
index 0000000000..36ad3808f8
--- /dev/null
+++ b/REORG.TODO/string/memory.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/*
+ * SVID
+ */
+
+#ifndef	_MEMORY_H
+#define	_MEMORY_H	1
+
+#include <features.h>
+
+
+#ifndef	_STRING_H
+# include <string.h>
+#endif	/* string.h  */
+
+
+#endif	/* memory.h  */
diff --git a/REORG.TODO/string/mempcpy.c b/REORG.TODO/string/mempcpy.c
new file mode 100644
index 0000000000..7a8718e79f
--- /dev/null
+++ b/REORG.TODO/string/mempcpy.c
@@ -0,0 +1,39 @@
+/* Copy memory to memory until the specified number of bytes
+   has been copied, return pointer to following byte.
+   Overlap is NOT handled correctly.
+   Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define NO_MEMPCPY_STPCPY_REDIRECT
+#include <string.h>
+
+#undef mempcpy
+#undef __mempcpy
+
+#ifndef MEMPCPY
+# define MEMPCPY __mempcpy
+#endif
+
+void *
+MEMPCPY (void *dest, const void *src, size_t len)
+{
+  return memcpy (dest, src, len) + len;
+}
+libc_hidden_def (__mempcpy)
+weak_alias (__mempcpy, mempcpy)
+libc_hidden_builtin_def (mempcpy)
diff --git a/REORG.TODO/string/memrchr.c b/REORG.TODO/string/memrchr.c
new file mode 100644
index 0000000000..0ecfe08842
--- /dev/null
+++ b/REORG.TODO/string/memrchr.c
@@ -0,0 +1,200 @@
+/* memrchr -- find the last occurrence of a byte in a memory block
+   Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+   with help from Dan Sahlin (dan@sics.se) and
+   commentary by Jim Blandy (jimb@ai.mit.edu);
+   adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+   and implemented by Roland McGrath (roland@ai.mit.edu).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#undef __ptr_t
+#define __ptr_t void *
+
+#if defined _LIBC
+# include <string.h>
+# include <memcopy.h>
+#endif
+
+#if defined HAVE_LIMITS_H || defined _LIBC
+# include <limits.h>
+#endif
+
+#define LONG_MAX_32_BITS 2147483647
+
+#ifndef LONG_MAX
+# define LONG_MAX LONG_MAX_32_BITS
+#endif
+
+#include <sys/types.h>
+
+#undef __memrchr
+#undef memrchr
+
+#ifndef weak_alias
+# define __memrchr memrchr
+#endif
+
+/* Search no more than N bytes of S for C.  */
+__ptr_t
+#ifndef MEMRCHR
+__memrchr
+#else
+MEMRCHR
+#endif
+     (const __ptr_t s, int c_in, size_t n)
+{
+  const unsigned char *char_ptr;
+  const unsigned long int *longword_ptr;
+  unsigned long int longword, magic_bits, charmask;
+  unsigned char c;
+
+  c = (unsigned char) c_in;
+
+  /* Handle the last few characters by reading one character at a time.
+     Do this until CHAR_PTR is aligned on a longword boundary.  */
+  for (char_ptr = (const unsigned char *) s + n;
+       n > 0 && ((unsigned long int) char_ptr
+		 & (sizeof (longword) - 1)) != 0;
+       --n)
+    if (*--char_ptr == c)
+      return (__ptr_t) char_ptr;
+
+  /* All these elucidatory comments refer to 4-byte longwords,
+     but the theory applies equally well to 8-byte longwords.  */
+
+  longword_ptr = (const unsigned long int *) char_ptr;
+
+  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
+     the "holes."  Note that there is a hole just to the left of
+     each byte, with an extra at the end:
+
+     bits:  01111110 11111110 11111110 11111111
+     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
+
+     The 1-bits make sure that carries propagate to the next 0-bit.
+     The 0-bits provide holes for carries to fall into.  */
+  magic_bits = -1;
+  magic_bits = magic_bits / 0xff * 0xfe << 1 >> 1 | 1;
+
+  /* Set up a longword, each of whose bytes is C.  */
+  charmask = c | (c << 8);
+  charmask |= charmask << 16;
+#if LONG_MAX > LONG_MAX_32_BITS
+  charmask |= charmask << 32;
+#endif
+
+  /* Instead of the traditional loop which tests each character,
+     we will test a longword at a time.  The tricky part is testing
+     if *any of the four* bytes in the longword in question are zero.  */
+  while (n >= sizeof (longword))
+    {
+      /* We tentatively exit the loop if adding MAGIC_BITS to
+	 LONGWORD fails to change any of the hole bits of LONGWORD.
+
+	 1) Is this safe?  Will it catch all the zero bytes?
+	 Suppose there is a byte with all zeros.  Any carry bits
+	 propagating from its left will fall into the hole at its
+	 least significant bit and stop.  Since there will be no
+	 carry from its most significant bit, the LSB of the
+	 byte to the left will be unchanged, and the zero will be
+	 detected.
+
+	 2) Is this worthwhile?  Will it ignore everything except
+	 zero bytes?  Suppose every byte of LONGWORD has a bit set
+	 somewhere.  There will be a carry into bit 8.  If bit 8
+	 is set, this will carry into bit 16.  If bit 8 is clear,
+	 one of bits 9-15 must be set, so there will be a carry
+	 into bit 16.  Similarly, there will be a carry into bit
+	 24.  If one of bits 24-30 is set, there will be a carry
+	 into bit 31, so all of the hole bits will be changed.
+
+	 The one misfire occurs when bits 24-30 are clear and bit
+	 31 is set; in this case, the hole at bit 31 is not
+	 changed.  If we had access to the processor carry flag,
+	 we could close this loophole by putting the fourth hole
+	 at bit 32!
+
+	 So it ignores everything except 128's, when they're aligned
+	 properly.
+
+	 3) But wait!  Aren't we looking for C, not zero?
+	 Good point.  So what we do is XOR LONGWORD with a longword,
+	 each of whose bytes is C.  This turns each byte that is C
+	 into a zero.  */
+
+      longword = *--longword_ptr ^ charmask;
+
+      /* Add MAGIC_BITS to LONGWORD.  */
+      if ((((longword + magic_bits)
+
+	    /* Set those bits that were unchanged by the addition.  */
+	    ^ ~longword)
+
+	   /* Look at only the hole bits.  If any of the hole bits
+	      are unchanged, most likely one of the bytes was a
+	      zero.  */
+	   & ~magic_bits) != 0)
+	{
+	  /* Which of the bytes was C?  If none of them were, it was
+	     a misfire; continue the search.  */
+
+	  const unsigned char *cp = (const unsigned char *) longword_ptr;
+
+#if LONG_MAX > 2147483647
+	  if (cp[7] == c)
+	    return (__ptr_t) &cp[7];
+	  if (cp[6] == c)
+	    return (__ptr_t) &cp[6];
+	  if (cp[5] == c)
+	    return (__ptr_t) &cp[5];
+	  if (cp[4] == c)
+	    return (__ptr_t) &cp[4];
+#endif
+	  if (cp[3] == c)
+	    return (__ptr_t) &cp[3];
+	  if (cp[2] == c)
+	    return (__ptr_t) &cp[2];
+	  if (cp[1] == c)
+	    return (__ptr_t) &cp[1];
+	  if (cp[0] == c)
+	    return (__ptr_t) cp;
+	}
+
+      n -= sizeof (longword);
+    }
+
+  char_ptr = (const unsigned char *) longword_ptr;
+
+  while (n-- > 0)
+    {
+      if (*--char_ptr == c)
+	return (__ptr_t) char_ptr;
+    }
+
+  return 0;
+}
+#ifndef MEMRCHR
+# ifdef weak_alias
+weak_alias (__memrchr, memrchr)
+# endif
+#endif
diff --git a/REORG.TODO/string/memset.c b/REORG.TODO/string/memset.c
new file mode 100644
index 0000000000..549790c356
--- /dev/null
+++ b/REORG.TODO/string/memset.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <memcopy.h>
+
+#undef memset
+
+void *
+inhibit_loop_to_libcall
+memset (void *dstpp, int c, size_t len)
+{
+  long int dstp = (long int) dstpp;
+
+  if (len >= 8)
+    {
+      size_t xlen;
+      op_t cccc;
+
+      cccc = (unsigned char) c;
+      cccc |= cccc << 8;
+      cccc |= cccc << 16;
+      if (OPSIZ > 4)
+	/* Do the shift in two steps to avoid warning if long has 32 bits.  */
+	cccc |= (cccc << 16) << 16;
+
+      /* There are at least some bytes to set.
+	 No need to test for LEN == 0 in this alignment loop.  */
+      while (dstp % OPSIZ != 0)
+	{
+	  ((byte *) dstp)[0] = c;
+	  dstp += 1;
+	  len -= 1;
+	}
+
+      /* Write 8 `op_t' per iteration until less than 8 `op_t' remain.  */
+      xlen = len / (OPSIZ * 8);
+      while (xlen > 0)
+	{
+	  ((op_t *) dstp)[0] = cccc;
+	  ((op_t *) dstp)[1] = cccc;
+	  ((op_t *) dstp)[2] = cccc;
+	  ((op_t *) dstp)[3] = cccc;
+	  ((op_t *) dstp)[4] = cccc;
+	  ((op_t *) dstp)[5] = cccc;
+	  ((op_t *) dstp)[6] = cccc;
+	  ((op_t *) dstp)[7] = cccc;
+	  dstp += 8 * OPSIZ;
+	  xlen -= 1;
+	}
+      len %= OPSIZ * 8;
+
+      /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain.  */
+      xlen = len / OPSIZ;
+      while (xlen > 0)
+	{
+	  ((op_t *) dstp)[0] = cccc;
+	  dstp += OPSIZ;
+	  xlen -= 1;
+	}
+      len %= OPSIZ;
+    }
+
+  /* Write the last few bytes.  */
+  while (len > 0)
+    {
+      ((byte *) dstp)[0] = c;
+      dstp += 1;
+      len -= 1;
+    }
+
+  return dstpp;
+}
+libc_hidden_builtin_def (memset)
diff --git a/REORG.TODO/string/noinl-tester.c b/REORG.TODO/string/noinl-tester.c
new file mode 100644
index 0000000000..2e994f73f9
--- /dev/null
+++ b/REORG.TODO/string/noinl-tester.c
@@ -0,0 +1,4 @@
+/* We don't want to test any of the inline functions here.  */
+
+#define __NO_STRING_INLINES 1
+#include "tester.c"
diff --git a/REORG.TODO/string/rawmemchr.c b/REORG.TODO/string/rawmemchr.c
new file mode 100644
index 0000000000..42a3f8aaba
--- /dev/null
+++ b/REORG.TODO/string/rawmemchr.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <libc-diag.h>
+
+#ifndef RAWMEMCHR
+# define RAWMEMCHR __rawmemchr
+#endif
+
+/* Find the first occurrence of C in S.  */
+void *
+RAWMEMCHR (const void *s, int c)
+{
+  DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+  /* GCC 8 warns about the size passed to memchr being larger than
+     PTRDIFF_MAX; the use of SIZE_MAX is deliberate here.  */
+  DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-overflow=");
+#endif
+  if (c != '\0')
+    return memchr (s, c, (size_t)-1);
+  DIAG_POP_NEEDS_COMMENT;
+  return (char *)s + strlen (s);
+}
+libc_hidden_def (__rawmemchr)
+weak_alias (__rawmemchr, rawmemchr)
diff --git a/REORG.TODO/string/stpcpy.c b/REORG.TODO/string/stpcpy.c
new file mode 100644
index 0000000000..1603fb319b
--- /dev/null
+++ b/REORG.TODO/string/stpcpy.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define NO_MEMPCPY_STPCPY_REDIRECT
+#include <string.h>
+
+#undef __stpcpy
+#undef stpcpy
+
+#ifndef STPCPY
+# define STPCPY __stpcpy
+#endif
+
+/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */
+char *
+STPCPY (char *dest, const char *src)
+{
+  size_t len = strlen (src);
+  return memcpy (dest, src, len + 1) + len;
+}
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/REORG.TODO/string/stpncpy.c b/REORG.TODO/string/stpncpy.c
new file mode 100644
index 0000000000..9b8ef348e5
--- /dev/null
+++ b/REORG.TODO/string/stpncpy.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef _LIBC
+# include <string.h>
+#else
+# include <sys/types.h>
+#endif
+
+#ifndef STPNCPY
+# ifdef weak_alias
+#  define STPNCPY	__stpncpy
+weak_alias (__stpncpy, stpncpy)
+# else
+#  define STPNCPY	stpncpy
+# endif
+#endif
+
+/* Copy no more than N characters of SRC to DEST, returning the address of
+   the terminating '\0' in DEST, if any, or else DEST + N.  */
+char *
+STPNCPY (char *dest, const char *src, size_t n)
+{
+  size_t size = __strnlen (src, n);
+  memcpy (dest, src, size);
+  dest += size;
+  if (size == n)
+    return dest;
+  return memset (dest, '\0', n - size);
+}
+#ifdef weak_alias
+libc_hidden_def (__stpncpy)
+#endif
diff --git a/REORG.TODO/string/str-two-way.h b/REORG.TODO/string/str-two-way.h
new file mode 100644
index 0000000000..599c867ffd
--- /dev/null
+++ b/REORG.TODO/string/str-two-way.h
@@ -0,0 +1,527 @@
+/* Byte-wise substring search, using the Two-Way algorithm.
+   Copyright (C) 2008-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Eric Blake <ebb9@byu.net>, 2008.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Before including this file, you need to include <string.h> (and
+   <config.h> before that, if not part of libc), and define:
+     RETURN_TYPE             A macro that expands to the return type.
+     AVAILABLE(h, h_l, j, n_l)
+			     A macro that returns nonzero if there are
+			     at least N_L bytes left starting at H[J].
+			     H is 'unsigned char *', H_L, J, and N_L
+			     are 'size_t'; H_L is an lvalue.  For
+			     NUL-terminated searches, H_L can be
+			     modified each iteration to avoid having
+			     to compute the end of H up front.
+
+  For case-insensitivity, you may optionally define:
+     CMP_FUNC(p1, p2, l)     A macro that returns 0 iff the first L
+			     characters of P1 and P2 are equal.
+     CANON_ELEMENT(c)        A macro that canonicalizes an element right after
+			     it has been fetched from one of the two strings.
+			     The argument is an 'unsigned char'; the result
+			     must be an 'unsigned char' as well.
+
+  Other macros you may optionally define:
+     RET0_IF_0(a)            Documented below at default definition.
+     CHECK_EOL               Same.
+
+  This file undefines the macros listed above, and defines
+  LONG_NEEDLE_THRESHOLD.
+*/
+
+#include <limits.h>
+#include <stdint.h>
+#include <sys/param.h>                  /* Defines MAX.  */
+
+/* We use the Two-Way string matching algorithm, which guarantees
+   linear complexity with constant space.  Additionally, for long
+   needles, we also use a bad character shift table similar to the
+   Boyer-Moore algorithm to achieve improved (potentially sub-linear)
+   performance.
+
+   See http://www-igm.univ-mlv.fr/~lecroq/string/node26.html#SECTION00260
+   and http://en.wikipedia.org/wiki/Boyer-Moore_string_search_algorithm
+*/
+
+/* Point at which computing a bad-byte shift table is likely to be
+   worthwhile.  Small needles should not compute a table, since it
+   adds (1 << CHAR_BIT) + NEEDLE_LEN computations of preparation for a
+   speedup no greater than a factor of NEEDLE_LEN.  The larger the
+   needle, the better the potential performance gain.  On the other
+   hand, on non-POSIX systems with CHAR_BIT larger than eight, the
+   memory required for the table is prohibitive.  */
+#if CHAR_BIT < 10
+# define LONG_NEEDLE_THRESHOLD 32U
+#else
+# define LONG_NEEDLE_THRESHOLD SIZE_MAX
+#endif
+
+#ifndef CANON_ELEMENT
+# define CANON_ELEMENT(c) c
+#endif
+#ifndef CMP_FUNC
+# define CMP_FUNC memcmp
+#endif
+
+/* Check for end-of-line in strstr and strcasestr routines.
+   We piggy-back matching procedure for detecting EOL where possible,
+   and use AVAILABLE macro otherwise.  */
+#ifndef CHECK_EOL
+# define CHECK_EOL (0)
+#endif
+
+/* Return NULL if argument is '\0'.  */
+#ifndef RET0_IF_0
+# define RET0_IF_0(a) /* nothing */
+#endif
+
+/* Perform a critical factorization of NEEDLE, of length NEEDLE_LEN.
+   Return the index of the first byte in the right half, and set
+   *PERIOD to the global period of the right half.
+
+   The global period of a string is the smallest index (possibly its
+   length) at which all remaining bytes in the string are repetitions
+   of the prefix (the last repetition may be a subset of the prefix).
+
+   When NEEDLE is factored into two halves, a local period is the
+   length of the smallest word that shares a suffix with the left half
+   and shares a prefix with the right half.  All factorizations of a
+   non-empty NEEDLE have a local period of at least 1 and no greater
+   than NEEDLE_LEN.
+
+   A critical factorization has the property that the local period
+   equals the global period.  All strings have at least one critical
+   factorization with the left half smaller than the global period.
+
+   Given an ordered alphabet, a critical factorization can be computed
+   in linear time, with 2 * NEEDLE_LEN comparisons, by computing the
+   larger of two ordered maximal suffixes.  The ordered maximal
+   suffixes are determined by lexicographic comparison of
+   periodicity.  */
+static size_t
+critical_factorization (const unsigned char *needle, size_t needle_len,
+			size_t *period)
+{
+  /* Index of last byte of left half, or SIZE_MAX.  */
+  size_t max_suffix, max_suffix_rev;
+  size_t j; /* Index into NEEDLE for current candidate suffix.  */
+  size_t k; /* Offset into current period.  */
+  size_t p; /* Intermediate period.  */
+  unsigned char a, b; /* Current comparison bytes.  */
+
+  /* Invariants:
+     0 <= j < NEEDLE_LEN - 1
+     -1 <= max_suffix{,_rev} < j (treating SIZE_MAX as if it were signed)
+     min(max_suffix, max_suffix_rev) < global period of NEEDLE
+     1 <= p <= global period of NEEDLE
+     p == global period of the substring NEEDLE[max_suffix{,_rev}+1...j]
+     1 <= k <= p
+  */
+
+  /* Perform lexicographic search.  */
+  max_suffix = SIZE_MAX;
+  j = 0;
+  k = p = 1;
+  while (j + k < needle_len)
+    {
+      a = CANON_ELEMENT (needle[j + k]);
+      b = CANON_ELEMENT (needle[max_suffix + k]);
+      if (a < b)
+	{
+	  /* Suffix is smaller, period is entire prefix so far.  */
+	  j += k;
+	  k = 1;
+	  p = j - max_suffix;
+	}
+      else if (a == b)
+	{
+	  /* Advance through repetition of the current period.  */
+	  if (k != p)
+	    ++k;
+	  else
+	    {
+	      j += p;
+	      k = 1;
+	    }
+	}
+      else /* b < a */
+	{
+	  /* Suffix is larger, start over from current location.  */
+	  max_suffix = j++;
+	  k = p = 1;
+	}
+    }
+  *period = p;
+
+  /* Perform reverse lexicographic search.  */
+  max_suffix_rev = SIZE_MAX;
+  j = 0;
+  k = p = 1;
+  while (j + k < needle_len)
+    {
+      a = CANON_ELEMENT (needle[j + k]);
+      b = CANON_ELEMENT (needle[max_suffix_rev + k]);
+      if (b < a)
+	{
+	  /* Suffix is smaller, period is entire prefix so far.  */
+	  j += k;
+	  k = 1;
+	  p = j - max_suffix_rev;
+	}
+      else if (a == b)
+	{
+	  /* Advance through repetition of the current period.  */
+	  if (k != p)
+	    ++k;
+	  else
+	    {
+	      j += p;
+	      k = 1;
+	    }
+	}
+      else /* a < b */
+	{
+	  /* Suffix is larger, start over from current location.  */
+	  max_suffix_rev = j++;
+	  k = p = 1;
+	}
+    }
+
+  /* Choose the longer suffix.  Return the first byte of the right
+     half, rather than the last byte of the left half.  */
+  if (max_suffix_rev + 1 < max_suffix + 1)
+    return max_suffix + 1;
+  *period = p;
+  return max_suffix_rev + 1;
+}
+
+/* Return the first location of non-empty NEEDLE within HAYSTACK, or
+   NULL.  HAYSTACK_LEN is the minimum known length of HAYSTACK.  This
+   method is optimized for NEEDLE_LEN < LONG_NEEDLE_THRESHOLD.
+   Performance is guaranteed to be linear, with an initialization cost
+   of 2 * NEEDLE_LEN comparisons.
+
+   If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at
+   most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching.
+   If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 *
+   HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching.  */
+static RETURN_TYPE
+two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
+		      const unsigned char *needle, size_t needle_len)
+{
+  size_t i; /* Index into current byte of NEEDLE.  */
+  size_t j; /* Index into current window of HAYSTACK.  */
+  size_t period; /* The period of the right half of needle.  */
+  size_t suffix; /* The index of the right half of needle.  */
+
+  /* Factor the needle into two halves, such that the left half is
+     smaller than the global period, and the right half is
+     periodic (with a period as large as NEEDLE_LEN - suffix).  */
+  suffix = critical_factorization (needle, needle_len, &period);
+
+  /* Perform the search.  Each iteration compares the right half
+     first.  */
+  if (CMP_FUNC (needle, needle + period, suffix) == 0)
+    {
+      /* Entire needle is periodic; a mismatch can only advance by the
+	 period, so use memory to avoid rescanning known occurrences
+	 of the period.  */
+      size_t memory = 0;
+      j = 0;
+      while (AVAILABLE (haystack, haystack_len, j, needle_len))
+	{
+	  const unsigned char *pneedle;
+	  const unsigned char *phaystack;
+
+	  /* Scan for matches in right half.  */
+	  i = MAX (suffix, memory);
+	  pneedle = &needle[i];
+	  phaystack = &haystack[i + j];
+	  while (i < needle_len && (CANON_ELEMENT (*pneedle++)
+				    == CANON_ELEMENT (*phaystack++)))
+	    ++i;
+	  if (needle_len <= i)
+	    {
+	      /* Scan for matches in left half.  */
+	      i = suffix - 1;
+	      pneedle = &needle[i];
+	      phaystack = &haystack[i + j];
+	      while (memory < i + 1 && (CANON_ELEMENT (*pneedle--)
+					== CANON_ELEMENT (*phaystack--)))
+		--i;
+	      if (i + 1 < memory + 1)
+		return (RETURN_TYPE) (haystack + j);
+	      /* No match, so remember how many repetitions of period
+		 on the right half were scanned.  */
+	      j += period;
+	      memory = needle_len - period;
+	    }
+	  else
+	    {
+	      j += i - suffix + 1;
+	      memory = 0;
+	    }
+	}
+    }
+  else
+    {
+      const unsigned char *phaystack = &haystack[suffix];
+      /* The comparison always starts from needle[suffix], so cache it
+	 and use an optimized first-character loop.  */
+      unsigned char needle_suffix = CANON_ELEMENT (needle[suffix]);
+
+#if CHECK_EOL
+      /* We start matching from the SUFFIX'th element, so make sure we
+	 don't hit '\0' before that.  */
+      if (haystack_len < suffix + 1
+	  && !AVAILABLE (haystack, haystack_len, 0, suffix + 1))
+	return NULL;
+#endif
+
+      /* The two halves of needle are distinct; no extra memory is
+	 required, and any mismatch results in a maximal shift.  */
+      period = MAX (suffix, needle_len - suffix) + 1;
+      j = 0;
+      while (1
+#if !CHECK_EOL
+	     && AVAILABLE (haystack, haystack_len, j, needle_len)
+#endif
+	     )
+	{
+	  unsigned char haystack_char;
+	  const unsigned char *pneedle;
+
+	  /* TODO: The first-character loop can be sped up by adapting
+	     longword-at-a-time implementation of memchr/strchr.  */
+	  if (needle_suffix
+	      != (haystack_char = CANON_ELEMENT (*phaystack++)))
+	    {
+	      RET0_IF_0 (haystack_char);
+#if !CHECK_EOL
+	      ++j;
+#endif
+	      continue;
+	    }
+
+#if CHECK_EOL
+	  /* Calculate J if it wasn't kept up-to-date in the first-character
+	     loop.  */
+	  j = phaystack - &haystack[suffix] - 1;
+#endif
+
+	  /* Scan for matches in right half.  */
+	  i = suffix + 1;
+	  pneedle = &needle[i];
+	  while (i < needle_len)
+	    {
+	      if (CANON_ELEMENT (*pneedle++)
+		  != (haystack_char = CANON_ELEMENT (*phaystack++)))
+		{
+		  RET0_IF_0 (haystack_char);
+		  break;
+		}
+	      ++i;
+	    }
+	  if (needle_len <= i)
+	    {
+	      /* Scan for matches in left half.  */
+	      i = suffix - 1;
+	      pneedle = &needle[i];
+	      phaystack = &haystack[i + j];
+	      while (i != SIZE_MAX)
+		{
+		  if (CANON_ELEMENT (*pneedle--)
+		      != (haystack_char = CANON_ELEMENT (*phaystack--)))
+		    {
+		      RET0_IF_0 (haystack_char);
+		      break;
+		    }
+		  --i;
+		}
+	      if (i == SIZE_MAX)
+		return (RETURN_TYPE) (haystack + j);
+	      j += period;
+	    }
+	  else
+	    j += i - suffix + 1;
+
+#if CHECK_EOL
+	  if (!AVAILABLE (haystack, haystack_len, j, needle_len))
+	    break;
+#endif
+
+	  phaystack = &haystack[suffix + j];
+	}
+    }
+ ret0: __attribute__ ((unused))
+  return NULL;
+}
+
+/* Return the first location of non-empty NEEDLE within HAYSTACK, or
+   NULL.  HAYSTACK_LEN is the minimum known length of HAYSTACK.  This
+   method is optimized for LONG_NEEDLE_THRESHOLD <= NEEDLE_LEN.
+   Performance is guaranteed to be linear, with an initialization cost
+   of 3 * NEEDLE_LEN + (1 << CHAR_BIT) operations.
+
+   If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at
+   most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching,
+   and sublinear performance O(HAYSTACK_LEN / NEEDLE_LEN) is possible.
+   If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 *
+   HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and
+   sublinear performance is not possible.  */
+static RETURN_TYPE
+two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
+		     const unsigned char *needle, size_t needle_len)
+{
+  size_t i; /* Index into current byte of NEEDLE.  */
+  size_t j; /* Index into current window of HAYSTACK.  */
+  size_t period; /* The period of the right half of needle.  */
+  size_t suffix; /* The index of the right half of needle.  */
+  size_t shift_table[1U << CHAR_BIT]; /* See below.  */
+
+  /* Factor the needle into two halves, such that the left half is
+     smaller than the global period, and the right half is
+     periodic (with a period as large as NEEDLE_LEN - suffix).  */
+  suffix = critical_factorization (needle, needle_len, &period);
+
+  /* Populate shift_table.  For each possible byte value c,
+     shift_table[c] is the distance from the last occurrence of c to
+     the end of NEEDLE, or NEEDLE_LEN if c is absent from the NEEDLE.
+     shift_table[NEEDLE[NEEDLE_LEN - 1]] contains the only 0.  */
+  for (i = 0; i < 1U << CHAR_BIT; i++)
+    shift_table[i] = needle_len;
+  for (i = 0; i < needle_len; i++)
+    shift_table[CANON_ELEMENT (needle[i])] = needle_len - i - 1;
+
+  /* Perform the search.  Each iteration compares the right half
+     first.  */
+  if (CMP_FUNC (needle, needle + period, suffix) == 0)
+    {
+      /* Entire needle is periodic; a mismatch can only advance by the
+	 period, so use memory to avoid rescanning known occurrences
+	 of the period.  */
+      size_t memory = 0;
+      size_t shift;
+      j = 0;
+      while (AVAILABLE (haystack, haystack_len, j, needle_len))
+	{
+	  const unsigned char *pneedle;
+	  const unsigned char *phaystack;
+
+	  /* Check the last byte first; if it does not match, then
+	     shift to the next possible match location.  */
+	  shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
+	  if (0 < shift)
+	    {
+	      if (memory && shift < period)
+		{
+		  /* Since needle is periodic, but the last period has
+		     a byte out of place, there can be no match until
+		     after the mismatch.  */
+		  shift = needle_len - period;
+		}
+	      memory = 0;
+	      j += shift;
+	      continue;
+	    }
+	  /* Scan for matches in right half.  The last byte has
+	     already been matched, by virtue of the shift table.  */
+	  i = MAX (suffix, memory);
+	  pneedle = &needle[i];
+	  phaystack = &haystack[i + j];
+	  while (i < needle_len - 1 && (CANON_ELEMENT (*pneedle++)
+					== CANON_ELEMENT (*phaystack++)))
+	    ++i;
+	  if (needle_len - 1 <= i)
+	    {
+	      /* Scan for matches in left half.  */
+	      i = suffix - 1;
+	      pneedle = &needle[i];
+	      phaystack = &haystack[i + j];
+	      while (memory < i + 1 && (CANON_ELEMENT (*pneedle--)
+					== CANON_ELEMENT (*phaystack--)))
+		--i;
+	      if (i + 1 < memory + 1)
+		return (RETURN_TYPE) (haystack + j);
+	      /* No match, so remember how many repetitions of period
+		 on the right half were scanned.  */
+	      j += period;
+	      memory = needle_len - period;
+	    }
+	  else
+	    {
+	      j += i - suffix + 1;
+	      memory = 0;
+	    }
+	}
+    }
+  else
+    {
+      /* The two halves of needle are distinct; no extra memory is
+	 required, and any mismatch results in a maximal shift.  */
+      size_t shift;
+      period = MAX (suffix, needle_len - suffix) + 1;
+      j = 0;
+      while (AVAILABLE (haystack, haystack_len, j, needle_len))
+	{
+	  const unsigned char *pneedle;
+	  const unsigned char *phaystack;
+
+	  /* Check the last byte first; if it does not match, then
+	     shift to the next possible match location.  */
+	  shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
+	  if (0 < shift)
+	    {
+	      j += shift;
+	      continue;
+	    }
+	  /* Scan for matches in right half.  The last byte has
+	     already been matched, by virtue of the shift table.  */
+	  i = suffix;
+	  pneedle = &needle[i];
+	  phaystack = &haystack[i + j];
+	  while (i < needle_len - 1 && (CANON_ELEMENT (*pneedle++)
+					== CANON_ELEMENT (*phaystack++)))
+	    ++i;
+	  if (needle_len - 1 <= i)
+	    {
+	      /* Scan for matches in left half.  */
+	      i = suffix - 1;
+	      pneedle = &needle[i];
+	      phaystack = &haystack[i + j];
+	      while (i != SIZE_MAX && (CANON_ELEMENT (*pneedle--)
+				       == CANON_ELEMENT (*phaystack--)))
+		--i;
+	      if (i == SIZE_MAX)
+		return (RETURN_TYPE) (haystack + j);
+	      j += period;
+	    }
+	  else
+	    j += i - suffix + 1;
+	}
+    }
+  return NULL;
+}
+
+#undef AVAILABLE
+#undef CANON_ELEMENT
+#undef CMP_FUNC
+#undef RET0_IF_0
+#undef RETURN_TYPE
+#undef CHECK_EOL
diff --git a/REORG.TODO/string/stratcliff.c b/REORG.TODO/string/stratcliff.c
new file mode 100644
index 0000000000..e28b0c5058
--- /dev/null
+++ b/REORG.TODO/string/stratcliff.c
@@ -0,0 +1,561 @@
+/* Test for string function add boundaries of usable memory.
+   Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE 1
+
+/* Make sure we don't test the optimized inline functions if we want to
+   test the real implementation.  */
+#undef __USE_STRING_INLINES
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+
+#ifndef CHAR
+# define L(c) c
+# define CHAR char
+# define MEMSET memset
+# define STRLEN strlen
+# define STRNLEN strnlen
+# define STRCHR strchr
+# define STRRCHR strrchr
+# define STRCPY strcpy
+# define STRNCPY strncpy
+# define MEMCMP memcmp
+# define STPCPY stpcpy
+# define STPNCPY stpncpy
+# define MEMCPY memcpy
+# define MEMPCPY mempcpy
+# define MEMCHR memchr
+# define STRCMP strcmp
+# define STRNCMP strncmp
+#endif
+
+
+#define STRINGIFY(s) STRINGIFY2 (s)
+#define STRINGIFY2(s) #s
+
+
+int
+do_test (void)
+{
+  int size = sysconf (_SC_PAGESIZE);
+  int nchars = size / sizeof (CHAR);
+  CHAR *adr;
+  CHAR *dest;
+  int result = 0;
+
+  adr = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
+		       MAP_PRIVATE | MAP_ANON, -1, 0);
+  dest = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
+			MAP_PRIVATE | MAP_ANON, -1, 0);
+  if (adr == MAP_FAILED || dest == MAP_FAILED)
+    {
+      if (errno == ENOSYS)
+	puts ("No test, mmap not available.");
+      else
+	{
+	  printf ("mmap failed: %m");
+	  result = 1;
+	}
+    }
+  else
+    {
+      int inner, middle, outer;
+
+      mprotect (adr, size, PROT_NONE);
+      mprotect (adr + 2 * nchars, size, PROT_NONE);
+      adr += nchars;
+
+      mprotect (dest, size, PROT_NONE);
+      mprotect (dest + 2 * nchars, size, PROT_NONE);
+      dest += nchars;
+
+      MEMSET (adr, L('T'), nchars);
+
+      /* strlen/wcslen test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+	    {
+	      adr[inner] = L('\0');
+
+	      if (STRLEN (&adr[outer]) != (size_t) (inner - outer))
+		{
+		  printf ("%s flunked for outer = %d, inner = %d\n",
+			  STRINGIFY (STRLEN), outer, inner);
+		  result = 1;
+		}
+
+	      adr[inner] = L('T');
+	    }
+	}
+
+      /* strnlen/wcsnlen test */
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+	    {
+	      adr[inner] = L('\0');
+
+	      if (STRNLEN (&adr[outer], inner - outer + 1)
+		  != (size_t) (inner - outer))
+		{
+		  printf ("%s flunked for outer = %d, inner = %d\n",
+			  STRINGIFY (STRNLEN), outer, inner);
+		  result = 1;
+		}
+
+	      adr[inner] = L('T');
+	    }
+	}
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (inner = MAX (outer, nchars - 64); inner <= nchars; ++inner)
+	    {
+	      if (STRNLEN (&adr[outer], inner - outer)
+		  != (size_t) (inner - outer))
+		{
+		  printf ("%s flunked bounded for outer = %d, inner = %d\n",
+			  STRINGIFY (STRNLEN), outer, inner);
+		  result = 1;
+		}
+	    }
+	}
+
+      /* strchr/wcschr test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+	    {
+	      for (inner = middle; inner < nchars; ++inner)
+		{
+		  adr[middle] = L('V');
+		  adr[inner] = L('\0');
+
+		  CHAR *cp = STRCHR (&adr[outer], L('V'));
+
+		  if ((inner == middle && cp != NULL)
+		      || (inner != middle
+			  && (cp - &adr[outer]) != middle - outer))
+		    {
+		      printf ("%s flunked for outer = %d, middle = %d, "
+			      "inner = %d\n",
+			      STRINGIFY (STRCHR), outer, middle, inner);
+		      result = 1;
+		    }
+
+		  adr[inner] = L('T');
+		  adr[middle] = L('T');
+		}
+	    }
+	}
+
+      /* Special test.  */
+      adr[nchars - 1] = L('\0');
+      if (STRCHR (&adr[nchars - 1], L('\n')) != NULL)
+	{
+	  printf ("%s flunked test of empty string at end of page\n",
+		  STRINGIFY (STRCHR));
+	  result = 1;
+	}
+
+      /* strrchr/wcsrchr test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+	    {
+	      for (inner = middle; inner < nchars; ++inner)
+		{
+		  adr[middle] = L('V');
+		  adr[inner] = L('\0');
+
+		  CHAR *cp = STRRCHR (&adr[outer], L('V'));
+
+		  if ((inner == middle && cp != NULL)
+		      || (inner != middle
+			  && (cp - &adr[outer]) != middle - outer))
+		    {
+		      printf ("%s flunked for outer = %d, middle = %d, "
+			      "inner = %d\n",
+			      STRINGIFY (STRRCHR), outer, middle, inner);
+		      result = 1;
+		    }
+
+		  adr[inner] = L('T');
+		  adr[middle] = L('T');
+		}
+	    }
+	}
+
+      /* memchr test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+	    {
+	      adr[middle] = L('V');
+
+	      CHAR *cp = MEMCHR (&adr[outer], L('V'), 3 * size);
+
+	      if (cp - &adr[outer] != middle - outer)
+		{
+		  printf ("%s flunked for outer = %d, middle = %d\n",
+			  STRINGIFY (MEMCHR), outer, middle);
+		  result = 1;
+		}
+
+	      adr[middle] = L('T');
+	    }
+	}
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  CHAR *cp = MEMCHR (&adr[outer], L('V'), nchars - outer);
+
+	  if (cp != NULL)
+	    {
+	      printf ("%s flunked for outer = %d\n",
+		      STRINGIFY (MEMCHR), outer);
+	      result = 1;
+	    }
+	}
+
+      /* These functions only exist for single-byte characters.  */
+#ifndef WCSTEST
+      /* rawmemchr test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+	    {
+	      adr[middle] = L('V');
+
+	      CHAR *cp = rawmemchr (&adr[outer], L('V'));
+
+	      if (cp - &adr[outer] != middle - outer)
+		{
+		  printf ("%s flunked for outer = %d, middle = %d\n",
+			  STRINGIFY (rawmemchr), outer, middle);
+		  result = 1;
+		}
+
+	      adr[middle] = L('T');
+	    }
+	}
+
+      /* memrchr test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+	    {
+	      adr[middle] = L('V');
+
+	      CHAR *cp = memrchr (&adr[outer], L('V'), nchars - outer);
+
+	      if (cp - &adr[outer] != middle - outer)
+		{
+		  printf ("%s flunked for outer = %d, middle = %d\n",
+			  STRINGIFY (memrchr), outer, middle);
+		  result = 1;
+		}
+
+	      adr[middle] = L('T');
+	    }
+	}
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  CHAR *cp = memrchr (&adr[outer], L('V'), nchars - outer);
+
+	  if (cp != NULL)
+	    {
+	      printf ("%s flunked for outer = %d\n",
+		      STRINGIFY (memrchr), outer);
+	      result = 1;
+	    }
+	}
+#endif
+
+      /* strcpy/wcscpy test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+	    {
+	      adr[inner] = L('\0');
+
+	      if (STRCPY (dest, &adr[outer]) != dest
+		  || STRLEN (dest) != (size_t) (inner - outer))
+		{
+		  printf ("%s flunked for outer = %d, inner = %d\n",
+			  STRINGIFY (STRCPY), outer, inner);
+		  result = 1;
+		}
+
+	      adr[inner] = L('T');
+	    }
+	}
+
+      /* strcmp/wcscmp tests */
+      for (outer = 1; outer < 32; ++outer)
+	for (middle = 0; middle < 16; ++middle)
+	  {
+	    MEMSET (adr + middle, L('T'), 256);
+	    adr[256] = L('\0');
+	    MEMSET (dest + nchars - outer, L('T'), outer - 1);
+	    dest[nchars - 1] = L('\0');
+
+	    if (STRCMP (adr + middle, dest + nchars - outer) <= 0)
+	      {
+		printf ("%s 1 flunked for outer = %d, middle = %d\n",
+			STRINGIFY (STRCMP), outer, middle);
+		result = 1;
+	      }
+
+	    if (STRCMP (dest + nchars - outer, adr + middle) >= 0)
+	      {
+		printf ("%s 2 flunked for outer = %d, middle = %d\n",
+			STRINGIFY (STRCMP), outer, middle);
+		result = 1;
+	      }
+	  }
+
+      /* strncmp/wcsncmp tests */
+      for (outer = 1; outer < 32; ++outer)
+	for (middle = 0; middle < 16; ++middle)
+	  {
+	    MEMSET (adr + middle, L('T'), 256);
+	    adr[256] = L('\0');
+	    MEMSET (dest + nchars - outer, L('T'), outer - 1);
+	    dest[nchars - 1] = L('U');
+
+	    for (inner = 0; inner < outer; ++inner)
+	      {
+		if (STRNCMP (adr + middle, dest + nchars - outer, inner) != 0)
+		  {
+		    printf ("%s 1 flunked for outer = %d, middle = %d, "
+			    "inner = %d\n",
+			    STRINGIFY (STRNCMP), outer, middle, inner);
+		    result = 1;
+		  }
+
+		if (STRNCMP (dest + nchars - outer, adr + middle, inner) != 0)
+		  {
+		    printf ("%s 2 flunked for outer = %d, middle = %d, "
+			    "inner = %d\n",
+			    STRINGIFY (STRNCMP), outer, middle, inner);
+		    result = 1;
+		  }
+	      }
+
+	    if (STRNCMP (adr + middle, dest + nchars - outer, outer) >= 0)
+	      {
+		printf ("%s 1 flunked for outer = %d, middle = %d, full\n",
+			STRINGIFY (STRNCMP), outer, middle);
+		result = 1;
+	      }
+
+	    if (STRNCMP (dest + nchars - outer, adr + middle, outer) <= 0)
+	      {
+		printf ("%s 2 flunked for outer = %d, middle = %d, full\n",
+			STRINGIFY (STRNCMP), outer, middle);
+		result = 1;
+	      }
+	  }
+
+      /* strncpy/wcsncpy tests */
+      adr[nchars - 1] = L('T');
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  size_t len;
+
+	  for (len = 0; len < nchars - outer; ++len)
+	    {
+	      if (STRNCPY (dest, &adr[outer], len) != dest
+		  || MEMCMP (dest, &adr[outer], len) != 0)
+		{
+		  printf ("outer %s flunked for outer = %d, len = %Zd\n",
+			  STRINGIFY (STRNCPY), outer, len);
+		  result = 1;
+		}
+	    }
+	}
+      adr[nchars - 1] = L('\0');
+
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+	    {
+	      size_t len;
+
+	      adr[inner] = L('\0');
+
+	      for (len = 0; len < nchars - outer + 64; ++len)
+		{
+		  if (STRNCPY (dest, &adr[outer], len) != dest
+		      || MEMCMP (dest, &adr[outer],
+				 MIN (inner - outer, len)) != 0
+		      || (inner - outer < len
+			  && STRLEN (dest) != (inner - outer)))
+		    {
+		      printf ("%s flunked for outer = %d, inner = %d, "
+			      "len = %Zd\n",
+			      STRINGIFY (STRNCPY), outer, inner, len);
+		      result = 1;
+		    }
+		  if (STRNCPY (dest + 1, &adr[outer], len) != dest + 1
+		      || MEMCMP (dest + 1, &adr[outer],
+				 MIN (inner - outer, len)) != 0
+		      || (inner - outer < len
+			  && STRLEN (dest + 1) != (inner - outer)))
+		    {
+		      printf ("%s+1 flunked for outer = %d, inner = %d, "
+			      "len = %Zd\n",
+			      STRINGIFY (STRNCPY), outer, inner, len);
+		      result = 1;
+		    }
+		}
+
+	      adr[inner] = L('T');
+	    }
+	}
+
+      /* stpcpy/wcpcpy test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+	    {
+	      adr[inner] = L('\0');
+
+	      if ((STPCPY (dest, &adr[outer]) - dest) != inner - outer)
+		{
+		  printf ("%s flunked for outer = %d, inner = %d\n",
+			  STRINGIFY (STPCPY), outer, inner);
+		  result = 1;
+		}
+
+	      adr[inner] = L('T');
+	    }
+	}
+
+      /* stpncpy/wcpncpy test */
+      adr[nchars - 1] = L('T');
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  size_t len;
+
+	  for (len = 0; len < nchars - outer; ++len)
+	    {
+	      if (STPNCPY (dest, &adr[outer], len) != dest + len
+		  || MEMCMP (dest, &adr[outer], len) != 0)
+		{
+		  printf ("outer %s flunked for outer = %d, len = %Zd\n",
+			  STRINGIFY (STPNCPY), outer, len);
+		  result = 1;
+		}
+	    }
+	}
+      adr[nchars - 1] = L('\0');
+
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	{
+	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+	    {
+	      adr[middle] = L('\0');
+
+	      for (inner = 0; inner < nchars - outer; ++ inner)
+		{
+		  if ((STPNCPY (dest, &adr[outer], inner) - dest)
+		      != MIN (inner, middle - outer))
+		    {
+		      printf ("%s flunked for outer = %d, middle = %d, "
+			      "inner = %d\n",
+			      STRINGIFY (STPNCPY), outer, middle, inner);
+		      result = 1;
+		    }
+		}
+
+	      adr[middle] = L('T');
+	    }
+	}
+
+      /* memcpy/wmemcpy test */
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+	for (inner = 0; inner < nchars - outer; ++inner)
+	  if (MEMCPY (dest, &adr[outer], inner) !=  dest)
+	    {
+	      printf ("%s flunked for outer = %d, inner = %d\n",
+		      STRINGIFY (MEMCPY), outer, inner);
+	      result = 1;
+	    }
+
+      /* mempcpy/wmempcpy test */
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+	for (inner = 0; inner < nchars - outer; ++inner)
+	  if (MEMPCPY (dest, &adr[outer], inner) !=  dest + inner)
+	    {
+	      printf ("%s flunked for outer = %d, inner = %d\n",
+		      STRINGIFY (MEMPCPY), outer, inner);
+	      result = 1;
+	    }
+
+      /* This function only exists for single-byte characters.  */
+#ifndef WCSTEST
+      /* memccpy test */
+      memset (adr, '\0', nchars);
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+	for (inner = 0; inner < nchars - outer; ++inner)
+	  if (memccpy (dest, &adr[outer], L('\1'), inner) != NULL)
+	    {
+	      printf ("memccpy flunked full copy for outer = %d, inner = %d\n",
+		      outer, inner);
+	      result = 1;
+	    }
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	for (middle = 0; middle < nchars - outer; ++middle)
+	  {
+	    memset (dest, L('\2'), middle + 1);
+	    for (inner = 0; inner < middle; ++inner)
+	      {
+		adr[outer + inner] = L('\1');
+
+		if (memccpy (dest, &adr[outer], '\1', middle + 128)
+		    !=  dest + inner + 1)
+		  {
+		    printf ("\
+memccpy flunked partial copy for outer = %d, middle = %d, inner = %d\n",
+			    outer, middle, inner);
+		    result = 1;
+		  }
+		else if (dest[inner + 1] != L('\2'))
+		  {
+		    printf ("\
+memccpy copied too much for outer = %d, middle = %d, inner = %d\n",
+			    outer, middle, inner);
+		    result = 1;
+		  }
+		adr[outer + inner] = L('\0');
+	      }
+	  }
+#endif
+    }
+
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/strcasecmp.c b/REORG.TODO/string/strcasecmp.c
new file mode 100644
index 0000000000..2d6ae0fa9d
--- /dev/null
+++ b/REORG.TODO/string/strcasecmp.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <string.h>
+
+#ifndef _LIBC
+# define __strcasecmp strcasecmp
+# define TOLOWER(Ch) tolower (Ch)
+#else
+# include <locale/localeinfo.h>
+# ifdef USE_IN_EXTENDED_LOCALE_MODEL
+#  define __strcasecmp __strcasecmp_l
+# endif
+# define TOLOWER(Ch) __tolower_l ((Ch), loc)
+#endif
+
+#ifdef USE_IN_EXTENDED_LOCALE_MODEL
+# define LOCALE_PARAM , __locale_t loc
+#else
+# define LOCALE_PARAM
+#endif
+
+/* Compare S1 and S2, ignoring case, returning less than, equal to or
+   greater than zero if S1 is lexicographically less than,
+   equal to or greater than S2.  */
+int
+__strcasecmp (const char *s1, const char *s2 LOCALE_PARAM)
+{
+#if defined _LIBC && !defined USE_IN_EXTENDED_LOCALE_MODEL
+  __locale_t loc = _NL_CURRENT_LOCALE;
+#endif
+  const unsigned char *p1 = (const unsigned char *) s1;
+  const unsigned char *p2 = (const unsigned char *) s2;
+  int result;
+
+  if (p1 == p2)
+    return 0;
+
+  while ((result = TOLOWER (*p1) - TOLOWER (*p2++)) == 0)
+    if (*p1++ == '\0')
+      break;
+
+  return result;
+}
+#ifndef __strcasecmp
+libc_hidden_def (__strcasecmp)
+weak_alias (__strcasecmp, strcasecmp)
+#endif
diff --git a/REORG.TODO/string/strcasecmp_l.c b/REORG.TODO/string/strcasecmp_l.c
new file mode 100644
index 0000000000..78271ad2ef
--- /dev/null
+++ b/REORG.TODO/string/strcasecmp_l.c
@@ -0,0 +1,22 @@
+/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define USE_IN_EXTENDED_LOCALE_MODEL	1
+#include "strcasecmp.c"
+
+libc_hidden_def (__strcasecmp_l)
+weak_alias (__strcasecmp_l, strcasecmp_l)
diff --git a/REORG.TODO/string/strcasestr.c b/REORG.TODO/string/strcasestr.c
new file mode 100644
index 0000000000..2acf003155
--- /dev/null
+++ b/REORG.TODO/string/strcasestr.c
@@ -0,0 +1,104 @@
+/* Return the offset of one string within another.
+   Copyright (C) 1994-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/*
+ * My personal strstr() implementation that beats most other algorithms.
+ * Until someone tells me otherwise, I assume that this is the
+ * fastest implementation of strstr() in C.
+ * I deliberately chose not to comment it.  You should have at least
+ * as much fun trying to understand it, as I had to write it :-).
+ *
+ * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de	*/
+
+/* Specification.  */
+#include <string.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <strings.h>
+
+#define TOLOWER(Ch) tolower (Ch)
+
+/* Two-Way algorithm.  */
+#define RETURN_TYPE char *
+#define AVAILABLE(h, h_l, j, n_l)			\
+  (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))	\
+   && ((h_l) = (j) + (n_l)))
+#define CHECK_EOL (1)
+#define RET0_IF_0(a) if (!a) goto ret0
+#define CANON_ELEMENT(c) TOLOWER (c)
+#define CMP_FUNC(p1, p2, l)				\
+  __strncasecmp ((const char *) (p1), (const char *) (p2), l)
+#include "str-two-way.h"
+
+#undef strcasestr
+#undef __strcasestr
+
+#ifndef STRCASESTR
+#define STRCASESTR __strcasestr
+#endif
+
+
+/* Find the first occurrence of NEEDLE in HAYSTACK, using
+   case-insensitive comparison.  This function gives unspecified
+   results in multibyte locales.  */
+char *
+STRCASESTR (const char *haystack_start, const char *needle_start)
+{
+  const char *haystack = haystack_start;
+  const char *needle = needle_start;
+  size_t needle_len; /* Length of NEEDLE.  */
+  size_t haystack_len; /* Known minimum length of HAYSTACK.  */
+  bool ok = true; /* True if NEEDLE is prefix of HAYSTACK.  */
+
+  /* Determine length of NEEDLE, and in the process, make sure
+     HAYSTACK is at least as long (no point processing all of a long
+     NEEDLE if HAYSTACK is too short).  */
+  while (*haystack && *needle)
+    {
+      ok &= (TOLOWER ((unsigned char) *haystack)
+	     == TOLOWER ((unsigned char) *needle));
+      haystack++;
+      needle++;
+    }
+  if (*needle)
+    return NULL;
+  if (ok)
+    return (char *) haystack_start;
+  needle_len = needle - needle_start;
+  haystack = haystack_start + 1;
+  haystack_len = needle_len - 1;
+
+  /* Perform the search.  Abstract memory is considered to be an array
+     of 'unsigned char' values, not an array of 'char' values.  See
+     ISO C 99 section 6.2.6.1.  */
+  if (needle_len < LONG_NEEDLE_THRESHOLD)
+    return two_way_short_needle ((const unsigned char *) haystack,
+				 haystack_len,
+				 (const unsigned char *) needle_start,
+				 needle_len);
+  return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
+			      (const unsigned char *) needle_start,
+			      needle_len);
+}
+
+#undef LONG_NEEDLE_THRESHOLD
+
+#ifndef NO_ALIAS
+weak_alias (__strcasestr, strcasestr)
+#endif
diff --git a/REORG.TODO/string/strcat.c b/REORG.TODO/string/strcat.c
new file mode 100644
index 0000000000..8373fabc1d
--- /dev/null
+++ b/REORG.TODO/string/strcat.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#undef strcat
+
+#ifndef STRCAT
+# define STRCAT strcat
+#endif
+
+/* Append SRC on the end of DEST.  */
+char *
+STRCAT (char *dest, const char *src)
+{
+  strcpy (dest + strlen (dest), src);
+  return dest;
+}
+libc_hidden_builtin_def (strcat)
diff --git a/REORG.TODO/string/strchr.c b/REORG.TODO/string/strchr.c
new file mode 100644
index 0000000000..50e4172853
--- /dev/null
+++ b/REORG.TODO/string/strchr.c
@@ -0,0 +1,185 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+   with help from Dan Sahlin (dan@sics.se) and
+   bug fix and commentary by Jim Blandy (jimb@ai.mit.edu);
+   adaptation to strchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+   and implemented by Roland McGrath (roland@ai.mit.edu).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <stdlib.h>
+
+#undef strchr
+
+#ifndef STRCHR
+# define STRCHR strchr
+#endif
+
+/* Find the first occurrence of C in S.  */
+char *
+STRCHR (const char *s, int c_in)
+{
+  const unsigned char *char_ptr;
+  const unsigned long int *longword_ptr;
+  unsigned long int longword, magic_bits, charmask;
+  unsigned char c;
+
+  c = (unsigned char) c_in;
+
+  /* Handle the first few characters by reading one character at a time.
+     Do this until CHAR_PTR is aligned on a longword boundary.  */
+  for (char_ptr = (const unsigned char *) s;
+       ((unsigned long int) char_ptr & (sizeof (longword) - 1)) != 0;
+       ++char_ptr)
+    if (*char_ptr == c)
+      return (void *) char_ptr;
+    else if (*char_ptr == '\0')
+      return NULL;
+
+  /* All these elucidatory comments refer to 4-byte longwords,
+     but the theory applies equally well to 8-byte longwords.  */
+
+  longword_ptr = (unsigned long int *) char_ptr;
+
+  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
+     the "holes."  Note that there is a hole just to the left of
+     each byte, with an extra at the end:
+
+     bits:  01111110 11111110 11111110 11111111
+     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
+
+     The 1-bits make sure that carries propagate to the next 0-bit.
+     The 0-bits provide holes for carries to fall into.  */
+  magic_bits = -1;
+  magic_bits = magic_bits / 0xff * 0xfe << 1 >> 1 | 1;
+
+  /* Set up a longword, each of whose bytes is C.  */
+  charmask = c | (c << 8);
+  charmask |= charmask << 16;
+  if (sizeof (longword) > 4)
+    /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
+    charmask |= (charmask << 16) << 16;
+  if (sizeof (longword) > 8)
+    abort ();
+
+  /* Instead of the traditional loop which tests each character,
+     we will test a longword at a time.  The tricky part is testing
+     if *any of the four* bytes in the longword in question are zero.  */
+  for (;;)
+    {
+      /* We tentatively exit the loop if adding MAGIC_BITS to
+	 LONGWORD fails to change any of the hole bits of LONGWORD.
+
+	 1) Is this safe?  Will it catch all the zero bytes?
+	 Suppose there is a byte with all zeros.  Any carry bits
+	 propagating from its left will fall into the hole at its
+	 least significant bit and stop.  Since there will be no
+	 carry from its most significant bit, the LSB of the
+	 byte to the left will be unchanged, and the zero will be
+	 detected.
+
+	 2) Is this worthwhile?  Will it ignore everything except
+	 zero bytes?  Suppose every byte of LONGWORD has a bit set
+	 somewhere.  There will be a carry into bit 8.  If bit 8
+	 is set, this will carry into bit 16.  If bit 8 is clear,
+	 one of bits 9-15 must be set, so there will be a carry
+	 into bit 16.  Similarly, there will be a carry into bit
+	 24.  If one of bits 24-30 is set, there will be a carry
+	 into bit 31, so all of the hole bits will be changed.
+
+	 The one misfire occurs when bits 24-30 are clear and bit
+	 31 is set; in this case, the hole at bit 31 is not
+	 changed.  If we had access to the processor carry flag,
+	 we could close this loophole by putting the fourth hole
+	 at bit 32!
+
+	 So it ignores everything except 128's, when they're aligned
+	 properly.
+
+	 3) But wait!  Aren't we looking for C as well as zero?
+	 Good point.  So what we do is XOR LONGWORD with a longword,
+	 each of whose bytes is C.  This turns each byte that is C
+	 into a zero.  */
+
+      longword = *longword_ptr++;
+
+      /* Add MAGIC_BITS to LONGWORD.  */
+      if ((((longword + magic_bits)
+
+	    /* Set those bits that were unchanged by the addition.  */
+	    ^ ~longword)
+
+	   /* Look at only the hole bits.  If any of the hole bits
+	      are unchanged, most likely one of the bytes was a
+	      zero.  */
+	   & ~magic_bits) != 0 ||
+
+	  /* That caught zeroes.  Now test for C.  */
+	  ((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask))
+	   & ~magic_bits) != 0)
+	{
+	  /* Which of the bytes was C or zero?
+	     If none of them were, it was a misfire; continue the search.  */
+
+	  const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
+
+	  if (*cp == c)
+	    return (char *) cp;
+	  else if (*cp == '\0')
+	    return NULL;
+	  if (*++cp == c)
+	    return (char *) cp;
+	  else if (*cp == '\0')
+	    return NULL;
+	  if (*++cp == c)
+	    return (char *) cp;
+	  else if (*cp == '\0')
+	    return NULL;
+	  if (*++cp == c)
+	    return (char *) cp;
+	  else if (*cp == '\0')
+	    return NULL;
+	  if (sizeof (longword) > 4)
+	    {
+	      if (*++cp == c)
+		return (char *) cp;
+	      else if (*cp == '\0')
+		return NULL;
+	      if (*++cp == c)
+		return (char *) cp;
+	      else if (*cp == '\0')
+		return NULL;
+	      if (*++cp == c)
+		return (char *) cp;
+	      else if (*cp == '\0')
+		return NULL;
+	      if (*++cp == c)
+		return (char *) cp;
+	      else if (*cp == '\0')
+		return NULL;
+	    }
+	}
+    }
+
+  return NULL;
+}
+
+#ifdef weak_alias
+# undef index
+weak_alias (strchr, index)
+#endif
+libc_hidden_builtin_def (strchr)
diff --git a/REORG.TODO/string/strchrnul.c b/REORG.TODO/string/strchrnul.c
new file mode 100644
index 0000000000..d62dc9c595
--- /dev/null
+++ b/REORG.TODO/string/strchrnul.c
@@ -0,0 +1,166 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+   with help from Dan Sahlin (dan@sics.se) and
+   bug fix and commentary by Jim Blandy (jimb@ai.mit.edu);
+   adaptation to strchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+   and implemented by Roland McGrath (roland@ai.mit.edu).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <memcopy.h>
+#include <stdlib.h>
+
+#undef __strchrnul
+#undef strchrnul
+
+#ifndef STRCHRNUL
+# define STRCHRNUL __strchrnul
+#endif
+
+/* Find the first occurrence of C in S or the final NUL byte.  */
+char *
+STRCHRNUL (const char *s, int c_in)
+{
+  const unsigned char *char_ptr;
+  const unsigned long int *longword_ptr;
+  unsigned long int longword, magic_bits, charmask;
+  unsigned char c;
+
+  c = (unsigned char) c_in;
+
+  /* Handle the first few characters by reading one character at a time.
+     Do this until CHAR_PTR is aligned on a longword boundary.  */
+  for (char_ptr = (const unsigned char *) s;
+       ((unsigned long int) char_ptr & (sizeof (longword) - 1)) != 0;
+       ++char_ptr)
+    if (*char_ptr == c || *char_ptr == '\0')
+      return (void *) char_ptr;
+
+  /* All these elucidatory comments refer to 4-byte longwords,
+     but the theory applies equally well to 8-byte longwords.  */
+
+  longword_ptr = (unsigned long int *) char_ptr;
+
+  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
+     the "holes."  Note that there is a hole just to the left of
+     each byte, with an extra at the end:
+
+     bits:  01111110 11111110 11111110 11111111
+     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
+
+     The 1-bits make sure that carries propagate to the next 0-bit.
+     The 0-bits provide holes for carries to fall into.  */
+  magic_bits = -1;
+  magic_bits = magic_bits / 0xff * 0xfe << 1 >> 1 | 1;
+
+  /* Set up a longword, each of whose bytes is C.  */
+  charmask = c | (c << 8);
+  charmask |= charmask << 16;
+  if (sizeof (longword) > 4)
+    /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
+    charmask |= (charmask << 16) << 16;
+  if (sizeof (longword) > 8)
+    abort ();
+
+  /* Instead of the traditional loop which tests each character,
+     we will test a longword at a time.  The tricky part is testing
+     if *any of the four* bytes in the longword in question are zero.  */
+  for (;;)
+    {
+      /* We tentatively exit the loop if adding MAGIC_BITS to
+	 LONGWORD fails to change any of the hole bits of LONGWORD.
+
+	 1) Is this safe?  Will it catch all the zero bytes?
+	 Suppose there is a byte with all zeros.  Any carry bits
+	 propagating from its left will fall into the hole at its
+	 least significant bit and stop.  Since there will be no
+	 carry from its most significant bit, the LSB of the
+	 byte to the left will be unchanged, and the zero will be
+	 detected.
+
+	 2) Is this worthwhile?  Will it ignore everything except
+	 zero bytes?  Suppose every byte of LONGWORD has a bit set
+	 somewhere.  There will be a carry into bit 8.  If bit 8
+	 is set, this will carry into bit 16.  If bit 8 is clear,
+	 one of bits 9-15 must be set, so there will be a carry
+	 into bit 16.  Similarly, there will be a carry into bit
+	 24.  If one of bits 24-30 is set, there will be a carry
+	 into bit 31, so all of the hole bits will be changed.
+
+	 The one misfire occurs when bits 24-30 are clear and bit
+	 31 is set; in this case, the hole at bit 31 is not
+	 changed.  If we had access to the processor carry flag,
+	 we could close this loophole by putting the fourth hole
+	 at bit 32!
+
+	 So it ignores everything except 128's, when they're aligned
+	 properly.
+
+	 3) But wait!  Aren't we looking for C as well as zero?
+	 Good point.  So what we do is XOR LONGWORD with a longword,
+	 each of whose bytes is C.  This turns each byte that is C
+	 into a zero.  */
+
+      longword = *longword_ptr++;
+
+      /* Add MAGIC_BITS to LONGWORD.  */
+      if ((((longword + magic_bits)
+
+	    /* Set those bits that were unchanged by the addition.  */
+	    ^ ~longword)
+
+	   /* Look at only the hole bits.  If any of the hole bits
+	      are unchanged, most likely one of the bytes was a
+	      zero.  */
+	   & ~magic_bits) != 0 ||
+
+	  /* That caught zeroes.  Now test for C.  */
+	  ((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask))
+	   & ~magic_bits) != 0)
+	{
+	  /* Which of the bytes was C or zero?
+	     If none of them were, it was a misfire; continue the search.  */
+
+	  const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
+
+	  if (*cp == c || *cp == '\0')
+	    return (char *) cp;
+	  if (*++cp == c || *cp == '\0')
+	    return (char *) cp;
+	  if (*++cp == c || *cp == '\0')
+	    return (char *) cp;
+	  if (*++cp == c || *cp == '\0')
+	    return (char *) cp;
+	  if (sizeof (longword) > 4)
+	    {
+	      if (*++cp == c || *cp == '\0')
+		return (char *) cp;
+	      if (*++cp == c || *cp == '\0')
+		return (char *) cp;
+	      if (*++cp == c || *cp == '\0')
+		return (char *) cp;
+	      if (*++cp == c || *cp == '\0')
+		return (char *) cp;
+	    }
+	}
+    }
+
+  /* This should never happen.  */
+  return NULL;
+}
+
+weak_alias (__strchrnul, strchrnul)
diff --git a/REORG.TODO/string/strcmp.c b/REORG.TODO/string/strcmp.c
new file mode 100644
index 0000000000..a818285ea2
--- /dev/null
+++ b/REORG.TODO/string/strcmp.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#undef strcmp
+
+#ifndef STRCMP
+# define STRCMP strcmp
+#endif
+
+/* Compare S1 and S2, returning less than, equal to or
+   greater than zero if S1 is lexicographically less than,
+   equal to or greater than S2.  */
+int
+STRCMP (const char *p1, const char *p2)
+{
+  const unsigned char *s1 = (const unsigned char *) p1;
+  const unsigned char *s2 = (const unsigned char *) p2;
+  unsigned char c1, c2;
+
+  do
+    {
+      c1 = (unsigned char) *s1++;
+      c2 = (unsigned char) *s2++;
+      if (c1 == '\0')
+	return c1 - c2;
+    }
+  while (c1 == c2);
+
+  return c1 - c2;
+}
+libc_hidden_builtin_def (strcmp)
diff --git a/REORG.TODO/string/strcoll.c b/REORG.TODO/string/strcoll.c
new file mode 100644
index 0000000000..8996bf90f4
--- /dev/null
+++ b/REORG.TODO/string/strcoll.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#ifndef STRING_TYPE
+# define STRING_TYPE char
+# define STRCOLL strcoll
+# define STRCOLL_L __strcoll_l
+# define USE_HIDDEN_DEF
+#endif
+
+#include "../locale/localeinfo.h"
+
+
+int
+STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2)
+{
+  return STRCOLL_L (s1, s2, _NL_CURRENT_LOCALE);
+}
+
+#ifdef USE_HIDDEN_DEF
+libc_hidden_def (STRCOLL)
+#endif
diff --git a/REORG.TODO/string/strcoll_l.c b/REORG.TODO/string/strcoll_l.c
new file mode 100644
index 0000000000..8fd55b000a
--- /dev/null
+++ b/REORG.TODO/string/strcoll_l.c
@@ -0,0 +1,363 @@
+/* Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Ulrich Drepper <drepper@gnu.org>, 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+#include <assert.h>
+#include <langinfo.h>
+#include <locale.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/param.h>
+
+#ifndef STRING_TYPE
+# define STRING_TYPE char
+# define USTRING_TYPE unsigned char
+# define STRCOLL __strcoll_l
+# define STRCMP strcmp
+# define WEIGHT_H "../locale/weight.h"
+# define SUFFIX	MB
+# define L(arg) arg
+#endif
+
+#define CONCAT(a,b) CONCAT1(a,b)
+#define CONCAT1(a,b) a##b
+
+#include "../locale/localeinfo.h"
+#include WEIGHT_H
+
+/* Track status while looking for sequences in a string.  */
+typedef struct
+{
+  int len;			/* Length of the current sequence.  */
+  size_t val;			/* Position of the sequence relative to the
+				   previous non-ignored sequence.  */
+  size_t idxmax;		/* Maximum index in sequences.  */
+  size_t idxcnt;		/* Current count of indices.  */
+  size_t backw;			/* Current Backward sequence index.  */
+  size_t backw_stop;		/* Index where the backward sequences stop.  */
+  const USTRING_TYPE *us;	/* The string.  */
+  unsigned char rule;		/* Saved rule for the first sequence.  */
+  int32_t idx;			/* Index to weight of the current sequence.  */
+  int32_t save_idx;		/* Save looked up index of a forward
+				   sequence after the last backward
+				   sequence.  */
+  const USTRING_TYPE *back_us;	/* Beginning of the backward sequence.  */
+} coll_seq;
+
+/* Get next sequence.  Traverse the string as required.  */
+static __always_inline void
+get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
+	      const USTRING_TYPE *weights, const int32_t *table,
+	      const USTRING_TYPE *extra, const int32_t *indirect,
+	      int pass)
+{
+  size_t val = seq->val = 0;
+  int len = seq->len;
+  size_t backw_stop = seq->backw_stop;
+  size_t backw = seq->backw;
+  size_t idxcnt = seq->idxcnt;
+  size_t idxmax = seq->idxmax;
+  int32_t idx = seq->idx;
+  const USTRING_TYPE *us = seq->us;
+
+  while (len == 0)
+    {
+      ++val;
+      if (backw_stop != ~0ul)
+	{
+	  /* There is something pushed.  */
+	  if (backw == backw_stop)
+	    {
+	      /* The last pushed character was handled.  Continue
+		 with forward characters.  */
+	      if (idxcnt < idxmax)
+		{
+		  idx = seq->save_idx;
+		  backw_stop = ~0ul;
+		}
+	      else
+		{
+		  /* Nothing anymore.  The backward sequence ended with
+		     the last sequence in the string.  Note that len is
+		     still zero.  */
+		  idx = 0;
+		  break;
+	        }
+	    }
+	  else
+	    {
+	      /* XXX Traverse BACKW sequences from the beginning of
+		 BACKW_STOP to get the next sequence.  Is ther a quicker way
+	         to do this?  */
+	      size_t i = backw_stop;
+	      us = seq->back_us;
+	      while (i < backw)
+		{
+		  int32_t tmp = findidx (table, indirect, extra, &us, -1);
+		  idx = tmp & 0xffffff;
+		  i++;
+		}
+	      --backw;
+	      us = seq->us;
+	    }
+	}
+      else
+	{
+	  backw_stop = idxmax;
+	  int32_t prev_idx = idx;
+
+	  while (*us != L('\0'))
+	    {
+	      int32_t tmp = findidx (table, indirect, extra, &us, -1);
+	      unsigned char rule = tmp >> 24;
+	      prev_idx = idx;
+	      idx = tmp & 0xffffff;
+	      idxcnt = idxmax++;
+
+	      /* Save the rule for the first sequence.  */
+	      if (__glibc_unlikely (idxcnt == 0))
+	        seq->rule = rule;
+
+	      if ((rulesets[rule * nrules + pass]
+		   & sort_backward) == 0)
+		/* No more backward characters to push.  */
+		break;
+	      ++idxcnt;
+	    }
+
+	  if (backw_stop >= idxcnt)
+	    {
+	      /* No sequence at all or just one.  */
+	      if (idxcnt == idxmax || backw_stop > idxcnt)
+		/* Note that len is still zero.  */
+		break;
+
+	      backw_stop = ~0ul;
+	    }
+	  else
+	    {
+	      /* We pushed backward sequences.  If the stream ended with the
+		 backward sequence, then we process the last sequence we
+		 found.  Otherwise we process the sequence before the last
+		 one since the last one was a forward sequence.  */
+	      seq->back_us = seq->us;
+	      seq->us = us;
+	      backw = idxcnt;
+	      if (idxmax > idxcnt)
+		{
+		  backw--;
+		  seq->save_idx = idx;
+		  idx = prev_idx;
+		}
+	      if (backw > backw_stop)
+		backw--;
+	    }
+	}
+
+      /* With GCC 5.3 when compiling with -Os the compiler complains
+	 that idx, taken from seq->idx (seq1 or seq2 from STRCOLL) may
+	 be used uninitialized.  In general this can't possibly be true
+	 since seq1.idx and seq2.idx are initialized to zero in the
+	 outer function.  Only one case where seq->idx is restored from
+	 seq->save_idx might result in an uninitialized idx value, but
+	 it is guarded by a sequence of checks against backw_stop which
+	 ensures that seq->save_idx was saved to first and contains a
+	 valid value.  */
+      DIAG_PUSH_NEEDS_COMMENT;
+      DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+      len = weights[idx++];
+      DIAG_POP_NEEDS_COMMENT;
+      /* Skip over indices of previous levels.  */
+      for (int i = 0; i < pass; i++)
+	{
+	  idx += len;
+	  len = weights[idx];
+	  idx++;
+	}
+    }
+
+  /* Update the structure.  */
+  seq->val = val;
+  seq->len = len;
+  seq->backw_stop = backw_stop;
+  seq->backw = backw;
+  seq->idxcnt = idxcnt;
+  seq->idxmax = idxmax;
+  seq->us = us;
+  seq->idx = idx;
+}
+
+/* Compare two sequences.  */
+static __always_inline int
+do_compare (coll_seq *seq1, coll_seq *seq2, int position,
+	    const USTRING_TYPE *weights)
+{
+  int seq1len = seq1->len;
+  int seq2len = seq2->len;
+  size_t val1 = seq1->val;
+  size_t val2 = seq2->val;
+  int idx1 = seq1->idx;
+  int idx2 = seq2->idx;
+  int result = 0;
+
+  /* Test for position if necessary.  */
+  if (position && val1 != val2)
+    {
+      result = val1 > val2 ? 1 : -1;
+      goto out;
+    }
+
+  /* Compare the two sequences.  */
+  do
+    {
+      if (weights[idx1] != weights[idx2])
+	{
+	  /* The sequences differ.  */
+	  result = weights[idx1] - weights[idx2];
+	  goto out;
+	}
+
+      /* Increment the offsets.  */
+      ++idx1;
+      ++idx2;
+
+      --seq1len;
+      --seq2len;
+    }
+  while (seq1len > 0 && seq2len > 0);
+
+  if (position && seq1len != seq2len)
+    result = seq1len - seq2len;
+
+out:
+  seq1->len = seq1len;
+  seq2->len = seq2len;
+  seq1->idx = idx1;
+  seq2->idx = idx2;
+  return result;
+}
+
+int
+STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+{
+  struct __locale_data *current = l->__locales[LC_COLLATE];
+  uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
+  /* We don't assign the following values right away since it might be
+     unnecessary in case there are no rules.  */
+  const unsigned char *rulesets;
+  const int32_t *table;
+  const USTRING_TYPE *weights;
+  const USTRING_TYPE *extra;
+  const int32_t *indirect;
+
+  if (nrules == 0)
+    return STRCMP (s1, s2);
+
+  /* Catch empty strings.  */
+  if (__glibc_unlikely (*s1 == '\0') || __glibc_unlikely (*s2 == '\0'))
+    return (*s1 != '\0') - (*s2 != '\0');
+
+  rulesets = (const unsigned char *)
+    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
+  table = (const int32_t *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
+  weights = (const USTRING_TYPE *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
+  extra = (const USTRING_TYPE *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
+  indirect = (const int32_t *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
+
+  assert (((uintptr_t) table) % __alignof__ (table[0]) == 0);
+  assert (((uintptr_t) weights) % __alignof__ (weights[0]) == 0);
+  assert (((uintptr_t) extra) % __alignof__ (extra[0]) == 0);
+  assert (((uintptr_t) indirect) % __alignof__ (indirect[0]) == 0);
+
+  int result = 0, rule = 0;
+
+  coll_seq seq1, seq2;
+  seq1.len = 0;
+  seq1.idxmax = 0;
+  seq1.rule = 0;
+  seq2.len = 0;
+  seq2.idxmax = 0;
+
+  for (int pass = 0; pass < nrules; ++pass)
+    {
+      seq1.idxcnt = 0;
+      seq1.idx = 0;
+      seq2.idx = 0;
+      seq1.backw_stop = ~0ul;
+      seq1.backw = ~0ul;
+      seq2.idxcnt = 0;
+      seq2.backw_stop = ~0ul;
+      seq2.backw = ~0ul;
+
+      /* We need the elements of the strings as unsigned values since they
+	 are used as indices.  */
+      seq1.us = (const USTRING_TYPE *) s1;
+      seq2.us = (const USTRING_TYPE *) s2;
+
+      /* We assume that if a rule has defined `position' in one section
+	 this is true for all of them.  Please note that the localedef programs
+	 makes sure that `position' is not used at the first level.  */
+
+      int position = rulesets[rule * nrules + pass] & sort_position;
+
+      while (1)
+	{
+	  get_next_seq (&seq1, nrules, rulesets, weights, table,
+				    extra, indirect, pass);
+	  get_next_seq (&seq2, nrules, rulesets, weights, table,
+				    extra, indirect, pass);
+	  /* See whether any or both strings are empty.  */
+	  if (seq1.len == 0 || seq2.len == 0)
+	    {
+	      if (seq1.len == seq2.len)
+		{
+		  /* Both strings ended and are equal at this level.  Do a
+		     byte-level comparison to ensure that we don't waste time
+		     going through multiple passes for totally equal strings
+		     before proceeding to subsequent passes.  */
+		  if (pass == 0 && STRCMP (s1, s2) == 0)
+		    return result;
+		  else
+		    break;
+	        }
+
+	      /* This means one string is shorter than the other.  Find out
+		 which one and return an appropriate value.  */
+	      return seq1.len == 0 ? -1 : 1;
+	    }
+
+	  result = do_compare (&seq1, &seq2, position, weights);
+	  if (result != 0)
+	    return result;
+	}
+
+      rule = seq1.rule;
+    }
+
+  return result;
+}
+libc_hidden_def (STRCOLL)
+
+#ifndef WIDE_CHAR_VERSION
+weak_alias (__strcoll_l, strcoll_l)
+#endif
diff --git a/REORG.TODO/string/strcpy.c b/REORG.TODO/string/strcpy.c
new file mode 100644
index 0000000000..120da44ee7
--- /dev/null
+++ b/REORG.TODO/string/strcpy.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <string.h>
+
+#undef strcpy
+
+#ifndef STRCPY
+# define STRCPY strcpy
+#endif
+
+/* Copy SRC to DEST.  */
+char *
+STRCPY (char *dest, const char *src)
+{
+  return memcpy (dest, src, strlen (src) + 1);
+}
+libc_hidden_builtin_def (strcpy)
diff --git a/REORG.TODO/string/strcspn.c b/REORG.TODO/string/strcspn.c
new file mode 100644
index 0000000000..1035552a8e
--- /dev/null
+++ b/REORG.TODO/string/strcspn.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include <libc-pointer-arith.h>
+
+#undef strcspn
+
+#ifndef STRCSPN
+# define STRCSPN strcspn
+#endif
+
+/* Return the length of the maximum initial segment of S
+   which contains no characters from REJECT.  */
+size_t
+STRCSPN (const char *str, const char *reject)
+{
+  if (__glibc_unlikely (reject[0] == '\0') ||
+      __glibc_unlikely (reject[1] == '\0'))
+    return __strchrnul (str, reject [0]) - str;
+
+  /* Use multiple small memsets to enable inlining on most targets.  */
+  unsigned char table[256];
+  unsigned char *p = memset (table, 0, 64);
+  memset (p + 64, 0, 64);
+  memset (p + 128, 0, 64);
+  memset (p + 192, 0, 64);
+
+  unsigned char *s = (unsigned char*) reject;
+  unsigned char tmp;
+  do
+    p[tmp = *s++] = 1;
+  while (tmp);
+
+  s = (unsigned char*) str;
+  if (p[s[0]]) return 0;
+  if (p[s[1]]) return 1;
+  if (p[s[2]]) return 2;
+  if (p[s[3]]) return 3;
+
+  s = (unsigned char *) PTR_ALIGN_DOWN (s, 4);
+
+  unsigned int c0, c1, c2, c3;
+  do
+    {
+      s += 4;
+      c0 = p[s[0]];
+      c1 = p[s[1]];
+      c2 = p[s[2]];
+      c3 = p[s[3]];
+    }
+  while ((c0 | c1 | c2 | c3) == 0);
+
+  size_t count = s - (unsigned char *) str;
+  return (c0 | c1) != 0 ? count - c0 + 1 : count - c2 + 3;
+}
+libc_hidden_builtin_def (strcspn)
diff --git a/REORG.TODO/string/strdup.c b/REORG.TODO/string/strdup.c
new file mode 100644
index 0000000000..40993fce1a
--- /dev/null
+++ b/REORG.TODO/string/strdup.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined _LIBC || defined  STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+char *malloc ();
+char *memcpy ();
+#endif
+
+#undef __strdup
+#undef strdup
+
+#ifndef weak_alias
+# define __strdup strdup
+#endif
+
+/* Duplicate S, returning an identical malloc'd string.  */
+char *
+__strdup (const char *s)
+{
+  size_t len = strlen (s) + 1;
+  void *new = malloc (len);
+
+  if (new == NULL)
+    return NULL;
+
+  return (char *) memcpy (new, s, len);
+}
+#ifdef libc_hidden_def
+libc_hidden_def (__strdup)
+#endif
+#ifdef weak_alias
+weak_alias (__strdup, strdup)
+#endif
diff --git a/REORG.TODO/string/strerror.c b/REORG.TODO/string/strerror.c
new file mode 100644
index 0000000000..0d235c6b6b
--- /dev/null
+++ b/REORG.TODO/string/strerror.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libintl.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+/* Return a string describing the errno code in ERRNUM.
+   The storage is good only until the next call to strerror.
+   Writing to the storage causes undefined behavior.  */
+libc_freeres_ptr (static char *buf);
+
+char *
+strerror (int errnum)
+{
+  char *ret = __strerror_r (errnum, NULL, 0);
+  int saved_errno;
+
+  if (__glibc_likely (ret != NULL))
+    return ret;
+  saved_errno = errno;
+  if (buf == NULL)
+    buf = malloc (1024);
+  __set_errno (saved_errno);
+  if (buf == NULL)
+    return _("Unknown error");
+  return __strerror_r (errnum, buf, 1024);
+}
diff --git a/REORG.TODO/string/strerror_l.c b/REORG.TODO/string/strerror_l.c
new file mode 100644
index 0000000000..03a3257dfd
--- /dev/null
+++ b/REORG.TODO/string/strerror_l.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 2007-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libintl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+
+
+static __thread char *last_value;
+
+
+static const char *
+translate (const char *str, locale_t loc)
+{
+  locale_t oldloc = __uselocale (loc);
+  const char *res = _(str);
+  __uselocale (oldloc);
+  return res;
+}
+
+
+/* Return a string describing the errno code in ERRNUM.  */
+char *
+strerror_l (int errnum, locale_t loc)
+{
+
+
+  if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal
+			|| _sys_errlist_internal[errnum] == NULL, 0))
+    {
+      free (last_value);
+      if (__asprintf (&last_value, "%s%d",
+		      translate ("Unknown error ", loc), errnum) == -1)
+	last_value = NULL;
+
+      return last_value;
+    }
+
+  return (char *) translate (_sys_errlist_internal[errnum], loc);
+}
+
+
+#ifdef _LIBC
+# ifdef _LIBC_REENTRANT
+/* This is called when a thread is exiting to free the last_value string.  */
+static void __attribute__ ((section ("__libc_thread_freeres_fn")))
+strerror_thread_freeres (void)
+{
+  free (last_value);
+}
+text_set_element (__libc_thread_subfreeres, strerror_thread_freeres);
+text_set_element (__libc_subfreeres, strerror_thread_freeres);
+# endif
+#endif
diff --git a/REORG.TODO/string/strfry.c b/REORG.TODO/string/strfry.c
new file mode 100644
index 0000000000..9d1bd88d4d
--- /dev/null
+++ b/REORG.TODO/string/strfry.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+char *
+strfry (char *string)
+{
+  static int init;
+  static struct random_data rdata;
+
+  if (!init)
+    {
+      static char state[32];
+      rdata.state = NULL;
+      __initstate_r (time ((time_t *) NULL) ^ getpid (),
+		     state, sizeof (state), &rdata);
+      init = 1;
+    }
+
+  size_t len = strlen (string);
+  if (len > 0)
+    for (size_t i = 0; i < len - 1; ++i)
+      {
+	int32_t j;
+	__random_r (&rdata, &j);
+	j = j % (len - i) + i;
+
+	char c = string[i];
+	string[i] = string[j];
+	string[j] = c;
+      }
+
+  return string;
+}
diff --git a/REORG.TODO/string/string-inlines.c b/REORG.TODO/string/string-inlines.c
new file mode 100644
index 0000000000..fa4a1594b2
--- /dev/null
+++ b/REORG.TODO/string/string-inlines.c
@@ -0,0 +1,570 @@
+/* Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/*  <bits/string.h> and <bits/string2.h> declare some extern inline
+    functions.  These functions are declared additionally here if
+    inlining is not possible.  */
+
+#undef __USE_STRING_INLINES
+#define __USE_STRING_INLINES
+#define _FORCE_INLINES
+#define __STRING_INLINE /* empty */
+#define __NO_INLINE__
+
+#include <string.h>
+#undef index
+#undef rindex
+
+#undef __NO_INLINE__
+#include <bits/string.h>
+#include <bits/string2.h>
+
+#include "shlib-compat.h"
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_25)
+/* The inline functions are not used from GLIBC 2.25 and forward, however
+   they are required to provide the symbols through string-inlines.c
+   (if inlining is not possible for compatibility reasons).  */
+
+char *
+__old_strtok_r_1c (char *__s, char __sep, char **__nextp)
+{
+  char *__result;
+  if (__s == NULL)
+    __s = *__nextp;
+  while (*__s == __sep)
+    ++__s;
+  __result = NULL;
+  if (*__s != '\0')
+    {
+      __result = __s++;
+      while (*__s != '\0')
+	if (*__s++ == __sep)
+	  {
+	    __s[-1] = '\0';
+	    break;
+	  }
+    }
+  *__nextp = __s;
+  return __result;
+}
+compat_symbol (libc, __old_strtok_r_1c, __strtok_r_1c, GLIBC_2_1_1);
+
+char *
+__old_strsep_1c (char **__s, char __reject)
+{
+  char *__retval = *__s;
+  if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
+    *(*__s)++ = '\0';
+  return __retval;
+}
+compat_symbol (libc, __old_strsep_1c, __strsep_1c, GLIBC_2_1_1);
+
+char *
+__old_strsep_2c (char **__s, char __reject1, char __reject2)
+{
+  char *__retval = *__s;
+  if (__retval != NULL)
+    {
+      char *__cp = __retval;
+      while (1)
+	{
+	  if (*__cp == '\0')
+	    {
+	      __cp = NULL;
+	      break;
+	    }
+	  if (*__cp == __reject1 || *__cp == __reject2)
+	    {
+	      *__cp++ = '\0';
+	      break;
+	    }
+	  ++__cp;
+	}
+      *__s = __cp;
+    }
+  return __retval;
+}
+compat_symbol (libc, __old_strsep_2c, __strsep_2c, GLIBC_2_1_1);
+
+char *
+__old_strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
+{
+  char *__retval = *__s;
+  if (__retval != NULL)
+    {
+      char *__cp = __retval;
+      while (1)
+	{
+	  if (*__cp == '\0')
+	    {
+	      __cp = NULL;
+	      break;
+	    }
+	  if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
+	    {
+	      *__cp++ = '\0';
+	      break;
+	    }
+	  ++__cp;
+	}
+      *__s = __cp;
+    }
+  return __retval;
+}
+compat_symbol (libc, __old_strsep_3c, __strsep_3c, GLIBC_2_1_1);
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_24)
+/* The inline functions are not used from GLIBC 2.24 and forward, however
+   they are required to provide the symbols through string-inlines.c
+   (if inlining is not possible for compatibility reasons).  */
+size_t
+__old_strcspn_c1 (const char *__s, int __reject)
+{
+  size_t __result = 0;
+  while (__s[__result] != '\0' && __s[__result] != __reject)
+    ++__result;
+  return __result;
+}
+compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1);
+
+size_t
+__old_strcspn_c2 (const char *__s, int __reject1, int __reject2)
+{
+  size_t __result = 0;
+  while (__s[__result] != '\0' && __s[__result] != __reject1
+	 && __s[__result] != __reject2)
+    ++__result;
+  return __result;
+}
+compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1);
+
+size_t
+__old_strcspn_c3 (const char *__s, int __reject1, int __reject2,
+	      int __reject3)
+{
+  size_t __result = 0;
+  while (__s[__result] != '\0' && __s[__result] != __reject1
+	 && __s[__result] != __reject2 && __s[__result] != __reject3)
+    ++__result;
+  return __result;
+}
+compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1);
+
+size_t
+__old_strspn_c1 (const char *__s, int __accept)
+{
+  size_t __result = 0;
+  /* Please note that __accept never can be '\0'.  */
+  while (__s[__result] == __accept)
+    ++__result;
+  return __result;
+}
+compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1);
+
+size_t
+__old_strspn_c2 (const char *__s, int __accept1, int __accept2)
+{
+  size_t __result = 0;
+  /* Please note that __accept1 and __accept2 never can be '\0'.  */
+  while (__s[__result] == __accept1 || __s[__result] == __accept2)
+    ++__result;
+  return __result;
+}
+compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1);
+
+size_t
+__old_strspn_c3 (const char *__s, int __accept1, int __accept2,
+		 int __accept3)
+{
+  size_t __result = 0;
+  /* Please note that __accept1 to __accept3 never can be '\0'.  */
+  while (__s[__result] == __accept1 || __s[__result] == __accept2
+	 || __s[__result] == __accept3)
+    ++__result;
+  return __result;
+}
+compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1);
+
+char *
+__old_strpbrk_c2 (const char *__s, int __accept1, int __accept2)
+{
+  /* Please note that __accept1 and __accept2 never can be '\0'.  */
+  while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
+    ++__s;
+  return *__s == '\0' ? NULL : (char *) (size_t) __s;
+}
+compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1);
+
+char *
+__old_strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
+{
+  /* Please note that __accept1 to __accept3 never can be '\0'.  */
+  while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
+	 && *__s != __accept3)
+    ++__s;
+  return *__s == '\0' ? NULL : (char *) (size_t) __s;
+}
+compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1);
+
+/* These are a few types we need for the optimizations if we cannot
+   use unaligned memory accesses.  */
+# define __STRING2_COPY_TYPE(N) \
+  typedef struct { unsigned char __arr[N]; }				      \
+    __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
+__STRING2_COPY_TYPE (2);
+__STRING2_COPY_TYPE (3);
+__STRING2_COPY_TYPE (4);
+__STRING2_COPY_TYPE (5);
+__STRING2_COPY_TYPE (6);
+__STRING2_COPY_TYPE (7);
+__STRING2_COPY_TYPE (8);
+# undef __STRING2_COPY_TYPE
+
+
+# if _STRING_INLINE_unaligned
+void *
+__old_mempcpy_small (void *__dest1,
+		     char __src0_1, char __src2_1, char __src4_1, char __src6_1,
+		     __uint16_t __src0_2, __uint16_t __src4_2,
+		     __uint32_t __src0_4, __uint32_t __src4_4,
+		     size_t __srclen)
+{
+  union {
+    __uint32_t __ui;
+    __uint16_t __usi;
+    unsigned char __uc;
+    unsigned char __c;
+  } *__u = __dest1;
+  switch ((unsigned int) __srclen)
+    {
+    case 1:
+      __u->__c = __src0_1;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 2:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 2);
+      break;
+    case 3:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__c = __src2_1;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 4:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      break;
+    case 5:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__c = __src4_1;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 6:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 2);
+      break;
+    case 7:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__c = __src6_1;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 8:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__ui = __src4_4;
+      __u = __extension__ ((void *) __u + 4);
+      break;
+    }
+  return (void *) __u;
+}
+
+# else
+
+void *
+__old_mempcpy_small (void *__dest, char __src1,
+		     __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
+		     __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
+		     __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
+		     __STRING2_COPY_ARR8 __src8, size_t __srclen)
+{
+  union {
+    char __c;
+    __STRING2_COPY_ARR2 __sca2;
+    __STRING2_COPY_ARR3 __sca3;
+    __STRING2_COPY_ARR4 __sca4;
+    __STRING2_COPY_ARR5 __sca5;
+    __STRING2_COPY_ARR6 __sca6;
+    __STRING2_COPY_ARR7 __sca7;
+    __STRING2_COPY_ARR8 __sca8;
+  } *__u = __dest;
+  switch ((unsigned int) __srclen)
+    {
+    case 1:
+      __u->__c = __src1;
+      break;
+    case 2:
+      __extension__ __u->__sca2 = __src2;
+      break;
+    case 3:
+      __extension__ __u->__sca3 = __src3;
+      break;
+    case 4:
+      __extension__ __u->__sca4 = __src4;
+      break;
+    case 5:
+      __extension__ __u->__sca5 = __src5;
+      break;
+    case 6:
+      __extension__ __u->__sca6 = __src6;
+      break;
+    case 7:
+      __extension__ __u->__sca7 = __src7;
+      break;
+    case 8:
+      __extension__ __u->__sca8 = __src8;
+      break;
+    }
+  return __extension__ ((void *) __u + __srclen);
+}
+# endif
+compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1);
+
+# if _STRING_INLINE_unaligned
+char *
+__old_strcpy_small (char *__dest,
+		    __uint16_t __src0_2, __uint16_t __src4_2,
+		    __uint32_t __src0_4, __uint32_t __src4_4,
+		    size_t __srclen)
+{
+  union {
+    __uint32_t __ui;
+    __uint16_t __usi;
+    unsigned char __uc;
+  } *__u = (void *) __dest;
+  switch ((unsigned int) __srclen)
+    {
+    case 1:
+      __u->__uc = '\0';
+      break;
+    case 2:
+      __u->__usi = __src0_2;
+      break;
+    case 3:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__uc = '\0';
+      break;
+    case 4:
+      __u->__ui = __src0_4;
+      break;
+    case 5:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__uc = '\0';
+      break;
+    case 6:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      break;
+    case 7:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__uc = '\0';
+      break;
+    case 8:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__ui = __src4_4;
+      break;
+    }
+  return __dest;
+}
+
+# else
+
+char *
+__old_strcpy_small (char *__dest,
+		    __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
+		    __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
+		    __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
+		    __STRING2_COPY_ARR8 __src8, size_t __srclen)
+{
+  union {
+    char __c;
+    __STRING2_COPY_ARR2 __sca2;
+    __STRING2_COPY_ARR3 __sca3;
+    __STRING2_COPY_ARR4 __sca4;
+    __STRING2_COPY_ARR5 __sca5;
+    __STRING2_COPY_ARR6 __sca6;
+    __STRING2_COPY_ARR7 __sca7;
+    __STRING2_COPY_ARR8 __sca8;
+  } *__u = (void *) __dest;
+  switch ((unsigned int) __srclen)
+    {
+    case 1:
+      __u->__c = '\0';
+      break;
+    case 2:
+      __extension__ __u->__sca2 = __src2;
+      break;
+    case 3:
+      __extension__ __u->__sca3 = __src3;
+      break;
+    case 4:
+      __extension__ __u->__sca4 = __src4;
+      break;
+    case 5:
+      __extension__ __u->__sca5 = __src5;
+      break;
+    case 6:
+      __extension__ __u->__sca6 = __src6;
+      break;
+    case 7:
+      __extension__ __u->__sca7 = __src7;
+      break;
+    case 8:
+      __extension__ __u->__sca8 = __src8;
+      break;
+  }
+  return __dest;
+}
+# endif
+compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1);
+
+# if _STRING_INLINE_unaligned
+char *
+__old_stpcpy_small (char *__dest,
+		    __uint16_t __src0_2, __uint16_t __src4_2,
+		    __uint32_t __src0_4, __uint32_t __src4_4,
+		    size_t __srclen)
+{
+  union {
+    unsigned int __ui;
+    unsigned short int __usi;
+    unsigned char __uc;
+    char __c;
+  } *__u = (void *) __dest;
+  switch ((unsigned int) __srclen)
+    {
+    case 1:
+      __u->__uc = '\0';
+      break;
+    case 2:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 3:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__uc = '\0';
+      break;
+    case 4:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 3);
+      break;
+    case 5:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__uc = '\0';
+      break;
+    case 6:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 7:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__uc = '\0';
+      break;
+    case 8:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__ui = __src4_4;
+      __u = __extension__ ((void *) __u + 3);
+      break;
+    }
+  return &__u->__c;
+}
+
+# else
+
+char *
+__old_stpcpy_small (char *__dest,
+		    __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
+		    __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
+		    __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
+		    __STRING2_COPY_ARR8 __src8, size_t __srclen)
+{
+  union {
+    char __c;
+    __STRING2_COPY_ARR2 __sca2;
+    __STRING2_COPY_ARR3 __sca3;
+    __STRING2_COPY_ARR4 __sca4;
+    __STRING2_COPY_ARR5 __sca5;
+    __STRING2_COPY_ARR6 __sca6;
+    __STRING2_COPY_ARR7 __sca7;
+    __STRING2_COPY_ARR8 __sca8;
+  } *__u = (void *) __dest;
+  switch ((unsigned int) __srclen)
+    {
+    case 1:
+      __u->__c = '\0';
+      break;
+    case 2:
+      __extension__ __u->__sca2 = __src2;
+      break;
+    case 3:
+      __extension__ __u->__sca3 = __src3;
+      break;
+    case 4:
+      __extension__ __u->__sca4 = __src4;
+      break;
+    case 5:
+      __extension__ __u->__sca5 = __src5;
+      break;
+    case 6:
+      __extension__ __u->__sca6 = __src6;
+      break;
+    case 7:
+      __extension__ __u->__sca7 = __src7;
+      break;
+    case 8:
+      __extension__ __u->__sca8 = __src8;
+      break;
+  }
+  return __dest + __srclen - 1;
+}
+# endif
+compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1);
+
+#endif
diff --git a/REORG.TODO/string/string.h b/REORG.TODO/string/string.h
new file mode 100644
index 0000000000..8eed67d77d
--- /dev/null
+++ b/REORG.TODO/string/string.h
@@ -0,0 +1,544 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/*
+ *	ISO C99 Standard: 7.21 String handling	<string.h>
+ */
+
+#ifndef	_STRING_H
+#define	_STRING_H	1
+
+#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
+#include <bits/libc-header-start.h>
+
+__BEGIN_DECLS
+
+/* Get size_t and NULL from <stddef.h>.  */
+#define	__need_size_t
+#define	__need_NULL
+#include <stddef.h>
+
+/* Tell the caller that we provide correct C++ prototypes.  */
+#if defined __cplusplus && __GNUC_PREREQ (4, 4)
+# define __CORRECT_ISO_CPP_STRING_H_PROTO
+#endif
+
+
+/* Copy N bytes of SRC to DEST.  */
+extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
+		     size_t __n) __THROW __nonnull ((1, 2));
+/* Copy N bytes of SRC to DEST, guaranteeing
+   correct behavior for overlapping strings.  */
+extern void *memmove (void *__dest, const void *__src, size_t __n)
+     __THROW __nonnull ((1, 2));
+
+/* Copy no more than N bytes of SRC to DEST, stopping when C is found.
+   Return the position in DEST one byte past where C was copied,
+   or NULL if C was not found in the first N bytes of SRC.  */
+#if defined __USE_MISC || defined __USE_XOPEN
+extern void *memccpy (void *__restrict __dest, const void *__restrict __src,
+		      int __c, size_t __n)
+     __THROW __nonnull ((1, 2));
+#endif /* Misc || X/Open.  */
+
+
+/* Set N bytes of S to C.  */
+extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1));
+
+/* Compare N bytes of S1 and S2.  */
+extern int memcmp (const void *__s1, const void *__s2, size_t __n)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+
+/* Search N bytes of S for C.  */
+#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++"
+{
+extern void *memchr (void *__s, int __c, size_t __n)
+      __THROW __asm ("memchr") __attribute_pure__ __nonnull ((1));
+extern const void *memchr (const void *__s, int __c, size_t __n)
+      __THROW __asm ("memchr") __attribute_pure__ __nonnull ((1));
+
+# ifdef __OPTIMIZE__
+__extern_always_inline void *
+memchr (void *__s, int __c, size_t __n) __THROW
+{
+  return __builtin_memchr (__s, __c, __n);
+}
+
+__extern_always_inline const void *
+memchr (const void *__s, int __c, size_t __n) __THROW
+{
+  return __builtin_memchr (__s, __c, __n);
+}
+# endif
+}
+#else
+extern void *memchr (const void *__s, int __c, size_t __n)
+      __THROW __attribute_pure__ __nonnull ((1));
+#endif
+
+#ifdef __USE_GNU
+/* Search in S for C.  This is similar to `memchr' but there is no
+   length limit.  */
+# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++" void *rawmemchr (void *__s, int __c)
+     __THROW __asm ("rawmemchr") __attribute_pure__ __nonnull ((1));
+extern "C++" const void *rawmemchr (const void *__s, int __c)
+     __THROW __asm ("rawmemchr") __attribute_pure__ __nonnull ((1));
+# else
+extern void *rawmemchr (const void *__s, int __c)
+     __THROW __attribute_pure__ __nonnull ((1));
+# endif
+
+/* Search N bytes of S for the final occurrence of C.  */
+# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++" void *memrchr (void *__s, int __c, size_t __n)
+      __THROW __asm ("memrchr") __attribute_pure__ __nonnull ((1));
+extern "C++" const void *memrchr (const void *__s, int __c, size_t __n)
+      __THROW __asm ("memrchr") __attribute_pure__ __nonnull ((1));
+# else
+extern void *memrchr (const void *__s, int __c, size_t __n)
+      __THROW __attribute_pure__ __nonnull ((1));
+# endif
+#endif
+
+
+/* Copy SRC to DEST.  */
+extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
+     __THROW __nonnull ((1, 2));
+/* Copy no more than N characters of SRC to DEST.  */
+extern char *strncpy (char *__restrict __dest,
+		      const char *__restrict __src, size_t __n)
+     __THROW __nonnull ((1, 2));
+
+/* Append SRC onto DEST.  */
+extern char *strcat (char *__restrict __dest, const char *__restrict __src)
+     __THROW __nonnull ((1, 2));
+/* Append no more than N characters from SRC onto DEST.  */
+extern char *strncat (char *__restrict __dest, const char *__restrict __src,
+		      size_t __n) __THROW __nonnull ((1, 2));
+
+/* Compare S1 and S2.  */
+extern int strcmp (const char *__s1, const char *__s2)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+/* Compare N characters of S1 and S2.  */
+extern int strncmp (const char *__s1, const char *__s2, size_t __n)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+
+/* Compare the collated forms of S1 and S2.  */
+extern int strcoll (const char *__s1, const char *__s2)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+/* Put a transformation of SRC into no more than N bytes of DEST.  */
+extern size_t strxfrm (char *__restrict __dest,
+		       const char *__restrict __src, size_t __n)
+     __THROW __nonnull ((2));
+
+#ifdef __USE_XOPEN2K8
+# include <xlocale.h>
+
+/* Compare the collated forms of S1 and S2, using sorting rules from L.  */
+extern int strcoll_l (const char *__s1, const char *__s2, __locale_t __l)
+     __THROW __attribute_pure__ __nonnull ((1, 2, 3));
+/* Put a transformation of SRC into no more than N bytes of DEST,
+   using sorting rules from L.  */
+extern size_t strxfrm_l (char *__dest, const char *__src, size_t __n,
+			 __locale_t __l) __THROW __nonnull ((2, 4));
+#endif
+
+#if (defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8	\
+     || __GLIBC_USE (LIB_EXT2))
+/* Duplicate S, returning an identical malloc'd string.  */
+extern char *strdup (const char *__s)
+     __THROW __attribute_malloc__ __nonnull ((1));
+#endif
+
+/* Return a malloc'd copy of at most N bytes of STRING.  The
+   resultant string is terminated even if no null terminator
+   appears before STRING[N].  */
+#if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2)
+extern char *strndup (const char *__string, size_t __n)
+     __THROW __attribute_malloc__ __nonnull ((1));
+#endif
+
+#if defined __USE_GNU && defined __GNUC__
+/* Duplicate S, returning an identical alloca'd string.  */
+# define strdupa(s)							      \
+  (__extension__							      \
+    ({									      \
+      const char *__old = (s);						      \
+      size_t __len = strlen (__old) + 1;				      \
+      char *__new = (char *) __builtin_alloca (__len);			      \
+      (char *) memcpy (__new, __old, __len);				      \
+    }))
+
+/* Return an alloca'd copy of at most N bytes of string.  */
+# define strndupa(s, n)							      \
+  (__extension__							      \
+    ({									      \
+      const char *__old = (s);						      \
+      size_t __len = strnlen (__old, (n));				      \
+      char *__new = (char *) __builtin_alloca (__len + 1);		      \
+      __new[__len] = '\0';						      \
+      (char *) memcpy (__new, __old, __len);				      \
+    }))
+#endif
+
+/* Find the first occurrence of C in S.  */
+#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++"
+{
+extern char *strchr (char *__s, int __c)
+     __THROW __asm ("strchr") __attribute_pure__ __nonnull ((1));
+extern const char *strchr (const char *__s, int __c)
+     __THROW __asm ("strchr") __attribute_pure__ __nonnull ((1));
+
+# ifdef __OPTIMIZE__
+__extern_always_inline char *
+strchr (char *__s, int __c) __THROW
+{
+  return __builtin_strchr (__s, __c);
+}
+
+__extern_always_inline const char *
+strchr (const char *__s, int __c) __THROW
+{
+  return __builtin_strchr (__s, __c);
+}
+# endif
+}
+#else
+extern char *strchr (const char *__s, int __c)
+     __THROW __attribute_pure__ __nonnull ((1));
+#endif
+/* Find the last occurrence of C in S.  */
+#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++"
+{
+extern char *strrchr (char *__s, int __c)
+     __THROW __asm ("strrchr") __attribute_pure__ __nonnull ((1));
+extern const char *strrchr (const char *__s, int __c)
+     __THROW __asm ("strrchr") __attribute_pure__ __nonnull ((1));
+
+# ifdef __OPTIMIZE__
+__extern_always_inline char *
+strrchr (char *__s, int __c) __THROW
+{
+  return __builtin_strrchr (__s, __c);
+}
+
+__extern_always_inline const char *
+strrchr (const char *__s, int __c) __THROW
+{
+  return __builtin_strrchr (__s, __c);
+}
+# endif
+}
+#else
+extern char *strrchr (const char *__s, int __c)
+     __THROW __attribute_pure__ __nonnull ((1));
+#endif
+
+#ifdef __USE_GNU
+/* This function is similar to `strchr'.  But it returns a pointer to
+   the closing NUL byte in case C is not found in S.  */
+# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++" char *strchrnul (char *__s, int __c)
+     __THROW __asm ("strchrnul") __attribute_pure__ __nonnull ((1));
+extern "C++" const char *strchrnul (const char *__s, int __c)
+     __THROW __asm ("strchrnul") __attribute_pure__ __nonnull ((1));
+# else
+extern char *strchrnul (const char *__s, int __c)
+     __THROW __attribute_pure__ __nonnull ((1));
+# endif
+#endif
+
+/* Return the length of the initial segment of S which
+   consists entirely of characters not in REJECT.  */
+extern size_t strcspn (const char *__s, const char *__reject)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+/* Return the length of the initial segment of S which
+   consists entirely of characters in ACCEPT.  */
+extern size_t strspn (const char *__s, const char *__accept)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+/* Find the first occurrence in S of any character in ACCEPT.  */
+#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++"
+{
+extern char *strpbrk (char *__s, const char *__accept)
+     __THROW __asm ("strpbrk") __attribute_pure__ __nonnull ((1, 2));
+extern const char *strpbrk (const char *__s, const char *__accept)
+     __THROW __asm ("strpbrk") __attribute_pure__ __nonnull ((1, 2));
+
+# ifdef __OPTIMIZE__
+__extern_always_inline char *
+strpbrk (char *__s, const char *__accept) __THROW
+{
+  return __builtin_strpbrk (__s, __accept);
+}
+
+__extern_always_inline const char *
+strpbrk (const char *__s, const char *__accept) __THROW
+{
+  return __builtin_strpbrk (__s, __accept);
+}
+# endif
+}
+#else
+extern char *strpbrk (const char *__s, const char *__accept)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+#endif
+/* Find the first occurrence of NEEDLE in HAYSTACK.  */
+#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++"
+{
+extern char *strstr (char *__haystack, const char *__needle)
+     __THROW __asm ("strstr") __attribute_pure__ __nonnull ((1, 2));
+extern const char *strstr (const char *__haystack, const char *__needle)
+     __THROW __asm ("strstr") __attribute_pure__ __nonnull ((1, 2));
+
+# ifdef __OPTIMIZE__
+__extern_always_inline char *
+strstr (char *__haystack, const char *__needle) __THROW
+{
+  return __builtin_strstr (__haystack, __needle);
+}
+
+__extern_always_inline const char *
+strstr (const char *__haystack, const char *__needle) __THROW
+{
+  return __builtin_strstr (__haystack, __needle);
+}
+# endif
+}
+#else
+extern char *strstr (const char *__haystack, const char *__needle)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+#endif
+
+
+/* Divide S into tokens separated by characters in DELIM.  */
+extern char *strtok (char *__restrict __s, const char *__restrict __delim)
+     __THROW __nonnull ((2));
+
+/* Divide S into tokens separated by characters in DELIM.  Information
+   passed between calls are stored in SAVE_PTR.  */
+extern char *__strtok_r (char *__restrict __s,
+			 const char *__restrict __delim,
+			 char **__restrict __save_ptr)
+     __THROW __nonnull ((2, 3));
+#ifdef __USE_POSIX
+extern char *strtok_r (char *__restrict __s, const char *__restrict __delim,
+		       char **__restrict __save_ptr)
+     __THROW __nonnull ((2, 3));
+#endif
+
+#ifdef __USE_GNU
+/* Similar to `strstr' but this function ignores the case of both strings.  */
+# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++" char *strcasestr (char *__haystack, const char *__needle)
+     __THROW __asm ("strcasestr") __attribute_pure__ __nonnull ((1, 2));
+extern "C++" const char *strcasestr (const char *__haystack,
+				     const char *__needle)
+     __THROW __asm ("strcasestr") __attribute_pure__ __nonnull ((1, 2));
+# else
+extern char *strcasestr (const char *__haystack, const char *__needle)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+# endif
+#endif
+
+#ifdef __USE_GNU
+/* Find the first occurrence of NEEDLE in HAYSTACK.
+   NEEDLE is NEEDLELEN bytes long;
+   HAYSTACK is HAYSTACKLEN bytes long.  */
+extern void *memmem (const void *__haystack, size_t __haystacklen,
+		     const void *__needle, size_t __needlelen)
+     __THROW __attribute_pure__ __nonnull ((1, 3));
+
+/* Copy N bytes of SRC to DEST, return pointer to bytes after the
+   last written byte.  */
+extern void *__mempcpy (void *__restrict __dest,
+			const void *__restrict __src, size_t __n)
+     __THROW __nonnull ((1, 2));
+extern void *mempcpy (void *__restrict __dest,
+		      const void *__restrict __src, size_t __n)
+     __THROW __nonnull ((1, 2));
+#endif
+
+
+/* Return the length of S.  */
+extern size_t strlen (const char *__s)
+     __THROW __attribute_pure__ __nonnull ((1));
+
+#ifdef	__USE_XOPEN2K8
+/* Find the length of STRING, but scan at most MAXLEN characters.
+   If no '\0' terminator is found in that many characters, return MAXLEN.  */
+extern size_t strnlen (const char *__string, size_t __maxlen)
+     __THROW __attribute_pure__ __nonnull ((1));
+#endif
+
+
+/* Return a string describing the meaning of the `errno' code in ERRNUM.  */
+extern char *strerror (int __errnum) __THROW;
+#ifdef __USE_XOPEN2K
+/* Reentrant version of `strerror'.
+   There are 2 flavors of `strerror_r', GNU which returns the string
+   and may or may not use the supplied temporary buffer and POSIX one
+   which fills the string into the buffer.
+   To use the POSIX version, -D_XOPEN_SOURCE=600 or -D_POSIX_C_SOURCE=200112L
+   without -D_GNU_SOURCE is needed, otherwise the GNU version is
+   preferred.  */
+# if defined __USE_XOPEN2K && !defined __USE_GNU
+/* Fill BUF with a string describing the meaning of the `errno' code in
+   ERRNUM.  */
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (strerror_r,
+			   (int __errnum, char *__buf, size_t __buflen),
+			   __xpg_strerror_r) __nonnull ((2));
+#  else
+extern int __xpg_strerror_r (int __errnum, char *__buf, size_t __buflen)
+     __THROW __nonnull ((2));
+#   define strerror_r __xpg_strerror_r
+#  endif
+# else
+/* If a temporary buffer is required, at most BUFLEN bytes of BUF will be
+   used.  */
+extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
+     __THROW __nonnull ((2)) __wur;
+# endif
+#endif
+
+#ifdef __USE_XOPEN2K8
+/* Translate error number to string according to the locale L.  */
+extern char *strerror_l (int __errnum, __locale_t __l) __THROW;
+#endif
+
+#ifdef __USE_MISC
+# include <strings.h>
+
+/* Set N bytes of S to 0.  The compiler will not delete a call to this
+   function, even if S is dead after the call.  */
+extern void explicit_bzero (void *__s, size_t __n) __THROW __nonnull ((1));
+
+/* Return the next DELIM-delimited token from *STRINGP,
+   terminating it with a '\0', and update *STRINGP to point past it.  */
+extern char *strsep (char **__restrict __stringp,
+		     const char *__restrict __delim)
+     __THROW __nonnull ((1, 2));
+#endif
+
+#ifdef	__USE_XOPEN2K8
+/* Return a string describing the meaning of the signal number in SIG.  */
+extern char *strsignal (int __sig) __THROW;
+
+/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */
+extern char *__stpcpy (char *__restrict __dest, const char *__restrict __src)
+     __THROW __nonnull ((1, 2));
+extern char *stpcpy (char *__restrict __dest, const char *__restrict __src)
+     __THROW __nonnull ((1, 2));
+
+/* Copy no more than N characters of SRC to DEST, returning the address of
+   the last character written into DEST.  */
+extern char *__stpncpy (char *__restrict __dest,
+			const char *__restrict __src, size_t __n)
+     __THROW __nonnull ((1, 2));
+extern char *stpncpy (char *__restrict __dest,
+		      const char *__restrict __src, size_t __n)
+     __THROW __nonnull ((1, 2));
+#endif
+
+#ifdef	__USE_GNU
+/* Compare S1 and S2 as strings holding name & indices/version numbers.  */
+extern int strverscmp (const char *__s1, const char *__s2)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+
+/* Sautee STRING briskly.  */
+extern char *strfry (char *__string) __THROW __nonnull ((1));
+
+/* Frobnicate N bytes of S.  */
+extern void *memfrob (void *__s, size_t __n) __THROW __nonnull ((1));
+
+# ifndef basename
+/* Return the file name within directory of FILENAME.  We don't
+   declare the function if the `basename' macro is available (defined
+   in <libgen.h>) which makes the XPG version of this function
+   available.  */
+#  ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
+extern "C++" char *basename (char *__filename)
+     __THROW __asm ("basename") __nonnull ((1));
+extern "C++" const char *basename (const char *__filename)
+     __THROW __asm ("basename") __nonnull ((1));
+#  else
+extern char *basename (const char *__filename) __THROW __nonnull ((1));
+#  endif
+# endif
+#endif
+
+
+#if __GNUC_PREREQ (3,4)
+# if defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ \
+     && !defined __NO_INLINE__ && !defined __cplusplus
+/* When using GNU CC we provide some optimized versions of selected
+   functions from this header.  There are two kinds of optimizations:
+
+   - machine-dependent optimizations, most probably using inline
+     assembler code; these might be quite expensive since the code
+     size can increase significantly.
+     These optimizations are not used unless the symbol
+	__USE_STRING_INLINES
+     is defined before including this header.
+
+   - machine-independent optimizations which do not increase the
+     code size significantly and which optimize mainly situations
+     where one or more arguments are compile-time constants.
+     These optimizations are used always when the compiler is
+     taught to optimize.
+
+   One can inhibit all optimizations by defining __NO_STRING_INLINES.  */
+
+/* Get the machine-dependent optimizations (if any).  */
+#  include <bits/string.h>
+
+/* These are generic optimizations which do not add too much inline code.  */
+#  include <bits/string2.h>
+# endif
+
+# if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
+/* Functions with security checks.  */
+#  include <bits/string3.h>
+# endif
+#endif
+
+#if defined __USE_GNU && defined __OPTIMIZE__ \
+    && defined __extern_always_inline && __GNUC_PREREQ (3,2)
+# if !defined _FORCE_INLINES && !defined _HAVE_STRING_ARCH_mempcpy
+
+#define mempcpy(dest, src, n) __mempcpy_inline (dest, src, n)
+#define __mempcpy(dest, src, n) __mempcpy_inline (dest, src, n)
+
+__extern_always_inline void *
+__mempcpy_inline (void *__restrict __dest,
+		  const void *__restrict __src, size_t __n)
+{
+  return (char *) memcpy (__dest, __src, __n) + __n;
+}
+
+# endif
+#endif
+
+__END_DECLS
+
+#endif /* string.h  */
diff --git a/REORG.TODO/string/strings.h b/REORG.TODO/string/strings.h
new file mode 100644
index 0000000000..43207af09c
--- /dev/null
+++ b/REORG.TODO/string/strings.h
@@ -0,0 +1,147 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_STRINGS_H
+#define	_STRINGS_H	1
+
+#include <features.h>
+#define __need_size_t
+#include <stddef.h>
+
+/* Tell the caller that we provide correct C++ prototypes.  */
+#if defined __cplusplus && __GNUC_PREREQ (4, 4)
+# define __CORRECT_ISO_CPP_STRINGS_H_PROTO
+#endif
+
+__BEGIN_DECLS
+
+#if defined __USE_MISC || !defined __USE_XOPEN2K8
+/* Compare N bytes of S1 and S2 (same as memcmp).  */
+extern int bcmp (const void *__s1, const void *__s2, size_t __n)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+
+/* Copy N bytes of SRC to DEST (like memmove, but args reversed).  */
+extern void bcopy (const void *__src, void *__dest, size_t __n)
+  __THROW __nonnull ((1, 2));
+
+/* Set N bytes of S to 0.  */
+extern void bzero (void *__s, size_t __n) __THROW __nonnull ((1));
+
+/* Find the first occurrence of C in S (same as strchr).  */
+# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
+extern "C++"
+{
+extern char *index (char *__s, int __c)
+     __THROW __asm ("index") __attribute_pure__ __nonnull ((1));
+extern const char *index (const char *__s, int __c)
+     __THROW __asm ("index") __attribute_pure__ __nonnull ((1));
+
+#  if defined __OPTIMIZE__
+__extern_always_inline char *
+index (char *__s, int __c) __THROW
+{
+  return __builtin_index (__s, __c);
+}
+
+__extern_always_inline const char *
+index (const char *__s, int __c) __THROW
+{
+  return __builtin_index (__s, __c);
+}
+#  endif
+}
+# else
+extern char *index (const char *__s, int __c)
+     __THROW __attribute_pure__ __nonnull ((1));
+# endif
+
+/* Find the last occurrence of C in S (same as strrchr).  */
+# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
+extern "C++"
+{
+extern char *rindex (char *__s, int __c)
+     __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
+extern const char *rindex (const char *__s, int __c)
+     __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
+
+#  if defined __OPTIMIZE__
+__extern_always_inline char *
+rindex (char *__s, int __c) __THROW
+{
+  return __builtin_rindex (__s, __c);
+}
+
+__extern_always_inline const char *
+rindex (const char *__s, int __c) __THROW
+{
+  return __builtin_rindex (__s, __c);
+}
+#  endif
+}
+# else
+extern char *rindex (const char *__s, int __c)
+     __THROW __attribute_pure__ __nonnull ((1));
+# endif
+#endif
+
+#if defined __USE_MISC || !defined __USE_XOPEN2K8 || defined __USE_XOPEN2K8XSI
+/* Return the position of the first bit set in I, or 0 if none are set.
+   The least-significant bit is position 1, the most-significant 32.  */
+extern int ffs (int __i) __THROW __attribute_const__;
+#endif
+
+/* The following two functions are non-standard but necessary for non-32 bit
+   platforms.  */
+# ifdef	__USE_GNU
+extern int ffsl (long int __l) __THROW __attribute_const__;
+__extension__ extern int ffsll (long long int __ll)
+     __THROW __attribute_const__;
+# endif
+
+/* Compare S1 and S2, ignoring case.  */
+extern int strcasecmp (const char *__s1, const char *__s2)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+
+/* Compare no more than N chars of S1 and S2, ignoring case.  */
+extern int strncasecmp (const char *__s1, const char *__s2, size_t __n)
+     __THROW __attribute_pure__ __nonnull ((1, 2));
+
+#ifdef	__USE_XOPEN2K8
+# include <xlocale.h>
+
+/* Compare S1 and S2, ignoring case, using collation rules from LOC.  */
+extern int strcasecmp_l (const char *__s1, const char *__s2, __locale_t __loc)
+     __THROW __attribute_pure__ __nonnull ((1, 2, 3));
+
+/* Compare no more than N chars of S1 and S2, ignoring case, using
+   collation rules from LOC.  */
+extern int strncasecmp_l (const char *__s1, const char *__s2,
+			  size_t __n, __locale_t __loc)
+     __THROW __attribute_pure__ __nonnull ((1, 2, 4));
+#endif
+
+__END_DECLS
+
+#if __GNUC_PREREQ (3,4) && __USE_FORTIFY_LEVEL > 0 \
+    && defined __fortify_function
+/* Functions with security checks.  */
+# if defined __USE_MISC || !defined __USE_XOPEN2K8
+#  include <bits/strings_fortified.h>
+# endif
+#endif
+
+#endif	/* strings.h  */
diff --git a/REORG.TODO/string/strlen.c b/REORG.TODO/string/strlen.c
new file mode 100644
index 0000000000..b368ccf58f
--- /dev/null
+++ b/REORG.TODO/string/strlen.c
@@ -0,0 +1,109 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Torbjorn Granlund (tege@sics.se),
+   with help from Dan Sahlin (dan@sics.se);
+   commentary by Jim Blandy (jimb@ai.mit.edu).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <stdlib.h>
+
+#undef strlen
+
+#ifndef STRLEN
+# define STRLEN strlen
+#endif
+
+/* Return the length of the null-terminated string STR.  Scan for
+   the null terminator quickly by testing four bytes at a time.  */
+size_t
+STRLEN (const char *str)
+{
+  const char *char_ptr;
+  const unsigned long int *longword_ptr;
+  unsigned long int longword, himagic, lomagic;
+
+  /* Handle the first few characters by reading one character at a time.
+     Do this until CHAR_PTR is aligned on a longword boundary.  */
+  for (char_ptr = str; ((unsigned long int) char_ptr
+			& (sizeof (longword) - 1)) != 0;
+       ++char_ptr)
+    if (*char_ptr == '\0')
+      return char_ptr - str;
+
+  /* All these elucidatory comments refer to 4-byte longwords,
+     but the theory applies equally well to 8-byte longwords.  */
+
+  longword_ptr = (unsigned long int *) char_ptr;
+
+  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
+     the "holes."  Note that there is a hole just to the left of
+     each byte, with an extra at the end:
+
+     bits:  01111110 11111110 11111110 11111111
+     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
+
+     The 1-bits make sure that carries propagate to the next 0-bit.
+     The 0-bits provide holes for carries to fall into.  */
+  himagic = 0x80808080L;
+  lomagic = 0x01010101L;
+  if (sizeof (longword) > 4)
+    {
+      /* 64-bit version of the magic.  */
+      /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
+      himagic = ((himagic << 16) << 16) | himagic;
+      lomagic = ((lomagic << 16) << 16) | lomagic;
+    }
+  if (sizeof (longword) > 8)
+    abort ();
+
+  /* Instead of the traditional loop which tests each character,
+     we will test a longword at a time.  The tricky part is testing
+     if *any of the four* bytes in the longword in question are zero.  */
+  for (;;)
+    {
+      longword = *longword_ptr++;
+
+      if (((longword - lomagic) & ~longword & himagic) != 0)
+	{
+	  /* Which of the bytes was the zero?  If none of them were, it was
+	     a misfire; continue the search.  */
+
+	  const char *cp = (const char *) (longword_ptr - 1);
+
+	  if (cp[0] == 0)
+	    return cp - str;
+	  if (cp[1] == 0)
+	    return cp - str + 1;
+	  if (cp[2] == 0)
+	    return cp - str + 2;
+	  if (cp[3] == 0)
+	    return cp - str + 3;
+	  if (sizeof (longword) > 4)
+	    {
+	      if (cp[4] == 0)
+		return cp - str + 4;
+	      if (cp[5] == 0)
+		return cp - str + 5;
+	      if (cp[6] == 0)
+		return cp - str + 6;
+	      if (cp[7] == 0)
+		return cp - str + 7;
+	    }
+	}
+    }
+}
+libc_hidden_builtin_def (strlen)
diff --git a/REORG.TODO/string/strncase.c b/REORG.TODO/string/strncase.c
new file mode 100644
index 0000000000..6cb996cf91
--- /dev/null
+++ b/REORG.TODO/string/strncase.c
@@ -0,0 +1,69 @@
+/* Compare at most N characters of two strings without taking care for
+   the case.
+   Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <ctype.h>
+
+#ifndef weak_alias
+# define __strncasecmp strncasecmp
+# define TOLOWER(Ch) tolower (Ch)
+#else
+# include <locale/localeinfo.h>
+# ifdef USE_IN_EXTENDED_LOCALE_MODEL
+#  define __strncasecmp __strncasecmp_l
+# endif
+# define TOLOWER(Ch) __tolower_l ((Ch), loc)
+#endif
+
+#ifdef USE_IN_EXTENDED_LOCALE_MODEL
+# define LOCALE_PARAM , __locale_t loc
+#else
+# define LOCALE_PARAM
+#endif
+
+/* Compare no more than N characters of S1 and S2,
+   ignoring case, returning less than, equal to or
+   greater than zero if S1 is lexicographically less
+   than, equal to or greater than S2.  */
+int
+__strncasecmp (const char *s1, const char *s2, size_t n LOCALE_PARAM)
+{
+#if defined _LIBC && !defined USE_IN_EXTENDED_LOCALE_MODEL
+  __locale_t loc = _NL_CURRENT_LOCALE;
+#endif
+  const unsigned char *p1 = (const unsigned char *) s1;
+  const unsigned char *p2 = (const unsigned char *) s2;
+  int result;
+
+  if (p1 == p2 || n == 0)
+    return 0;
+
+  while ((result = TOLOWER (*p1) - TOLOWER (*p2++)) == 0)
+    if (*p1++ == '\0' || --n == 0)
+      break;
+
+  return result;
+}
+#ifndef __strncasecmp
+weak_alias (__strncasecmp, strncasecmp)
+#endif
diff --git a/REORG.TODO/string/strncase_l.c b/REORG.TODO/string/strncase_l.c
new file mode 100644
index 0000000000..395fc9fd08
--- /dev/null
+++ b/REORG.TODO/string/strncase_l.c
@@ -0,0 +1,24 @@
+/* Compare at most N characters of two strings without taking care for
+   the case using given locale.
+   Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define USE_IN_EXTENDED_LOCALE_MODEL	1
+#include "strncase.c"
+
+libc_hidden_def (__strncasecmp_l)
+weak_alias (__strncasecmp_l, strncasecmp_l)
diff --git a/REORG.TODO/string/strncat.c b/REORG.TODO/string/strncat.c
new file mode 100644
index 0000000000..71a13eec0b
--- /dev/null
+++ b/REORG.TODO/string/strncat.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#ifndef STRNCAT
+# undef strncat
+# define STRNCAT  strncat
+#endif
+
+char *
+STRNCAT (char *s1, const char *s2, size_t n)
+{
+  char *s = s1;
+
+  /* Find the end of S1.  */
+  s1 += strlen (s1);
+
+  size_t ss = __strnlen (s2, n);
+
+  s1[ss] = '\0';
+  memcpy (s1, s2, ss);
+
+  return s;
+}
diff --git a/REORG.TODO/string/strncmp.c b/REORG.TODO/string/strncmp.c
new file mode 100644
index 0000000000..c41e120091
--- /dev/null
+++ b/REORG.TODO/string/strncmp.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <memcopy.h>
+
+#undef strncmp
+
+#ifndef STRNCMP
+#define STRNCMP strncmp
+#endif
+
+/* Compare no more than N characters of S1 and S2,
+   returning less than, equal to or greater than zero
+   if S1 is lexicographically less than, equal to or
+   greater than S2.  */
+int
+STRNCMP (const char *s1, const char *s2, size_t n)
+{
+  unsigned char c1 = '\0';
+  unsigned char c2 = '\0';
+
+  if (n >= 4)
+    {
+      size_t n4 = n >> 2;
+      do
+	{
+	  c1 = (unsigned char) *s1++;
+	  c2 = (unsigned char) *s2++;
+	  if (c1 == '\0' || c1 != c2)
+	    return c1 - c2;
+	  c1 = (unsigned char) *s1++;
+	  c2 = (unsigned char) *s2++;
+	  if (c1 == '\0' || c1 != c2)
+	    return c1 - c2;
+	  c1 = (unsigned char) *s1++;
+	  c2 = (unsigned char) *s2++;
+	  if (c1 == '\0' || c1 != c2)
+	    return c1 - c2;
+	  c1 = (unsigned char) *s1++;
+	  c2 = (unsigned char) *s2++;
+	  if (c1 == '\0' || c1 != c2)
+	    return c1 - c2;
+	} while (--n4 > 0);
+      n &= 3;
+    }
+
+  while (n > 0)
+    {
+      c1 = (unsigned char) *s1++;
+      c2 = (unsigned char) *s2++;
+      if (c1 == '\0' || c1 != c2)
+	return c1 - c2;
+      n--;
+    }
+
+  return c1 - c2;
+}
+
+libc_hidden_builtin_def (STRNCMP)
diff --git a/REORG.TODO/string/strncpy.c b/REORG.TODO/string/strncpy.c
new file mode 100644
index 0000000000..1b45c52e73
--- /dev/null
+++ b/REORG.TODO/string/strncpy.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#undef strncpy
+
+#ifndef STRNCPY
+ #define STRNCPY strncpy
+#endif
+
+char *
+STRNCPY (char *s1, const char *s2, size_t n)
+{
+  size_t size = __strnlen (s2, n);
+  if (size != n)
+    memset (s1 + size, '\0', n - size);
+  return memcpy (s1, s2, size);
+}
+libc_hidden_builtin_def (strncpy)
diff --git a/REORG.TODO/string/strndup.c b/REORG.TODO/string/strndup.c
new file mode 100644
index 0000000000..fa0e7dcda1
--- /dev/null
+++ b/REORG.TODO/string/strndup.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#if defined _LIBC || defined STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+char *malloc ();
+#endif
+
+#undef __strndup
+#undef strndup
+
+#ifndef weak_alias
+# define __strndup strndup
+#endif
+
+char *
+__strndup (const char *s, size_t n)
+{
+  size_t len = __strnlen (s, n);
+  char *new = (char *) malloc (len + 1);
+
+  if (new == NULL)
+    return NULL;
+
+  new[len] = '\0';
+  return (char *) memcpy (new, s, len);
+}
+#ifdef libc_hidden_def
+libc_hidden_def (__strndup)
+#endif
+#ifdef weak_alias
+weak_alias (__strndup, strndup)
+#endif
diff --git a/REORG.TODO/string/strnlen.c b/REORG.TODO/string/strnlen.c
new file mode 100644
index 0000000000..ff9fb6197a
--- /dev/null
+++ b/REORG.TODO/string/strnlen.c
@@ -0,0 +1,166 @@
+/* Find the length of STRING, but scan at most MAXLEN characters.
+   Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+   Based on strlen written by Torbjorn Granlund (tege@sics.se),
+   with help from Dan Sahlin (dan@sics.se);
+   commentary by Jim Blandy (jimb@ai.mit.edu).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <stdlib.h>
+
+/* Find the length of S, but scan at most MAXLEN characters.  If no
+   '\0' terminator is found in that many characters, return MAXLEN.  */
+
+#ifdef STRNLEN
+# define __strnlen STRNLEN
+#endif
+
+size_t
+__strnlen (const char *str, size_t maxlen)
+{
+  const char *char_ptr, *end_ptr = str + maxlen;
+  const unsigned long int *longword_ptr;
+  unsigned long int longword, himagic, lomagic;
+
+  if (maxlen == 0)
+    return 0;
+
+  if (__glibc_unlikely (end_ptr < str))
+    end_ptr = (const char *) ~0UL;
+
+  /* Handle the first few characters by reading one character at a time.
+     Do this until CHAR_PTR is aligned on a longword boundary.  */
+  for (char_ptr = str; ((unsigned long int) char_ptr
+			& (sizeof (longword) - 1)) != 0;
+       ++char_ptr)
+    if (*char_ptr == '\0')
+      {
+	if (char_ptr > end_ptr)
+	  char_ptr = end_ptr;
+	return char_ptr - str;
+      }
+
+  /* All these elucidatory comments refer to 4-byte longwords,
+     but the theory applies equally well to 8-byte longwords.  */
+
+  longword_ptr = (unsigned long int *) char_ptr;
+
+  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
+     the "holes."  Note that there is a hole just to the left of
+     each byte, with an extra at the end:
+
+     bits:  01111110 11111110 11111110 11111111
+     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
+
+     The 1-bits make sure that carries propagate to the next 0-bit.
+     The 0-bits provide holes for carries to fall into.  */
+  himagic = 0x80808080L;
+  lomagic = 0x01010101L;
+  if (sizeof (longword) > 4)
+    {
+      /* 64-bit version of the magic.  */
+      /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
+      himagic = ((himagic << 16) << 16) | himagic;
+      lomagic = ((lomagic << 16) << 16) | lomagic;
+    }
+  if (sizeof (longword) > 8)
+    abort ();
+
+  /* Instead of the traditional loop which tests each character,
+     we will test a longword at a time.  The tricky part is testing
+     if *any of the four* bytes in the longword in question are zero.  */
+  while (longword_ptr < (unsigned long int *) end_ptr)
+    {
+      /* We tentatively exit the loop if adding MAGIC_BITS to
+	 LONGWORD fails to change any of the hole bits of LONGWORD.
+
+	 1) Is this safe?  Will it catch all the zero bytes?
+	 Suppose there is a byte with all zeros.  Any carry bits
+	 propagating from its left will fall into the hole at its
+	 least significant bit and stop.  Since there will be no
+	 carry from its most significant bit, the LSB of the
+	 byte to the left will be unchanged, and the zero will be
+	 detected.
+
+	 2) Is this worthwhile?  Will it ignore everything except
+	 zero bytes?  Suppose every byte of LONGWORD has a bit set
+	 somewhere.  There will be a carry into bit 8.  If bit 8
+	 is set, this will carry into bit 16.  If bit 8 is clear,
+	 one of bits 9-15 must be set, so there will be a carry
+	 into bit 16.  Similarly, there will be a carry into bit
+	 24.  If one of bits 24-30 is set, there will be a carry
+	 into bit 31, so all of the hole bits will be changed.
+
+	 The one misfire occurs when bits 24-30 are clear and bit
+	 31 is set; in this case, the hole at bit 31 is not
+	 changed.  If we had access to the processor carry flag,
+	 we could close this loophole by putting the fourth hole
+	 at bit 32!
+
+	 So it ignores everything except 128's, when they're aligned
+	 properly.  */
+
+      longword = *longword_ptr++;
+
+      if ((longword - lomagic) & himagic)
+	{
+	  /* Which of the bytes was the zero?  If none of them were, it was
+	     a misfire; continue the search.  */
+
+	  const char *cp = (const char *) (longword_ptr - 1);
+
+	  char_ptr = cp;
+	  if (cp[0] == 0)
+	    break;
+	  char_ptr = cp + 1;
+	  if (cp[1] == 0)
+	    break;
+	  char_ptr = cp + 2;
+	  if (cp[2] == 0)
+	    break;
+	  char_ptr = cp + 3;
+	  if (cp[3] == 0)
+	    break;
+	  if (sizeof (longword) > 4)
+	    {
+	      char_ptr = cp + 4;
+	      if (cp[4] == 0)
+		break;
+	      char_ptr = cp + 5;
+	      if (cp[5] == 0)
+		break;
+	      char_ptr = cp + 6;
+	      if (cp[6] == 0)
+		break;
+	      char_ptr = cp + 7;
+	      if (cp[7] == 0)
+		break;
+	    }
+	}
+      char_ptr = end_ptr;
+    }
+
+  if (char_ptr > end_ptr)
+    char_ptr = end_ptr;
+  return char_ptr - str;
+}
+#ifndef STRNLEN
+libc_hidden_def (__strnlen)
+weak_alias (__strnlen, strnlen)
+#endif
+libc_hidden_def (strnlen)
diff --git a/REORG.TODO/string/strpbrk.c b/REORG.TODO/string/strpbrk.c
new file mode 100644
index 0000000000..02d0bd2f63
--- /dev/null
+++ b/REORG.TODO/string/strpbrk.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#undef strpbrk
+
+#ifndef STRPBRK
+#define STRPBRK strpbrk
+#endif
+
+/* Find the first occurrence in S of any character in ACCEPT.  */
+char *
+STRPBRK (const char *s, const char *accept)
+{
+  s += strcspn (s, accept);
+  return *s ? (char *)s : NULL;
+}
+libc_hidden_builtin_def (strpbrk)
diff --git a/REORG.TODO/string/strrchr.c b/REORG.TODO/string/strrchr.c
new file mode 100644
index 0000000000..92638a8fbd
--- /dev/null
+++ b/REORG.TODO/string/strrchr.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#undef strrchr
+
+#ifndef STRRCHR
+# define STRRCHR strrchr
+#endif
+
+/* Find the last occurrence of C in S.  */
+char *
+STRRCHR (const char *s, int c)
+{
+  const char *found, *p;
+
+  c = (unsigned char) c;
+
+  /* Since strchr is fast, we use it rather than the obvious loop.  */
+
+  if (c == '\0')
+    return strchr (s, '\0');
+
+  found = NULL;
+  while ((p = strchr (s, c)) != NULL)
+    {
+      found = p;
+      s = p + 1;
+    }
+
+  return (char *) found;
+}
+
+#ifdef weak_alias
+#undef rindex
+weak_alias (strrchr, rindex)
+#endif
+libc_hidden_builtin_def (strrchr)
diff --git a/REORG.TODO/string/strsep.c b/REORG.TODO/string/strsep.c
new file mode 100644
index 0000000000..7091234a6c
--- /dev/null
+++ b/REORG.TODO/string/strsep.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+#undef __strsep
+#undef strsep
+
+char *
+__strsep (char **stringp, const char *delim)
+{
+  char *begin, *end;
+
+  begin = *stringp;
+  if (begin == NULL)
+    return NULL;
+
+  /* Find the end of the token.  */
+  end = begin + strcspn (begin, delim);
+
+  if (*end)
+    {
+      /* Terminate the token and set *STRINGP past NUL character.  */
+      *end++ = '\0';
+      *stringp = end;
+    }
+  else
+    /* No more delimiters; this is the last token.  */
+    *stringp = NULL;
+
+  return begin;
+}
+weak_alias (__strsep, strsep)
+strong_alias (__strsep, __strsep_g)
+libc_hidden_def (__strsep_g)
diff --git a/REORG.TODO/string/strsignal.c b/REORG.TODO/string/strsignal.c
new file mode 100644
index 0000000000..6cb4399934
--- /dev/null
+++ b/REORG.TODO/string/strsignal.c
@@ -0,0 +1,125 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libintl.h>
+#include <libc-lock.h>
+
+static __libc_key_t key;
+
+/* If nonzero the key allocation failed and we should better use a
+   static buffer than fail.  */
+#define BUFFERSIZ	100
+static char local_buf[BUFFERSIZ];
+static char *static_buf;
+
+/* Destructor for the thread-specific data.  */
+static void init (void);
+static void free_key_mem (void *mem);
+static char *getbuffer (void);
+
+
+/* Return a string describing the meaning of the signal number SIGNUM.  */
+char *
+strsignal (int signum)
+{
+  __libc_once_define (static, once);
+  const char *desc;
+
+  /* If we have not yet initialized the buffer do it now.  */
+  __libc_once (once, init);
+
+  if (
+#ifdef SIGRTMIN
+      (signum >= SIGRTMIN && signum <= SIGRTMAX) ||
+#endif
+      signum < 0 || signum >= NSIG
+      || (desc = _sys_siglist[signum]) == NULL)
+    {
+      char *buffer = getbuffer ();
+      int len;
+#ifdef SIGRTMIN
+      if (signum >= SIGRTMIN && signum <= SIGRTMAX)
+	len = __snprintf (buffer, BUFFERSIZ - 1, _("Real-time signal %d"),
+			  signum - SIGRTMIN);
+      else
+#endif
+	len = __snprintf (buffer, BUFFERSIZ - 1, _("Unknown signal %d"),
+			  signum);
+      if (len >= BUFFERSIZ)
+	buffer = NULL;
+      else
+	buffer[len] = '\0';
+
+      return buffer;
+    }
+
+  return (char *) _(desc);
+}
+
+
+/* Initialize buffer.  */
+static void
+init (void)
+{
+  if (__libc_key_create (&key, free_key_mem))
+    /* Creating the key failed.  This means something really went
+       wrong.  In any case use a static buffer which is better than
+       nothing.  */
+    static_buf = local_buf;
+}
+
+
+/* Free the thread specific data, this is done if a thread terminates.  */
+static void
+free_key_mem (void *mem)
+{
+  free (mem);
+  __libc_setspecific (key, NULL);
+}
+
+
+/* Return the buffer to be used.  */
+static char *
+getbuffer (void)
+{
+  char *result;
+
+  if (static_buf != NULL)
+    result = static_buf;
+  else
+    {
+      /* We don't use the static buffer and so we have a key.  Use it
+	 to get the thread-specific buffer.  */
+      result = __libc_getspecific (key);
+      if (result == NULL)
+	{
+	  /* No buffer allocated so far.  */
+	  result = malloc (BUFFERSIZ);
+	  if (result == NULL)
+	    /* No more memory available.  We use the static buffer.  */
+	    result = local_buf;
+	  else
+	    __libc_setspecific (key, result);
+	}
+    }
+
+  return result;
+}
diff --git a/REORG.TODO/string/strspn.c b/REORG.TODO/string/strspn.c
new file mode 100644
index 0000000000..c63197cdf0
--- /dev/null
+++ b/REORG.TODO/string/strspn.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include <libc-pointer-arith.h>
+
+#undef strspn
+#ifndef STRSPN
+# define STRSPN strspn
+#endif
+
+/* Return the length of the maximum initial segment
+   of S which contains only characters in ACCEPT.  */
+size_t
+STRSPN (const char *str, const char *accept)
+{
+  if (accept[0] == '\0')
+    return 0;
+  if (__glibc_unlikely (accept[1] == '\0'))
+    {
+      const char *a = str;
+      for (; *str == *accept; str++);
+      return str - a;
+    }
+
+  /* Use multiple small memsets to enable inlining on most targets.  */
+  unsigned char table[256];
+  unsigned char *p = memset (table, 0, 64);
+  memset (p + 64, 0, 64);
+  memset (p + 128, 0, 64);
+  memset (p + 192, 0, 64);
+
+  unsigned char *s = (unsigned char*) accept;
+  /* Different from strcspn it does not add the NULL on the table
+     so can avoid check if str[i] is NULL, since table['\0'] will
+     be 0 and thus stopping the loop check.  */
+  do
+    p[*s++] = 1;
+  while (*s);
+
+  s = (unsigned char*) str;
+  if (!p[s[0]]) return 0;
+  if (!p[s[1]]) return 1;
+  if (!p[s[2]]) return 2;
+  if (!p[s[3]]) return 3;
+
+  s = (unsigned char *) PTR_ALIGN_DOWN (s, 4);
+
+  unsigned int c0, c1, c2, c3;
+  do {
+      s += 4;
+      c0 = p[s[0]];
+      c1 = p[s[1]];
+      c2 = p[s[2]];
+      c3 = p[s[3]];
+  } while ((c0 & c1 & c2 & c3) != 0);
+
+  size_t count = s - (unsigned char *) str;
+  return (c0 & c1) == 0 ? count + c0 : count + c2 + 2;
+}
+libc_hidden_builtin_def (strspn)
diff --git a/REORG.TODO/string/strstr.c b/REORG.TODO/string/strstr.c
new file mode 100644
index 0000000000..88f1d5de36
--- /dev/null
+++ b/REORG.TODO/string/strstr.c
@@ -0,0 +1,92 @@
+/* Return the offset of one string within another.
+   Copyright (C) 1994-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This particular implementation was written by Eric Blake, 2008.  */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+/* Specification of strstr.  */
+#include <string.h>
+
+#include <stdbool.h>
+
+#ifndef _LIBC
+# define __builtin_expect(expr, val)   (expr)
+#endif
+
+#define RETURN_TYPE char *
+#define AVAILABLE(h, h_l, j, n_l)			\
+  (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))	\
+   && ((h_l) = (j) + (n_l)))
+#define CHECK_EOL (1)
+#define RET0_IF_0(a) if (!a) goto ret0
+#include "str-two-way.h"
+
+#undef strstr
+
+#ifndef STRSTR
+#define STRSTR strstr
+#endif
+
+/* Return the first occurrence of NEEDLE in HAYSTACK.  Return HAYSTACK
+   if NEEDLE is empty, otherwise NULL if NEEDLE is not found in
+   HAYSTACK.  */
+char *
+STRSTR (const char *haystack_start, const char *needle_start)
+{
+  const char *haystack = haystack_start;
+  const char *needle = needle_start;
+  size_t needle_len; /* Length of NEEDLE.  */
+  size_t haystack_len; /* Known minimum length of HAYSTACK.  */
+  bool ok = true; /* True if NEEDLE is prefix of HAYSTACK.  */
+
+  /* Determine length of NEEDLE, and in the process, make sure
+     HAYSTACK is at least as long (no point processing all of a long
+     NEEDLE if HAYSTACK is too short).  */
+  while (*haystack && *needle)
+    ok &= *haystack++ == *needle++;
+  if (*needle)
+    return NULL;
+  if (ok)
+    return (char *) haystack_start;
+
+  /* Reduce the size of haystack using strchr, since it has a smaller
+     linear coefficient than the Two-Way algorithm.  */
+  needle_len = needle - needle_start;
+  haystack = strchr (haystack_start + 1, *needle_start);
+  if (!haystack || __builtin_expect (needle_len == 1, 0))
+    return (char *) haystack;
+  needle -= needle_len;
+  haystack_len = (haystack > haystack_start + needle_len ? 1
+		  : needle_len + haystack_start - haystack);
+
+  /* Perform the search.  Abstract memory is considered to be an array
+     of 'unsigned char' values, not an array of 'char' values.  See
+     ISO C 99 section 6.2.6.1.  */
+  if (needle_len < LONG_NEEDLE_THRESHOLD)
+    return two_way_short_needle ((const unsigned char *) haystack,
+				 haystack_len,
+				 (const unsigned char *) needle, needle_len);
+  return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
+			      (const unsigned char *) needle, needle_len);
+}
+libc_hidden_builtin_def (strstr)
+
+#undef LONG_NEEDLE_THRESHOLD
diff --git a/REORG.TODO/string/strtok.c b/REORG.TODO/string/strtok.c
new file mode 100644
index 0000000000..6b9de89747
--- /dev/null
+++ b/REORG.TODO/string/strtok.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+
+/* Parse S into tokens separated by characters in DELIM.
+   If S is NULL, the last string strtok() was called with is
+   used.  For example:
+	char s[] = "-abc-=-def";
+	x = strtok(s, "-");		// x = "abc"
+	x = strtok(NULL, "-=");		// x = "def"
+	x = strtok(NULL, "=");		// x = NULL
+		// s = "abc\0=-def\0"
+*/
+char *
+strtok (char *s, const char *delim)
+{
+  static char *olds;
+  return __strtok_r (s, delim, &olds);
+}
diff --git a/REORG.TODO/string/strtok_r.c b/REORG.TODO/string/strtok_r.c
new file mode 100644
index 0000000000..ace3520a25
--- /dev/null
+++ b/REORG.TODO/string/strtok_r.c
@@ -0,0 +1,79 @@
+/* Reentrant string tokenizer.  Generic version.
+   Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#ifndef _LIBC
+/* Get specification.  */
+# include "strtok_r.h"
+# define __strtok_r strtok_r
+#endif
+
+/* Parse S into tokens separated by characters in DELIM.
+   If S is NULL, the saved pointer in SAVE_PTR is used as
+   the next starting point.  For example:
+	char s[] = "-abc-=-def";
+	char *sp;
+	x = strtok_r(s, "-", &sp);	// x = "abc", sp = "=-def"
+	x = strtok_r(NULL, "-=", &sp);	// x = "def", sp = NULL
+	x = strtok_r(NULL, "=", &sp);	// x = NULL
+		// s = "abc\0-def\0"
+*/
+char *
+__strtok_r (char *s, const char *delim, char **save_ptr)
+{
+  char *end;
+
+  if (s == NULL)
+    s = *save_ptr;
+
+  if (*s == '\0')
+    {
+      *save_ptr = s;
+      return NULL;
+    }
+
+  /* Scan leading delimiters.  */
+  s += strspn (s, delim);
+  if (*s == '\0')
+    {
+      *save_ptr = s;
+      return NULL;
+    }
+
+  /* Find the end of the token.  */
+  end = s + strcspn (s, delim);
+  if (*end == '\0')
+    {
+      *save_ptr = end;
+      return s;
+    }
+
+  /* Terminate the token and make *SAVE_PTR point past it.  */
+  *end = '\0';
+  *save_ptr = end + 1;
+  return s;
+}
+#ifdef weak_alias
+libc_hidden_def (__strtok_r)
+weak_alias (__strtok_r, strtok_r)
+#endif
diff --git a/REORG.TODO/string/strverscmp.c b/REORG.TODO/string/strverscmp.c
new file mode 100644
index 0000000000..383f6445c8
--- /dev/null
+++ b/REORG.TODO/string/strverscmp.c
@@ -0,0 +1,107 @@
+/* Compare strings while treating digits characters numerically.
+   Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
+#include <string.h>
+#include <ctype.h>
+
+/* states: S_N: normal, S_I: comparing integral part, S_F: comparing
+           fractionnal parts, S_Z: idem but with leading Zeroes only */
+#define  S_N    0x0
+#define  S_I    0x3
+#define  S_F    0x6
+#define  S_Z    0x9
+
+/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
+#define  CMP    2
+#define  LEN    3
+
+
+/* Compare S1 and S2 as strings holding indices/version numbers,
+   returning less than, equal to or greater than zero if S1 is less than,
+   equal to or greater than S2 (for more info, see the texinfo doc).
+*/
+
+int
+__strverscmp (const char *s1, const char *s2)
+{
+  const unsigned char *p1 = (const unsigned char *) s1;
+  const unsigned char *p2 = (const unsigned char *) s2;
+
+  /* Symbol(s)    0       [1-9]   others
+     Transition   (10) 0  (01) d  (00) x   */
+  static const uint8_t next_state[] =
+  {
+      /* state    x    d    0  */
+      /* S_N */  S_N, S_I, S_Z,
+      /* S_I */  S_N, S_I, S_I,
+      /* S_F */  S_N, S_F, S_F,
+      /* S_Z */  S_N, S_F, S_Z
+  };
+
+  static const int8_t result_type[] =
+  {
+      /* state   x/x  x/d  x/0  d/x  d/d  d/0  0/x  0/d  0/0  */
+
+      /* S_N */  CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP,
+      /* S_I */  CMP, -1,  -1,  +1,  LEN, LEN, +1,  LEN, LEN,
+      /* S_F */  CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
+      /* S_Z */  CMP, +1,  +1,  -1,  CMP, CMP, -1,  CMP, CMP
+  };
+
+  if (p1 == p2)
+    return 0;
+
+  unsigned char c1 = *p1++;
+  unsigned char c2 = *p2++;
+  /* Hint: '0' is a digit too.  */
+  int state = S_N + ((c1 == '0') + (isdigit (c1) != 0));
+
+  int diff;
+  while ((diff = c1 - c2) == 0)
+    {
+      if (c1 == '\0')
+	return diff;
+
+      state = next_state[state];
+      c1 = *p1++;
+      c2 = *p2++;
+      state += (c1 == '0') + (isdigit (c1) != 0);
+    }
+
+  state = result_type[state * 3 + (((c2 == '0') + (isdigit (c2) != 0)))];
+
+  switch (state)
+  {
+    case CMP:
+      return diff;
+
+    case LEN:
+      while (isdigit (*p1++))
+	if (!isdigit (*p2++))
+	  return 1;
+
+      return isdigit (*p2) ? -1 : diff;
+
+    default:
+      return state;
+  }
+}
+libc_hidden_def (__strverscmp)
+weak_alias (__strverscmp, strverscmp)
diff --git a/REORG.TODO/string/strxfrm.c b/REORG.TODO/string/strxfrm.c
new file mode 100644
index 0000000000..5210466555
--- /dev/null
+++ b/REORG.TODO/string/strxfrm.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <locale/localeinfo.h>
+
+#ifndef STRING_TYPE
+# define STRING_TYPE char
+# define STRXFRM strxfrm
+# define STRXFRM_L __strxfrm_l
+#endif
+
+size_t
+STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n)
+{
+  return STRXFRM_L (dest, src, n, _NL_CURRENT_LOCALE);
+}
diff --git a/REORG.TODO/string/strxfrm_l.c b/REORG.TODO/string/strxfrm_l.c
new file mode 100644
index 0000000000..dd98a4caaf
--- /dev/null
+++ b/REORG.TODO/string/strxfrm_l.c
@@ -0,0 +1,747 @@
+/* Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Ulrich Drepper <drepper@gnu.org>, 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <langinfo.h>
+#include <locale.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+
+#ifndef STRING_TYPE
+# define STRING_TYPE char
+# define USTRING_TYPE unsigned char
+# define STRXFRM __strxfrm_l
+# define STRLEN strlen
+# define STPNCPY __stpncpy
+# define WEIGHT_H "../locale/weight.h"
+# define SUFFIX	MB
+# define L(arg) arg
+#endif
+
+#define CONCAT(a,b) CONCAT1(a,b)
+#define CONCAT1(a,b) a##b
+
+/* Maximum string size that is calculated with cached indices.  Right now this
+   is an arbitrary value open to optimizations.  SMALL_STR_SIZE * 4 has to be
+   lower than __MAX_ALLOCA_CUTOFF.  Keep localedata/xfrm-test.c in sync.  */
+#define SMALL_STR_SIZE 4095
+
+#include "../locale/localeinfo.h"
+#include WEIGHT_H
+
+/* Group locale data for shorter parameter lists.  */
+typedef struct
+{
+  uint_fast32_t nrules;
+  unsigned char *rulesets;
+  USTRING_TYPE *weights;
+  int32_t *table;
+  USTRING_TYPE *extra;
+  int32_t *indirect;
+} locale_data_t;
+
+#ifndef WIDE_CHAR_VERSION
+
+/* We need UTF-8 encoding of numbers.  */
+static int
+utf8_encode (char *buf, int val)
+{
+  int retval;
+
+  if (val < 0x80)
+    {
+      *buf++ = (char) val;
+      retval = 1;
+    }
+  else
+    {
+      int step;
+
+      for (step = 2; step < 6; ++step)
+	if ((val & (~(uint32_t)0 << (5 * step + 1))) == 0)
+	  break;
+      retval = step;
+
+      *buf = (unsigned char) (~0xff >> step);
+      --step;
+      do
+	{
+	  buf[step] = 0x80 | (val & 0x3f);
+	  val >>= 6;
+	}
+      while (--step > 0);
+      *buf |= val;
+    }
+
+  return retval;
+}
+#endif
+
+/* Find next weight and rule index.  Inlined since called for every char.  */
+static __always_inline size_t
+find_idx (const USTRING_TYPE **us, int32_t *weight_idx,
+	  unsigned char *rule_idx, const locale_data_t *l_data, const int pass)
+{
+  int32_t tmp = findidx (l_data->table, l_data->indirect, l_data->extra, us,
+			 -1);
+  *rule_idx = tmp >> 24;
+  int32_t idx = tmp & 0xffffff;
+  size_t len = l_data->weights[idx++];
+
+  /* Skip over indices of previous levels.  */
+  for (int i = 0; i < pass; i++)
+    {
+      idx += len;
+      len = l_data->weights[idx++];
+    }
+
+  *weight_idx = idx;
+  return len;
+}
+
+static int
+find_position (const USTRING_TYPE *us, const locale_data_t *l_data,
+	       const int pass)
+{
+  int32_t weight_idx;
+  unsigned char rule_idx;
+  const USTRING_TYPE *usrc = us;
+
+  find_idx (&usrc, &weight_idx, &rule_idx, l_data, pass);
+  return l_data->rulesets[rule_idx * l_data->nrules + pass] & sort_position;
+}
+
+/* Do the transformation.  */
+static size_t
+do_xfrm (const USTRING_TYPE *usrc, STRING_TYPE *dest, size_t n,
+	 const locale_data_t *l_data)
+{
+  int32_t weight_idx;
+  unsigned char rule_idx;
+  uint_fast32_t pass;
+  size_t needed = 0;
+  size_t last_needed;
+
+  /* Now the passes over the weights.  */
+  for (pass = 0; pass < l_data->nrules; ++pass)
+    {
+      size_t backw_len = 0;
+      last_needed = needed;
+      const USTRING_TYPE *cur = usrc;
+      const USTRING_TYPE *backw_start = NULL;
+
+       /* We assume that if a rule has defined `position' in one section
+         this is true for all of them.  */
+      int position = find_position (cur, l_data, pass);
+
+      if (position == 0)
+	{
+	  while (*cur != L('\0'))
+	    {
+	      const USTRING_TYPE *pos = cur;
+	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
+				     pass);
+	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
+
+	      if ((rule & sort_forward) != 0)
+		{
+		  /* Handle the pushed backward sequence.  */
+		  if (backw_start != NULL)
+		    {
+		      for (size_t i = backw_len; i > 0; )
+			{
+			  int32_t weight_idx;
+			  unsigned char rule_idx;
+			  size_t len = find_idx (&backw_start, &weight_idx,
+						 &rule_idx, l_data, pass);
+			  if (needed + i < n)
+			    for (size_t j = len; j > 0; j--)
+			      dest[needed + i - j] =
+				l_data->weights[weight_idx++];
+
+			  i -= len;
+			}
+
+		      needed += backw_len;
+		      backw_start = NULL;
+		      backw_len = 0;
+		    }
+
+		  /* Now handle the forward element.  */
+		  if (needed + len < n)
+		    while (len-- > 0)
+		      dest[needed++] = l_data->weights[weight_idx++];
+		  else
+		    /* No more characters fit into the buffer.  */
+		    needed += len;
+		}
+	      else
+		{
+		  /* Remember start of the backward sequence & track length.  */
+		  if (backw_start == NULL)
+		    backw_start = pos;
+		  backw_len += len;
+		}
+	    }
+
+
+	  /* Handle the pushed backward sequence.  */
+	  if (backw_start != NULL)
+	    {
+	      for (size_t i = backw_len; i > 0; )
+		{
+		  size_t len = find_idx (&backw_start, &weight_idx, &rule_idx,
+					 l_data, pass);
+		  if (needed + i < n)
+		    for (size_t j = len; j > 0; j--)
+		      dest[needed + i - j] =
+			l_data->weights[weight_idx++];
+
+		  i -= len;
+		}
+
+	      needed += backw_len;
+	    }
+	}
+      else
+	{
+	  int val = 1;
+#ifndef WIDE_CHAR_VERSION
+	  char buf[7];
+	  size_t buflen;
+#endif
+	  size_t i;
+
+	  while (*cur != L('\0'))
+	    {
+	      const USTRING_TYPE *pos = cur;
+	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
+				     pass);
+	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
+
+	      if ((rule & sort_forward) != 0)
+		{
+		  /* Handle the pushed backward sequence.  */
+		  if (backw_start != NULL)
+		    {
+		      for (size_t p = backw_len; p > 0; p--)
+			{
+			  size_t len;
+			  int32_t weight_idx;
+			  unsigned char rule_idx;
+			  const USTRING_TYPE *backw_cur = backw_start;
+
+			  /* To prevent a warning init the used vars.  */
+			  len = find_idx (&backw_cur, &weight_idx,
+					  &rule_idx, l_data, pass);
+
+			  for (i = 1; i < p; i++)
+			    len = find_idx (&backw_cur, &weight_idx,
+					    &rule_idx, l_data, pass);
+
+			  if (len != 0)
+			    {
+#ifdef WIDE_CHAR_VERSION
+			      if (needed + 1 + len < n)
+				{
+				  dest[needed] = val;
+				  for (i = 0; i < len; ++i)
+				    dest[needed + 1 + i] =
+				      l_data->weights[weight_idx + i];
+				}
+			      needed += 1 + len;
+#else
+			      buflen = utf8_encode (buf, val);
+			      if (needed + buflen + len < n)
+				{
+				  for (i = 0; i < buflen; ++i)
+				    dest[needed + i] = buf[i];
+				  for (i = 0; i < len; ++i)
+				    dest[needed + buflen + i] =
+				      l_data->weights[weight_idx + i];
+				}
+			      needed += buflen + len;
+#endif
+			      val = 1;
+			    }
+			  else
+			    ++val;
+			}
+
+		      backw_start = NULL;
+		      backw_len = 0;
+		    }
+
+		  /* Now handle the forward element.  */
+		  if (len != 0)
+		    {
+#ifdef WIDE_CHAR_VERSION
+		      if (needed + 1 + len < n)
+			{
+			  dest[needed] = val;
+			  for (i = 0; i < len; ++i)
+			    dest[needed + 1 + i] =
+			      l_data->weights[weight_idx + i];
+			}
+		      needed += 1 + len;
+#else
+		      buflen = utf8_encode (buf, val);
+		      if (needed + buflen + len < n)
+			{
+			  for (i = 0; i < buflen; ++i)
+			    dest[needed + i] = buf[i];
+			  for (i = 0; i < len; ++i)
+			    dest[needed + buflen + i] =
+			      l_data->weights[weight_idx + i];
+			}
+		      needed += buflen + len;
+#endif
+		      val = 1;
+		    }
+		  else
+		    ++val;
+		}
+	      else
+		{
+		  /* Remember start of the backward sequence & track length.  */
+		  if (backw_start == NULL)
+		    backw_start = pos;
+		  backw_len++;
+		}
+	    }
+
+	  /* Handle the pushed backward sequence.  */
+	  if (backw_start != NULL)
+	    {
+	      for (size_t p = backw_len; p > 0; p--)
+		{
+		  size_t len;
+		  int32_t weight_idx;
+		  unsigned char rule_idx;
+		  const USTRING_TYPE *backw_cur = backw_start;
+
+		  /* To prevent a warning init the used vars.  */
+		  len = find_idx (&backw_cur, &weight_idx,
+				  &rule_idx, l_data, pass);
+
+		  for (i = 1; i < p; i++)
+		    len = find_idx (&backw_cur, &weight_idx,
+				    &rule_idx, l_data, pass);
+
+		  if (len != 0)
+		    {
+#ifdef WIDE_CHAR_VERSION
+		      if (needed + 1 + len < n)
+			{
+			  dest[needed] = val;
+			  for (i = 0; i < len; ++i)
+			    dest[needed + 1 + i] =
+			      l_data->weights[weight_idx + i];
+			}
+		      needed += 1 + len;
+#else
+		      buflen = utf8_encode (buf, val);
+		      if (needed + buflen + len < n)
+			{
+			  for (i = 0; i < buflen; ++i)
+			    dest[needed + i] = buf[i];
+			  for (i = 0; i < len; ++i)
+			    dest[needed + buflen + i] =
+			      l_data->weights[weight_idx + i];
+			}
+		      needed += buflen + len;
+#endif
+		      val = 1;
+		    }
+		  else
+		    ++val;
+		}
+	    }
+	}
+
+      /* Finally store the byte to separate the passes or terminate
+	 the string.  */
+      if (needed < n)
+	dest[needed] = pass + 1 < l_data->nrules ? L('\1') : L('\0');
+      ++needed;
+    }
+
+  /* This is a little optimization: many collation specifications have
+     a `position' rule at the end and if no non-ignored character
+     is found the last \1 byte is immediately followed by a \0 byte
+     signalling this.  We can avoid the \1 byte(s).  */
+  if (needed > 2 && needed == last_needed + 1)
+    {
+      /* Remove the \1 byte.  */
+      if (--needed <= n)
+	dest[needed - 1] = L('\0');
+    }
+
+  /* Return the number of bytes/words we need, but don't count the NUL
+     byte/word at the end.  */
+  return needed - 1;
+}
+
+/* Do the transformation using weight-index and rule cache.  */
+static size_t
+do_xfrm_cached (STRING_TYPE *dest, size_t n, const locale_data_t *l_data,
+		size_t idxmax, int32_t *idxarr, const unsigned char *rulearr)
+{
+  uint_fast32_t nrules = l_data->nrules;
+  unsigned char *rulesets = l_data->rulesets;
+  USTRING_TYPE *weights = l_data->weights;
+  uint_fast32_t pass;
+  size_t needed = 0;
+  size_t last_needed;
+  size_t idxcnt;
+
+  /* Now the passes over the weights.  */
+  for (pass = 0; pass < nrules; ++pass)
+    {
+      size_t backw_stop = ~0ul;
+      int rule = rulesets[rulearr[0] * nrules + pass];
+      /* We assume that if a rule has defined `position' in one section
+	 this is true for all of them.  */
+      int position = rule & sort_position;
+
+      last_needed = needed;
+      if (position == 0)
+	{
+	  for (idxcnt = 0; idxcnt < idxmax; ++idxcnt)
+	    {
+	      if ((rule & sort_forward) != 0)
+		{
+		  size_t len;
+
+		  if (backw_stop != ~0ul)
+		    {
+		      /* Handle the pushed elements now.  */
+		      size_t backw;
+
+		      for (backw = idxcnt; backw > backw_stop; )
+			{
+			  --backw;
+			  len = weights[idxarr[backw]++];
+
+			  if (needed + len < n)
+			    while (len-- > 0)
+			      dest[needed++] = weights[idxarr[backw]++];
+			  else
+			    {
+				/* No more characters fit into the buffer.  */
+			      needed += len;
+			      idxarr[backw] += len;
+			    }
+			}
+
+		      backw_stop = ~0ul;
+		    }
+
+		  /* Now handle the forward element.  */
+		  len = weights[idxarr[idxcnt]++];
+		  if (needed + len < n)
+		    while (len-- > 0)
+		      dest[needed++] = weights[idxarr[idxcnt]++];
+		  else
+		    {
+		      /* No more characters fit into the buffer.  */
+		      needed += len;
+		      idxarr[idxcnt] += len;
+		    }
+		}
+	      else
+		{
+		  /* Remember where the backwards series started.  */
+		  if (backw_stop == ~0ul)
+		    backw_stop = idxcnt;
+		}
+
+	      rule = rulesets[rulearr[idxcnt + 1] * nrules + pass];
+	    }
+
+
+	  if (backw_stop != ~0ul)
+	    {
+	      /* Handle the pushed elements now.  */
+	      size_t backw;
+
+	      backw = idxcnt;
+	      while (backw > backw_stop)
+		{
+		  size_t len = weights[idxarr[--backw]++];
+
+		  if (needed + len < n)
+		    while (len-- > 0)
+		      dest[needed++] = weights[idxarr[backw]++];
+		  else
+		    {
+		      /* No more characters fit into the buffer.  */
+		      needed += len;
+		      idxarr[backw] += len;
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  int val = 1;
+#ifndef WIDE_CHAR_VERSION
+	  char buf[7];
+	  size_t buflen;
+#endif
+	  size_t i;
+
+	  for (idxcnt = 0; idxcnt < idxmax; ++idxcnt)
+	    {
+	      if ((rule & sort_forward) != 0)
+		{
+		  size_t len;
+
+		  if (backw_stop != ~0ul)
+		    {
+		     /* Handle the pushed elements now.  */
+		      size_t backw;
+
+		      for (backw = idxcnt; backw > backw_stop; )
+			{
+			  --backw;
+			  len = weights[idxarr[backw]++];
+			  if (len != 0)
+			    {
+#ifdef WIDE_CHAR_VERSION
+			      if (needed + 1 + len < n)
+				{
+				  dest[needed] = val;
+				  for (i = 0; i < len; ++i)
+				    dest[needed + 1 + i] =
+				      weights[idxarr[backw] + i];
+				}
+			      needed += 1 + len;
+#else
+			      buflen = utf8_encode (buf, val);
+			      if (needed + buflen + len < n)
+				{
+				  for (i = 0; i < buflen; ++i)
+				    dest[needed + i] = buf[i];
+				  for (i = 0; i < len; ++i)
+				    dest[needed + buflen + i] =
+				      weights[idxarr[backw] + i];
+				}
+			      needed += buflen + len;
+#endif
+			      idxarr[backw] += len;
+			      val = 1;
+			    }
+			  else
+			    ++val;
+			}
+
+		      backw_stop = ~0ul;
+		    }
+
+		  /* Now handle the forward element.  */
+		  len = weights[idxarr[idxcnt]++];
+		  if (len != 0)
+		    {
+#ifdef WIDE_CHAR_VERSION
+		      if (needed + 1+ len < n)
+			{
+			  dest[needed] = val;
+			  for (i = 0; i < len; ++i)
+			    dest[needed + 1 + i] =
+			      weights[idxarr[idxcnt] + i];
+			}
+		      needed += 1 + len;
+#else
+		      buflen = utf8_encode (buf, val);
+		      if (needed + buflen + len < n)
+			{
+			  for (i = 0; i < buflen; ++i)
+			    dest[needed + i] = buf[i];
+			  for (i = 0; i < len; ++i)
+			    dest[needed + buflen + i] =
+			      weights[idxarr[idxcnt] + i];
+			}
+		      needed += buflen + len;
+#endif
+		      idxarr[idxcnt] += len;
+		      val = 1;
+		    }
+		  else
+		    /* Note that we don't have to increment `idxarr[idxcnt]'
+		       since the length is zero.  */
+		    ++val;
+		}
+	      else
+		{
+		  /* Remember where the backwards series started.  */
+		  if (backw_stop == ~0ul)
+		    backw_stop = idxcnt;
+		}
+
+	      rule = rulesets[rulearr[idxcnt + 1] * nrules + pass];
+	    }
+
+	  if (backw_stop != ~0ul)
+	    {
+	      /* Handle the pushed elements now.  */
+	      size_t backw;
+
+	      backw = idxmax - 1;
+	      while (backw > backw_stop)
+		{
+		  size_t len = weights[idxarr[--backw]++];
+		  if (len != 0)
+		    {
+#ifdef WIDE_CHAR_VERSION
+		      if (needed + 1 + len < n)
+			{
+			  dest[needed] = val;
+			  for (i = 0; i < len; ++i)
+			    dest[needed + 1 + i] =
+			      weights[idxarr[backw] + i];
+			}
+		      needed += 1 + len;
+#else
+		      buflen = utf8_encode (buf, val);
+		      if (needed + buflen + len < n)
+			{
+			  for (i = 0; i < buflen; ++i)
+			    dest[needed + i] = buf[i];
+			  for (i = 0; i < len; ++i)
+			    dest[needed + buflen + i] =
+			      weights[idxarr[backw] + i];
+			}
+		      needed += buflen + len;
+#endif
+		      idxarr[backw] += len;
+		      val = 1;
+		    }
+		  else
+		    ++val;
+		}
+	    }
+	}
+
+      /* Finally store the byte to separate the passes or terminate
+	 the string.  */
+      if (needed < n)
+	dest[needed] = pass + 1 < nrules ? L('\1') : L('\0');
+      ++needed;
+    }
+
+  /* This is a little optimization: many collation specifications have
+     a `position' rule at the end and if no non-ignored character
+     is found the last \1 byte is immediately followed by a \0 byte
+     signalling this.  We can avoid the \1 byte(s).  */
+  if (needed > 2 && needed == last_needed + 1)
+    {
+      /* Remove the \1 byte.  */
+      if (--needed <= n)
+	dest[needed - 1] = L('\0');
+    }
+
+  /* Return the number of bytes/words we need, but don't count the NUL
+     byte/word at the end.  */
+  return needed - 1;
+}
+
+size_t
+STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
+{
+  locale_data_t l_data;
+  struct __locale_data *current = l->__locales[LC_COLLATE];
+  l_data.nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
+
+  /* Handle byte comparison case.  */
+  if (l_data.nrules == 0)
+    {
+      size_t srclen = STRLEN (src);
+
+      if (n != 0)
+	STPNCPY (dest, src, MIN (srclen + 1, n));
+
+      return srclen;
+    }
+
+  /* Handle an empty string, code hereafter relies on strlen (src) > 0.  */
+  if (*src == L('\0'))
+    {
+      if (n != 0)
+	*dest = L('\0');
+      return 0;
+    }
+
+  /* Get the locale data.  */
+  l_data.rulesets = (unsigned char *)
+    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
+  l_data.table = (int32_t *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
+  l_data.weights = (USTRING_TYPE *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
+  l_data.extra = (USTRING_TYPE *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
+  l_data.indirect = (int32_t *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
+
+  assert (((uintptr_t) l_data.table) % __alignof__ (l_data.table[0]) == 0);
+  assert (((uintptr_t) l_data.weights) % __alignof__ (l_data.weights[0]) == 0);
+  assert (((uintptr_t) l_data.extra) % __alignof__ (l_data.extra[0]) == 0);
+  assert (((uintptr_t) l_data.indirect) % __alignof__ (l_data.indirect[0]) == 0);
+
+  /* We need the elements of the string as unsigned values since they
+     are used as indeces.  */
+  const USTRING_TYPE *usrc = (const USTRING_TYPE *) src;
+
+  /* Allocate cache for small strings on the stack and fill it with weight and
+     rule indices.  If the cache size is not sufficient, continue with the
+     uncached xfrm version.  */
+  size_t idxmax = 0;
+  const USTRING_TYPE *cur = usrc;
+  int32_t *idxarr = alloca (SMALL_STR_SIZE * sizeof (int32_t));
+  unsigned char *rulearr = alloca (SMALL_STR_SIZE + 1);
+
+  do
+    {
+      int32_t tmp = findidx (l_data.table, l_data.indirect, l_data.extra, &cur,
+			     -1);
+      rulearr[idxmax] = tmp >> 24;
+      idxarr[idxmax] = tmp & 0xffffff;
+
+      ++idxmax;
+    }
+  while (*cur != L('\0') && idxmax < SMALL_STR_SIZE);
+
+  /* This element is only read, the value never used but to determine
+     another value which then is ignored.  */
+  rulearr[idxmax] = '\0';
+
+  /* Do the transformation.  */
+  if (*cur == L('\0'))
+    return do_xfrm_cached (dest, n, &l_data, idxmax, idxarr, rulearr);
+  else
+    return do_xfrm (usrc, dest, n, &l_data);
+}
+libc_hidden_def (STRXFRM)
+
+#ifndef WIDE_CHAR_VERSION
+weak_alias (__strxfrm_l, strxfrm_l)
+#endif
diff --git a/REORG.TODO/string/swab.c b/REORG.TODO/string/swab.c
new file mode 100644
index 0000000000..bcdf6595b6
--- /dev/null
+++ b/REORG.TODO/string/swab.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+
+void
+swab (const void *bfrom, void *bto, ssize_t n)
+{
+  const char *from = (const char *) bfrom;
+  char *to = (char *) bto;
+
+  n &= ~((ssize_t) 1);
+  while (n > 1)
+    {
+      const char b0 = from[--n], b1 = from[--n];
+      to[n] = b0;
+      to[n + 1] = b1;
+    }
+}
diff --git a/REORG.TODO/string/test-bcopy.c b/REORG.TODO/string/test-bcopy.c
new file mode 100644
index 0000000000..11acf07b79
--- /dev/null
+++ b/REORG.TODO/string/test-bcopy.c
@@ -0,0 +1,20 @@
+/* Test and measure bcopy functions.
+   Copyright (C) 2012-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_BCOPY
+#include "test-memmove.c"
diff --git a/REORG.TODO/string/test-bzero.c b/REORG.TODO/string/test-bzero.c
new file mode 100644
index 0000000000..a24c448804
--- /dev/null
+++ b/REORG.TODO/string/test-bzero.c
@@ -0,0 +1,19 @@
+/* Test and measure bzero functions.
+   Copyright (C) 2012-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+#define TEST_BZERO
+#include "test-memset.c"
diff --git a/REORG.TODO/string/test-endian-types.c b/REORG.TODO/string/test-endian-types.c
new file mode 100644
index 0000000000..86a89324f7
--- /dev/null
+++ b/REORG.TODO/string/test-endian-types.c
@@ -0,0 +1,49 @@
+/* Test endian.h endian-conversion macros always return the correct type.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <endian.h>
+#include <stdint.h>
+
+int i;
+uint16_t u16;
+uint32_t u32;
+uint64_t u64;
+
+int
+do_test (void)
+{
+  /* This is a compilation test.  */
+  extern __typeof (htobe16 (i)) u16;
+  extern __typeof (htole16 (i)) u16;
+  extern __typeof (be16toh (i)) u16;
+  extern __typeof (le16toh (i)) u16;
+  extern __typeof (htobe32 (i)) u32;
+  extern __typeof (htole32 (i)) u32;
+  extern __typeof (be32toh (i)) u32;
+  extern __typeof (le32toh (i)) u32;
+  extern __typeof (htobe64 (i)) u64;
+  extern __typeof (htole64 (i)) u64;
+  extern __typeof (be64toh (i)) u64;
+  extern __typeof (le64toh (i)) u64;
+  (void) u16;
+  (void) u32;
+  (void) u64;
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-explicit_bzero.c b/REORG.TODO/string/test-explicit_bzero.c
new file mode 100644
index 0000000000..7e41163eb1
--- /dev/null
+++ b/REORG.TODO/string/test-explicit_bzero.c
@@ -0,0 +1,20 @@
+/* Test and measure explicit_bzero.
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+#define TEST_EXPLICIT_BZERO
+#define TEST_BZERO
+#include "test-memset.c"
diff --git a/REORG.TODO/string/test-ffs.c b/REORG.TODO/string/test-ffs.c
new file mode 100644
index 0000000000..11b6ea838b
--- /dev/null
+++ b/REORG.TODO/string/test-ffs.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
+     On-Line Applications Research Corporation.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int
+do_test (void)
+{
+  int failures = 0;
+  int i;
+
+  auto void try (const char *name, long long int param, int value,
+		 int expected);
+
+  void try (const char *name, long long int param, int value, int expected)
+    {
+      if (value != expected)
+	{
+	  printf ("%s(%#llx) expected %d got %d\n",
+		  name, param, expected, value);
+	  ++failures;
+	}
+      else
+	printf ("%s(%#llx) as expected %d\n", name, param, value);
+    }
+
+#define TEST(fct, type) \
+  try (#fct, 0, fct ((type) 0), 0);					      \
+  for (i=0 ; i < 8 * sizeof (type); i++)				      \
+    try (#fct, 1ll << i, fct (((type) 1) << i), i + 1);			      \
+  for (i=0 ; i < 8 * sizeof (type) ; i++)				      \
+    try (#fct, (~((type) 0) >> i) << i, fct ((~((type) 0) >> i) << i), i + 1);\
+  try (#fct, 0x80008000, fct ((type) 0x80008000), 16)
+
+  TEST (ffs, int);
+  TEST (ffsl, long int);
+  TEST (ffsll, long long int);
+
+  if (failures)
+    printf ("Test FAILED!  %d failure%s.\n", failures, &"s"[failures == 1]);
+  else
+    puts ("Test succeeded.");
+
+  return failures;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-memccpy.c b/REORG.TODO/string/test-memccpy.c
new file mode 100644
index 0000000000..7bd67a61e7
--- /dev/null
+++ b/REORG.TODO/string/test-memccpy.c
@@ -0,0 +1,269 @@
+/* Test and measure memccpy functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#define TEST_NAME "memccpy"
+#include "test-string.h"
+
+void *simple_memccpy (void *, const void *, int, size_t);
+void *stupid_memccpy (void *, const void *, int, size_t);
+
+IMPL (stupid_memccpy, 0)
+IMPL (simple_memccpy, 0)
+IMPL (memccpy, 1)
+
+void *
+simple_memccpy (void *dst, const void *src, int c, size_t n)
+{
+  const char *s = src;
+  char *d = dst;
+
+  while (n-- > 0)
+    if ((*d++ = *s++) == (char) c)
+      return d;
+
+  return NULL;
+}
+
+void *
+stupid_memccpy (void *dst, const void *src, int c, size_t n)
+{
+  void *p = memchr (src, c, n);
+
+  if (p != NULL)
+    return mempcpy (dst, src, p - src + 1);
+
+  memcpy (dst, src, n);
+  return NULL;
+}
+
+typedef void *(*proto_t) (void *, const void *, int c, size_t);
+
+static void
+do_one_test (impl_t *impl, void *dst, const void *src, int c, size_t len,
+	     size_t n)
+{
+  void *expect = len > n ? NULL : (char *) dst + len;
+  if (CALL (impl, dst, src, c, n) != expect)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     CALL (impl, dst, src, c, n), expect);
+      ret = 1;
+      return;
+    }
+
+  if (memcmp (dst, src, len > n ? n : len) != 0)
+    {
+      error (0, 0, "Wrong result in function %s", impl->name);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, int c, size_t len, size_t n,
+	 int max_char)
+{
+  size_t i;
+  char *s1, *s2;
+
+  align1 &= 7;
+  if (align1 + len >= page_size)
+    return;
+
+  align2 &= 7;
+  if (align2 + len >= page_size)
+    return;
+
+  s1 = (char *) (buf1 + align1);
+  s2 = (char *) (buf2 + align2);
+
+  for (i = 0; i < len - 1; ++i)
+    {
+      s1[i] = 32 + 23 * i % (max_char - 32);
+      if (s1[i] == (char) c)
+	--s1[i];
+    }
+  s1[len - 1] = c;
+  for (i = len; i + align1 < page_size && i < len + 64; ++i)
+    s1[i] = 32 + 32 * i % (max_char - 32);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s2, s1, c, len, n);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size, mode;
+  unsigned char *p1 = buf1 + page_size - 512;
+  unsigned char *p2 = buf2 + page_size - 512;
+  unsigned char *res, c;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      mode = random ();
+      c = random ();
+      if (mode & 1)
+	{
+	  size = random () & 255;
+	  align1 = 512 - size - (random () & 15);
+	  if (mode & 2)
+	    align2 = align1 - (random () & 24);
+	  else
+	    align2 = align1 - (random () & 31);
+	  if (mode & 4)
+	    {
+	      j = align1;
+	      align1 = align2;
+	      align2 = j;
+	    }
+	  if (mode & 8)
+	    len = size - (random () & 31);
+	  else
+	    len = 512;
+	  if (len >= 512)
+	    len = random () & 511;
+	}
+      else
+	{
+	  align1 = random () & 31;
+	  if (mode & 2)
+	    align2 = random () & 31;
+	  else
+	    align2 = align1 + (random () & 24);
+	  len = random () & 511;
+	  j = align1;
+	  if (align2 > j)
+	    j = align2;
+	  if (mode & 4)
+	    {
+	      size = random () & 511;
+	      if (size + j > 512)
+		size = 512 - j - (random() & 31);
+	    }
+	  else
+	    size = 512 - j;
+	  if ((mode & 8) && len + j >= 512)
+	    len = 512 - j - (random () & 7);
+	}
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = c;
+	  else
+	    {
+	      p1[i] = random () & 255;
+	      if (i >= align1 && i < len + align1 && p1[i] == c)
+		p1[i] = (random () & 127) + 3 + c;
+	    }
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  unsigned char *expect;
+	  memset (p2 - 64, '\1', 512 + 64);
+	  res = CALL (impl, p2 + align2, p1 + align1, (char) c, size);
+	  if (len >= size)
+	    expect = NULL;
+	  else
+	    expect = p2 + align2 + len + 1;
+
+	  if (res != expect)
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %d) %p != %p",
+		     n, impl->name, align1, align2, len, size, c, res, expect);
+	      ret = 1;
+	    }
+	  for (j = 0; j < align2 + 64; ++j)
+	    {
+	      if (p2[j - 64] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  j = align2 + len + 1;
+	  if (size + align2 < j)
+	    j = size + align2;
+	  for (; j < 512; ++j)
+	    {
+	      if (p2[j] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  j = len + 1;
+	  if (size < j)
+	    j = size;
+	  if (memcmp (p1 + align1, p2 + align2, j))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, 12, 16, 16, 127);
+      do_test (i, i, 23, 16, 16, 255);
+      do_test (i, 2 * i, 28, 16, 16, 127);
+      do_test (2 * i, i, 31, 16, 16, 255);
+      do_test (8 - i, 2 * i, 1, 1 << i, 2 << i, 127);
+      do_test (2 * i, 8 - i, 17, 2 << i, 1 << i, 127);
+      do_test (8 - i, 2 * i, 0, 1 << i, 2 << i, 255);
+      do_test (2 * i, 8 - i, i, 2 << i, 1 << i, 255);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, i, 4 << i, 8 << i, 127);
+      do_test (0, 0, i, 16 << i, 8 << i, 127);
+      do_test (8 - i, 2 * i, i, 4 << i, 8 << i, 127);
+      do_test (8 - i, 2 * i, i, 16 << i, 8 << i, 127);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-memchr.c b/REORG.TODO/string/test-memchr.c
new file mode 100644
index 0000000000..73a93f0fc9
--- /dev/null
+++ b/REORG.TODO/string/test-memchr.c
@@ -0,0 +1,227 @@
+/* Test memchr functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "memchr"
+#else
+# define TEST_NAME "wmemchr"
+#endif /* WIDE */
+
+#include "test-string.h"
+#include <stdint.h>
+
+#ifndef WIDE
+# define MEMCHR memchr
+# define CHAR char
+# define UCHAR unsigned char
+# define SIMPLE_MEMCHR simple_memchr
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+#else
+# include <wchar.h>
+# define MEMCHR wmemchr
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define SIMPLE_MEMCHR simple_wmemchr
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+#endif /* WIDE */
+
+typedef CHAR *(*proto_t) (const CHAR *, int, size_t);
+CHAR *SIMPLE_MEMCHR (const CHAR *, int, size_t);
+
+IMPL (SIMPLE_MEMCHR, 0)
+IMPL (MEMCHR, 1)
+
+CHAR *
+SIMPLE_MEMCHR (const CHAR *s, int c, size_t n)
+{
+  while (n--)
+    if (*s++ == (CHAR) c)
+      return (CHAR *) s - 1;
+  return NULL;
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *s, int c, size_t n, CHAR *exp_res)
+{
+  CHAR *res = CALL (impl, s, c, n);
+  if (res != exp_res)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     res, exp_res);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align, size_t pos, size_t len, size_t n, int seek_char)
+{
+  size_t i;
+  CHAR *result;
+
+  if ((align + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  CHAR *buf = (CHAR *) (buf1);
+
+  for (i = 0; i < len; ++i)
+    {
+      buf[align + i] = 1 + 23 * i % SMALL_CHAR;
+      if (buf[align + i] == seek_char)
+	buf[align + i] = seek_char + 1;
+    }
+  buf[align + len] = 0;
+
+  if (pos < len)
+    {
+      buf[align + pos] = seek_char;
+      buf[align + len] = -seek_char;
+      result = (CHAR *) (buf + align + pos);
+    }
+  else
+    {
+      result = NULL;
+      buf[align + len] = seek_char;
+    }
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, (CHAR *) (buf + align), seek_char, n, result);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align, pos, len;
+  int seek_char;
+  CHAR *result;
+  UCHAR *p = (UCHAR *) (buf1 + page_size) - 512;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align = random () & 15;
+      pos = random () & 511;
+      if (pos + align >= 512)
+	pos = 511 - align - (random () & 7);
+      len = random () & 511;
+      if (pos >= len)
+	len = pos + (random () & 7);
+      if (len + align >= 512)
+	len = 512 - align - (random () & 7);
+      seek_char = random () & BIG_CHAR;
+      j = len + align + 64;
+      if (j > 512)
+	j = 512;
+
+      for (i = 0; i < j; i++)
+	{
+	  if (i == pos + align)
+	    p[i] = seek_char;
+	  else
+	    {
+	      p[i] = random () & BIG_CHAR;
+	      if (i < pos + align && p[i] == seek_char)
+		p[i] = seek_char + 13;
+	    }
+	}
+
+      if (pos < len)
+	{
+	  size_t r = random ();
+	  if ((r & 31) == 0)
+	    len = ~(uintptr_t) (p + align) - ((r >> 5) & 31);
+	  result = (CHAR *) (p + pos + align);
+	}
+      else
+	result = NULL;
+
+      FOR_EACH_IMPL (impl, 1)
+	if (CALL (impl, (CHAR *) (p + align), seek_char, len) != result)
+	  {
+	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
+		   n, impl->name, align, seek_char, len, pos,
+		   CALL (impl, (CHAR *) (p + align), seek_char, len),
+		   result, p);
+	    ret = 1;
+	  }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i, j;
+
+  test_init ();
+
+  printf ("%20s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      /* Test n == 0.  */
+      do_test (i, i, 0, 0, 23);
+      do_test (i, i, 0, 0, 0);
+
+      do_test (0, 16 << i, 2048, 2048, 23);
+      do_test (i, 64, 256, 256, 23);
+      do_test (0, 16 << i, 2048, 2048, 0);
+      do_test (i, 64, 256, 256, 0);
+
+      /* Check for large input sizes and for these cases we need to
+	 make sure the byte is within the size range (that's why
+	 7 << i must be smaller than 2048).  */
+      do_test (0, 7 << i, 2048, SIZE_MAX, 23);
+      do_test (0, 2048 - i, 2048, SIZE_MAX, 23);
+      do_test (i, 64, 256, SIZE_MAX, 23);
+      do_test (0, 7 << i, 2048, SIZE_MAX, 0);
+      do_test (0, 2048 - i, 2048, SIZE_MAX, 0);
+      do_test (i, 64, 256, SIZE_MAX, 0);
+    }
+
+  for (i = 1; i < 64; ++i)
+    {
+      for (j = 1; j < 64; j++)
+        {
+	  do_test (0, 64 - j, 64, SIZE_MAX, 23);
+	  do_test (i, 64 - j, 64, SIZE_MAX, 23);
+        }
+    }
+
+  for (i = 1; i < 32; ++i)
+    {
+      do_test (0, i, i + 1, i + 1, 23);
+      do_test (0, i, i + 1, i + 1, 0);
+    }
+
+  /* BZ#21182 - wrong overflow calculation for i686 implementation
+     with address near end of the page.  */
+  for (i = 2; i < 16; ++i)
+    /* page_size is in fact getpagesize() * 2.  */
+    do_test (page_size / 2 - i, i, i, 1, 0x9B);
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-memcmp.c b/REORG.TODO/string/test-memcmp.c
new file mode 100644
index 0000000000..a7969edaea
--- /dev/null
+++ b/REORG.TODO/string/test-memcmp.c
@@ -0,0 +1,525 @@
+/* Test and measure memcmp functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+   Added wmemcmp support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifdef WIDE
+# define TEST_NAME "wmemcmp"
+#else
+# define TEST_NAME "memcmp"
+#endif
+#include "test-string.h"
+#ifdef WIDE
+# include <inttypes.h>
+# include <wchar.h>
+
+# define MEMCMP wmemcmp
+# define MEMCPY wmemcpy
+# define SIMPLE_MEMCMP simple_wmemcmp
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define CHARBYTES 4
+# define CHAR__MIN WCHAR_MIN
+# define CHAR__MAX WCHAR_MAX
+int
+simple_wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n)
+{
+  int ret = 0;
+  /* Warning!
+	wmemcmp has to use SIGNED comparison for elements.
+	memcmp has to use UNSIGNED comparison for elemnts.
+  */
+  while (n-- && (ret = *s1 < *s2 ? -1 : *s1 == *s2 ? 0 : 1) == 0) {s1++; s2++;}
+  return ret;
+}
+#else
+# include <limits.h>
+
+# define MEMCMP memcmp
+# define MEMCPY memcpy
+# define SIMPLE_MEMCMP simple_memcmp
+# define CHAR char
+# define MAX_CHAR 255
+# define UCHAR unsigned char
+# define CHARBYTES 1
+# define CHAR__MIN CHAR_MIN
+# define CHAR__MAX CHAR_MAX
+
+int
+simple_memcmp (const char *s1, const char *s2, size_t n)
+{
+  int ret = 0;
+
+  while (n-- && (ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) == 0);
+  return ret;
+}
+#endif
+
+typedef int (*proto_t) (const CHAR *, const CHAR *, size_t);
+
+IMPL (SIMPLE_MEMCMP, 0)
+IMPL (MEMCMP, 1)
+
+static int
+check_result (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t len,
+	      int exp_result)
+{
+  int result = CALL (impl, s1, s2, len);
+  if ((exp_result == 0 && result != 0)
+      || (exp_result < 0 && result >= 0)
+      || (exp_result > 0 && result <= 0))
+    {
+      error (0, 0, "Wrong result in function %s %d %d", impl->name,
+	     result, exp_result);
+      ret = 1;
+      return -1;
+    }
+
+  return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t len,
+	     int exp_result)
+{
+  if (check_result (impl, s1, s2, len, exp_result) < 0)
+    return;
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int exp_result)
+{
+  size_t i;
+  CHAR *s1, *s2;
+
+  if (len == 0)
+    return;
+
+  align1 &= 63;
+  if (align1 + (len + 1) * CHARBYTES >= page_size)
+    return;
+
+  align2 &= 63;
+  if (align2 + (len + 1) * CHARBYTES >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1 + align1);
+  s2 = (CHAR *) (buf2 + align2);
+
+  for (i = 0; i < len; i++)
+    s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % CHAR__MAX;
+
+  s1[len] = align1;
+  s2[len] = align2;
+  s2[len - 1] -= exp_result;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, s2, len, exp_result);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, pos, len;
+  int result;
+  long r;
+  UCHAR *p1 =  (UCHAR *) (buf1 + page_size - 512 * CHARBYTES);
+  UCHAR *p2 =  (UCHAR *) (buf2 + page_size - 512 * CHARBYTES);
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+   align1 = random () & 31;
+      if (random () & 1)
+	align2 = random () & 31;
+      else
+	align2 = align1 + (random () & 24);
+      pos = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (pos + j >= 512)
+	pos = 511 - j - (random () & 7);
+      len = random () & 511;
+      if (len + j >= 512)
+	len = 511 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512) j = 512;
+      for (i = 0; i < j; ++i)
+	p1[i] = random () & 255;
+      for (i = 0; i < j; ++i)
+	p2[i] = random () & 255;
+
+      result = 0;
+      if (pos >= len)
+	MEMCPY ((CHAR *) p2 + align2, (const CHAR *) p1 + align1, len);
+      else
+	{
+	  MEMCPY ((CHAR *) p2 + align2, (const CHAR *) p1 + align1, pos);
+	  if (p2[align2 + pos] == p1[align1 + pos])
+	    {
+	      p2[align2 + pos] = random () & 255;
+	      if (p2[align2 + pos] == p1[align1 + pos])
+		p2[align2 + pos] = p1[align1 + pos] + 3 + (random () & 127);
+	    }
+
+	  if (p1[align1 + pos] < p2[align2 + pos])
+	    result = -1;
+	  else
+	    result = 1;
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  r = CALL (impl, (CHAR *) p1 + align1, (const CHAR *) p2 + align2,
+		    len);
+	  if ((r == 0 && result)
+	      || (r < 0 && result >= 0)
+	      || (r > 0 && result <= 0))
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p",
+		     n, impl->name, align1 * CHARBYTES & 63,  align2 * CHARBYTES & 63, len, pos, r, result, p1, p2);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+static void
+check1 (void)
+{
+  CHAR s1[116], s2[116];
+  int n, exp_result;
+
+  s1[0] = -108;
+  s2[0] = -108;
+  s1[1] = 99;
+  s2[1] = 99;
+  s1[2] = -113;
+  s2[2] = -113;
+  s1[3] = 1;
+  s2[3] = 1;
+  s1[4] = 116;
+  s2[4] = 116;
+  s1[5] = 99;
+  s2[5] = 99;
+  s1[6] = -113;
+  s2[6] = -113;
+  s1[7] = 1;
+  s2[7] = 1;
+  s1[8] = 84;
+  s2[8] = 84;
+  s1[9] = 99;
+  s2[9] = 99;
+  s1[10] = -113;
+  s2[10] = -113;
+  s1[11] = 1;
+  s2[11] = 1;
+  s1[12] = 52;
+  s2[12] = 52;
+  s1[13] = 99;
+  s2[13] = 99;
+  s1[14] = -113;
+  s2[14] = -113;
+  s1[15] = 1;
+  s2[15] = 1;
+  s1[16] = -76;
+  s2[16] = -76;
+  s1[17] = -14;
+  s2[17] = -14;
+  s1[18] = -109;
+  s2[18] = -109;
+  s1[19] = 1;
+  s2[19] = 1;
+  s1[20] = -108;
+  s2[20] = -108;
+  s1[21] = -14;
+  s2[21] = -14;
+  s1[22] = -109;
+  s2[22] = -109;
+  s1[23] = 1;
+  s2[23] = 1;
+  s1[24] = 84;
+  s2[24] = 84;
+  s1[25] = -15;
+  s2[25] = -15;
+  s1[26] = -109;
+  s2[26] = -109;
+  s1[27] = 1;
+  s2[27] = 1;
+  s1[28] = 52;
+  s2[28] = 52;
+  s1[29] = -15;
+  s2[29] = -15;
+  s1[30] = -109;
+  s2[30] = -109;
+  s1[31] = 1;
+  s2[31] = 1;
+  s1[32] = 20;
+  s2[32] = 20;
+  s1[33] = -15;
+  s2[33] = -15;
+  s1[34] = -109;
+  s2[34] = -109;
+  s1[35] = 1;
+  s2[35] = 1;
+  s1[36] = 20;
+  s2[36] = 20;
+  s1[37] = -14;
+  s2[37] = -14;
+  s1[38] = -109;
+  s2[38] = -109;
+  s1[39] = 1;
+  s2[39] = 1;
+  s1[40] = 52;
+  s2[40] = 52;
+  s1[41] = -14;
+  s2[41] = -14;
+  s1[42] = -109;
+  s2[42] = -109;
+  s1[43] = 1;
+  s2[43] = 1;
+  s1[44] = 84;
+  s2[44] = 84;
+  s1[45] = -14;
+  s2[45] = -14;
+  s1[46] = -109;
+  s2[46] = -109;
+  s1[47] = 1;
+  s2[47] = 1;
+  s1[48] = 116;
+  s2[48] = 116;
+  s1[49] = -14;
+  s2[49] = -14;
+  s1[50] = -109;
+  s2[50] = -109;
+  s1[51] = 1;
+  s2[51] = 1;
+  s1[52] = 116;
+  s2[52] = 116;
+  s1[53] = -15;
+  s2[53] = -15;
+  s1[54] = -109;
+  s2[54] = -109;
+  s1[55] = 1;
+  s2[55] = 1;
+  s1[56] = -44;
+  s2[56] = -44;
+  s1[57] = -14;
+  s2[57] = -14;
+  s1[58] = -109;
+  s2[58] = -109;
+  s1[59] = 1;
+  s2[59] = 1;
+  s1[60] = -108;
+  s2[60] = -108;
+  s1[61] = -15;
+  s2[61] = -15;
+  s1[62] = -109;
+  s2[62] = -109;
+  s1[63] = 1;
+  s2[63] = 1;
+  s1[64] = -76;
+  s2[64] = -76;
+  s1[65] = -15;
+  s2[65] = -15;
+  s1[66] = -109;
+  s2[66] = -109;
+  s1[67] = 1;
+  s2[67] = 1;
+  s1[68] = -44;
+  s2[68] = -44;
+  s1[69] = -15;
+  s2[69] = -15;
+  s1[70] = -109;
+  s2[70] = -109;
+  s1[71] = 1;
+  s2[71] = 1;
+  s1[72] = -12;
+  s2[72] = -12;
+  s1[73] = -15;
+  s2[73] = -15;
+  s1[74] = -109;
+  s2[74] = -109;
+  s1[75] = 1;
+  s2[75] = 1;
+  s1[76] = -12;
+  s2[76] = -12;
+  s1[77] = -14;
+  s2[77] = -14;
+  s1[78] = -109;
+  s2[78] = -109;
+  s1[79] = 1;
+  s2[79] = 1;
+  s1[80] = 20;
+  s2[80] = -68;
+  s1[81] = -12;
+  s2[81] = 64;
+  s1[82] = -109;
+  s2[82] = -106;
+  s1[83] = 1;
+  s2[83] = 1;
+  s1[84] = -12;
+  s2[84] = -12;
+  s1[85] = -13;
+  s2[85] = -13;
+  s1[86] = -109;
+  s2[86] = -109;
+  s1[87] = 1;
+  s2[87] = 1;
+  s1[88] = -44;
+  s2[88] = -44;
+  s1[89] = -13;
+  s2[89] = -13;
+  s1[90] = -109;
+  s2[90] = -109;
+  s1[91] = 1;
+  s2[91] = 1;
+  s1[92] = -76;
+  s2[92] = -76;
+  s1[93] = -13;
+  s2[93] = -13;
+  s1[94] = -109;
+  s2[94] = -109;
+  s1[95] = 1;
+  s2[95] = 1;
+  s1[96] = -108;
+  s2[96] = -108;
+  s1[97] = -13;
+  s2[97] = -13;
+  s1[98] = -109;
+  s2[98] = -109;
+  s1[99] = 1;
+  s2[99] = 1;
+  s1[100] = 116;
+  s2[100] = 116;
+  s1[101] = CHAR__MIN;
+  s2[101] = CHAR__MAX;
+  s1[102] = -109;
+  s2[102] = -109;
+  s1[103] = 1;
+  s2[103] = 1;
+  s1[104] = 84;
+  s2[104] = 84;
+  s1[105] = -13;
+  s2[105] = -13;
+  s1[106] = -109;
+  s2[106] = -109;
+  s1[107] = 1;
+  s2[107] = 1;
+  s1[108] = 52;
+  s2[108] = 52;
+  s1[109] = -13;
+  s2[109] = -13;
+  s1[110] = -109;
+  s2[110] = -109;
+  s1[111] = 1;
+  s2[111] = 1;
+  s1[112] = CHAR__MAX;
+  s2[112] = CHAR__MIN;
+  s1[113] = -13;
+  s2[113] = -13;
+  s1[114] = -109;
+  s2[114] = -109;
+  s1[115] = 1;
+  s2[115] = 1;
+
+  n = 116;
+  for (size_t i = 0; i < n; i++)
+    {
+      exp_result = SIMPLE_MEMCMP (s1 + i, s2 + i, n - i);
+      FOR_EACH_IMPL (impl, 0)
+	check_result (impl, s1 + i, s2 + i, n - i, exp_result);
+    }
+}
+
+/* This test checks that memcmp doesn't overrun buffers.  */
+static void
+check2 (void)
+{
+  size_t max_length = page_size / sizeof (CHAR);
+
+  /* Initialize buf2 to the same values as buf1.  The bug requires the
+     last compared byte to be different.  */
+  memcpy (buf2, buf1, page_size);
+  ((char *) buf2)[page_size - 1] ^= 0x11;
+
+  for (size_t length = 1; length < max_length; length++)
+    {
+      CHAR *s1 = (CHAR *) buf1 + max_length - length;
+      CHAR *s2 = (CHAR *) buf2 + max_length - length;
+
+      const int exp_result = SIMPLE_MEMCMP (s1, s2, length);
+
+      FOR_EACH_IMPL (impl, 0)
+	check_result (impl, s1, s2, length, exp_result);
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  check1 ();
+  check2 ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 16; ++i)
+    {
+      do_test (i * CHARBYTES, i * CHARBYTES, i, 0);
+      do_test (i * CHARBYTES, i * CHARBYTES, i, 1);
+      do_test (i * CHARBYTES, i * CHARBYTES, i, -1);
+    }
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, 0);
+      do_test (0, 0, i, 1);
+      do_test (0, 0, i, -1);
+    }
+
+  for (i = 1; i < 10; ++i)
+    {
+      do_test (0, 0, 2 << i, 0);
+      do_test (0, 0, 2 << i, 1);
+      do_test (0, 0, 2 << i, -1);
+      do_test (0, 0, 16 << i, 0);
+      do_test ((8 - i) * CHARBYTES, (2 * i) * CHARBYTES, 16 << i, 0);
+      do_test (0, 0, 16 << i, 1);
+      do_test (0, 0, 16 << i, -1);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 0);
+      do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 1);
+      do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, -1);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-memcpy.c b/REORG.TODO/string/test-memcpy.c
new file mode 100644
index 0000000000..49f0a76047
--- /dev/null
+++ b/REORG.TODO/string/test-memcpy.c
@@ -0,0 +1,259 @@
+/* Test and measure memcpy functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef MEMCPY_RESULT
+# define MEMCPY_RESULT(dst, len) dst
+# define MIN_PAGE_SIZE 131072
+# define TEST_MAIN
+# define TEST_NAME "memcpy"
+# include "test-string.h"
+
+char *simple_memcpy (char *, const char *, size_t);
+char *builtin_memcpy (char *, const char *, size_t);
+
+IMPL (simple_memcpy, 0)
+IMPL (builtin_memcpy, 0)
+IMPL (memcpy, 1)
+
+char *
+simple_memcpy (char *dst, const char *src, size_t n)
+{
+  char *ret = dst;
+  while (n--)
+    *dst++ = *src++;
+  return ret;
+}
+
+char *
+builtin_memcpy (char *dst, const char *src, size_t n)
+{
+  return __builtin_memcpy (dst, src, n);
+}
+#endif
+
+typedef char *(*proto_t) (char *, const char *, size_t);
+
+static void
+do_one_test (impl_t *impl, char *dst, const char *src,
+	     size_t len)
+{
+  size_t i;
+
+  /* Must clear the destination buffer set by the previous run.  */
+  for (i = 0; i < len; i++)
+    dst[i] = 0;
+
+  if (CALL (impl, dst, src, len) != MEMCPY_RESULT (dst, len))
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     CALL (impl, dst, src, len), MEMCPY_RESULT (dst, len));
+      ret = 1;
+      return;
+    }
+
+  if (memcmp (dst, src, len) != 0)
+    {
+      error (0, 0, "Wrong result in function %s dst %p \"%.*s\" src %p \"%.*s\" len %zu",
+	     impl->name, dst, (int) len, dst, src, (int) len, src, len);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len)
+{
+  size_t i, j;
+  char *s1, *s2;
+
+  align1 &= 63;
+  if (align1 + len >= page_size)
+    return;
+
+  align2 &= 63;
+  if (align2 + len >= page_size)
+    return;
+
+  s1 = (char *) (buf1 + align1);
+  s2 = (char *) (buf2 + align2);
+
+  for (i = 0, j = 1; i < len; i++, j += 23)
+    s1[i] = j;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s2, s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size1, size2, size;
+  int c;
+  unsigned char *p1, *p2;
+  unsigned char *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      if (n == 0)
+	{
+	  len = getpagesize ();
+	  size = len + 512;
+	  size1 = size;
+	  size2 = size;
+	  align1 = 512;
+	  align2 = 512;
+	}
+      else
+	{
+	  if ((random () & 255) == 0)
+	    size = 65536;
+	  else
+	    size = 768;
+	  if (size > page_size)
+	    size = page_size;
+	  size1 = size;
+	  size2 = size;
+	  i = random ();
+	  if (i & 3)
+	    size -= 256;
+	  if (i & 1)
+	    size1 -= 256;
+	  if (i & 2)
+	    size2 -= 256;
+	  if (i & 4)
+	    {
+	      len = random () % size;
+	      align1 = size1 - len - (random () & 31);
+	      align2 = size2 - len - (random () & 31);
+	      if (align1 > size1)
+		align1 = 0;
+	      if (align2 > size2)
+		align2 = 0;
+	    }
+	  else
+	    {
+	      align1 = random () & 63;
+	      align2 = random () & 63;
+	      len = random () % size;
+	      if (align1 + len > size1)
+		align1 = size1 - len;
+	      if (align2 + len > size2)
+		align2 = size2 - len;
+	    }
+	}
+      p1 = buf1 + page_size - size1;
+      p2 = buf2 + page_size - size2;
+      c = random () & 255;
+      j = align1 + len + 256;
+      if (j > size1)
+	j = size1;
+      for (i = 0; i < j; ++i)
+	p1[i] = random () & 255;
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  j = align2 + len + 256;
+	  if (j > size2)
+	    j = size2;
+	  memset (p2, c, j);
+	  res = (unsigned char *) CALL (impl,
+					(char *) (p2 + align2),
+					(char *) (p1 + align1), len);
+	  if (res != MEMCPY_RESULT (p2 + align2, len))
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
+		     n, impl->name, align1, align2, len, res,
+		     MEMCPY_RESULT (p2 + align2, len));
+	      ret = 1;
+	    }
+	  for (i = 0; i < align2; ++i)
+	    {
+	      if (p2[i] != c)
+		{
+		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  for (i = align2 + len; i < j; ++i)
+	    {
+	      if (p2[i] != c)
+		{
+		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  if (memcmp (p1 + align1, p2 + align2, len))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < 18; ++i)
+    {
+      do_test (0, 0, 1 << i);
+      do_test (i, 0, 1 << i);
+      do_test (0, i, 1 << i);
+      do_test (i, i, 1 << i);
+    }
+
+  for (i = 0; i < 32; ++i)
+    {
+      do_test (0, 0, i);
+      do_test (i, 0, i);
+      do_test (0, i, i);
+      do_test (i, i, i);
+    }
+
+  for (i = 3; i < 32; ++i)
+    {
+      if ((i & (i - 1)) == 0)
+	continue;
+      do_test (0, 0, 16 * i);
+      do_test (i, 0, 16 * i);
+      do_test (0, i, 16 * i);
+      do_test (i, i, 16 * i);
+    }
+
+  do_test (0, 0, getpagesize ());
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-memmem.c b/REORG.TODO/string/test-memmem.c
new file mode 100644
index 0000000000..82fd93ccde
--- /dev/null
+++ b/REORG.TODO/string/test-memmem.c
@@ -0,0 +1,184 @@
+/* Test and measure memmem functions.
+   Copyright (C) 2008-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2008.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#define TEST_NAME "memmem"
+#define BUF1PAGES 20
+#define ITERATIONS 500
+#include "test-string.h"
+
+typedef char *(*proto_t) (const void *, size_t, const void *, size_t);
+void *simple_memmem (const void *, size_t, const void *, size_t);
+
+IMPL (simple_memmem, 0)
+IMPL (memmem, 1)
+
+void *
+simple_memmem (const void *haystack, size_t haystack_len, const void *needle,
+	       size_t needle_len)
+{
+  const char *begin;
+  const char *const last_possible
+    = (const char *) haystack + haystack_len - needle_len;
+
+  if (needle_len == 0)
+    /* The first occurrence of the empty string is deemed to occur at
+       the beginning of the string.  */
+    return (void *) haystack;
+
+  /* Sanity check, otherwise the loop might search through the whole
+     memory.  */
+  if (__glibc_unlikely (haystack_len < needle_len))
+    return NULL;
+
+  for (begin = (const char *) haystack; begin <= last_possible; ++begin)
+    if (begin[0] == ((const char *) needle)[0] &&
+        !memcmp ((const void *) &begin[1],
+                 (const void *) ((const char *) needle + 1),
+                 needle_len - 1))
+      return (void *) begin;
+
+  return NULL;
+}
+
+static int
+check_result (impl_t *impl, const void *haystack, size_t haystack_len,
+	     const void *needle, size_t needle_len, const void *expected)
+{
+  void *res;
+
+  res = CALL (impl, haystack, haystack_len, needle, needle_len);
+  if (res != expected)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     res, expected);
+      ret = 1;
+      return -1;
+    }
+
+  return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const void *haystack, size_t haystack_len,
+	     const void *needle, size_t needle_len, const void *expected)
+{
+  if (check_result (impl, haystack, haystack_len, needle, needle_len,
+		    expected) < 0)
+    return;
+}
+
+static void
+do_test (const char *str, size_t len, size_t idx)
+{
+  char tmpbuf[len];
+
+  memcpy (tmpbuf, buf1 + idx, len);
+  memcpy (buf1 + idx, str, len);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx);
+
+  memcpy (buf1 + idx, tmpbuf, len);
+}
+
+static void
+do_random_tests (void)
+{
+  for (size_t n = 0; n < ITERATIONS; ++n)
+    {
+      char tmpbuf[32];
+
+      size_t shift = random () % 11;
+      size_t rel = random () % ((2 << (shift + 1)) * 64);
+      size_t idx = MIN ((2 << shift) * 64 + rel, BUF1PAGES * page_size - 2);
+      size_t len = random () % (sizeof (tmpbuf) - 1) + 1;
+      len = MIN (len, BUF1PAGES * page_size - idx - 1);
+      memcpy (tmpbuf, buf1 + idx, len);
+      for (size_t i = random () % len / 2 + 1; i > 0; --i)
+	{
+	  size_t off = random () % len;
+	  char ch = '0' + random () % 10;
+
+	  buf1[idx + off] = ch;
+	}
+
+      FOR_EACH_IMPL (impl, 0)
+	do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len,
+		     buf1 + idx);
+
+      memcpy (buf1 + idx, tmpbuf, len);
+    }
+}
+
+static void
+check1 (void)
+{
+
+  const char search_buf_data[5] = { 0x56, 0x34, 0x12, 0x78, 0x78 };
+  const char pattern[2] = { 0x78, 0x56 };
+  void *search_buf = (void *) buf1 + page_size - sizeof search_buf_data;
+  void *exp_result;
+
+  memcpy (search_buf, search_buf_data, sizeof search_buf_data);
+  exp_result = simple_memmem (search_buf, sizeof search_buf_data,
+			      pattern, sizeof pattern);
+  FOR_EACH_IMPL (impl, 0)
+    check_result (impl, search_buf, sizeof search_buf_data,
+		  pattern, sizeof pattern, exp_result);
+}
+
+static const char *const strs[] =
+  {
+    "00000", "00112233", "0123456789", "0000111100001111",
+    "00000111110000022222", "012345678901234567890",
+    "abc0", "aaaa0", "abcabc0"
+  };
+
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  check1 ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < BUF1PAGES * page_size; ++i)
+    buf1[i] = 60 + random () % 32;
+
+  for (i = 0; i < sizeof (strs) / sizeof (strs[0]); ++i)
+    for (size_t j = 0; j < 120; j += 7)
+      {
+	size_t len = strlen (strs[i]);
+
+	do_test (strs[i], len, j);
+      }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-memmove.c b/REORG.TODO/string/test-memmove.c
new file mode 100644
index 0000000000..51f79f6eb4
--- /dev/null
+++ b/REORG.TODO/string/test-memmove.c
@@ -0,0 +1,290 @@
+/* Test and measure memmove functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifdef TEST_BCOPY
+# define TEST_NAME "bcopy"
+#else
+# define TEST_NAME "memmove"
+#endif
+#include "test-string.h"
+
+char *simple_memmove (char *, const char *, size_t);
+
+#ifdef TEST_BCOPY
+typedef void (*proto_t) (const char *, char *, size_t);
+void simple_bcopy (const char *, char *, size_t);
+
+IMPL (simple_bcopy, 0)
+IMPL (bcopy, 1)
+
+void
+simple_bcopy (const char *src, char *dst, size_t n)
+{
+  simple_memmove (dst, src, n);
+}
+#else
+typedef char *(*proto_t) (char *, const char *, size_t);
+
+IMPL (simple_memmove, 0)
+IMPL (memmove, 1)
+#endif
+
+char *
+inhibit_loop_to_libcall
+simple_memmove (char *dst, const char *src, size_t n)
+{
+  char *ret = dst;
+  if (src < dst)
+    {
+      dst += n;
+      src += n;
+      while (n--)
+	*--dst = *--src;
+    }
+  else
+    while (n--)
+      *dst++ = *src++;
+  return ret;
+}
+
+static void
+do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src,
+	     size_t len)
+{
+  /* This also clears the destination buffer set by the previous run.  */
+  memcpy (src, orig_src, len);
+#ifdef TEST_BCOPY
+  CALL (impl, src, dst, len);
+#else
+  char *res;
+
+  res = CALL (impl, dst, src, len);
+  if (res != dst)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     res, dst);
+      ret = 1;
+      return;
+    }
+#endif
+
+  if (memcmp (dst, orig_src, len) != 0)
+    {
+      error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
+	     impl->name, dst, src);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len)
+{
+  size_t i, j;
+  char *s1, *s2;
+
+  align1 &= 63;
+  if (align1 + len >= page_size)
+    return;
+
+  align2 &= 63;
+  if (align2 + len >= page_size)
+    return;
+
+  s1 = (char *) (buf1 + align1);
+  s2 = (char *) (buf2 + align2);
+
+  for (i = 0, j = 1; i < len; i++, j += 23)
+    s1[i] = j;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s2, (char *) (buf2 + align1), s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, n, align1, align2, len, size;
+  size_t srcstart, srcend, dststart, dstend;
+  int c;
+  unsigned char *p1, *p2;
+#ifndef TEST_BCOPY
+  unsigned char *res;
+#endif
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      if ((random () & 255) == 0)
+	size = 65536;
+      else
+	size = 512;
+      if (size > page_size)
+	size = page_size;
+      if ((random () & 3) == 0)
+	{
+	  len = random () & (size - 1);
+	  align1 = size - len - (random () & 31);
+	  align2 = size - len - (random () & 31);
+	  if (align1 > size)
+	    align1 = 0;
+	  if (align2 > size)
+	    align2 = 0;
+	}
+      else
+	{
+	  align1 = random () & (size / 2 - 1);
+	  align2 = random () & (size / 2 - 1);
+	  len = random () & (size - 1);
+	  if (align1 + len > size)
+	    align1 = size - len;
+	  if (align2 + len > size)
+	    align2 = size - len;
+	}
+
+      p1 = buf1 + page_size - size;
+      p2 = buf2 + page_size - size;
+      c = random () & 255;
+      srcend = align1 + len + 256;
+      if (srcend > size)
+	srcend = size;
+      if (align1 > 256)
+	srcstart = align1 - 256;
+      else
+	srcstart = 0;
+      for (i = srcstart; i < srcend; ++i)
+	p1[i] = random () & 255;
+      dstend = align2 + len + 256;
+      if (dstend > size)
+	dstend = size;
+      if (align2 > 256)
+	dststart = align2 - 256;
+      else
+	dststart = 0;
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  memset (p2 + dststart, c, dstend - dststart);
+	  memcpy (p2 + srcstart, p1 + srcstart, srcend - srcstart);
+#ifdef TEST_BCOPY
+	  CALL (impl, (char *) (p2 + align1), (char *) (p2 + align2), len);
+#else
+	  res = (unsigned char *) CALL (impl,
+					(char *) (p2 + align2),
+					(char *) (p2 + align1), len);
+	  if (res != p2 + align2)
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
+		     n, impl->name, align1, align2, len, res, p2 + align2);
+	      ret = 1;
+	    }
+#endif
+	  if (memcmp (p1 + align1, p2 + align2, len))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	    }
+	  for (i = dststart; i < dstend; ++i)
+	    {
+	      if (i >= align2 && i < align2 + len)
+		{
+		  i = align2 + len - 1;
+		  continue;
+		}
+	      if (i >= srcstart && i < srcend)
+		{
+		  i = srcend - 1;
+		  continue;
+		}
+	      if (p2[i] != c)
+		{
+		  error (0, 0, "Iteration %zd - garbage in memset area, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+
+	  if (srcstart < align2
+	      && memcmp (p2 + srcstart, p1 + srcstart,
+			 (srcend > align2 ? align2 : srcend) - srcstart))
+	    {
+	      error (0, 0, "Iteration %zd - garbage before dst, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	      break;
+	    }
+
+	  i = srcstart > align2 + len ? srcstart : align2 + len;
+	  if (srcend > align2 + len
+	      && memcmp (p2 + i, p1 + i, srcend - i))
+	    {
+	      error (0, 0, "Iteration %zd - garbage after dst, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	      break;
+	    }
+	}
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < 14; ++i)
+    {
+      do_test (0, 32, 1 << i);
+      do_test (32, 0, 1 << i);
+      do_test (0, i, 1 << i);
+      do_test (i, 0, 1 << i);
+    }
+
+  for (i = 0; i < 32; ++i)
+    {
+      do_test (0, 32, i);
+      do_test (32, 0, i);
+      do_test (0, i, i);
+      do_test (i, 0, i);
+    }
+
+  for (i = 3; i < 32; ++i)
+    {
+      if ((i & (i - 1)) == 0)
+	continue;
+      do_test (0, 32, 16 * i);
+      do_test (32, 0, 16 * i);
+      do_test (0, i, 16 * i);
+      do_test (i, 0, 16 * i);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-mempcpy.c b/REORG.TODO/string/test-mempcpy.c
new file mode 100644
index 0000000000..364a811c62
--- /dev/null
+++ b/REORG.TODO/string/test-mempcpy.c
@@ -0,0 +1,38 @@
+/* Test and measure mempcpy functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define MEMCPY_RESULT(dst, len) (dst) + (len)
+#define TEST_MAIN
+#define TEST_NAME "mempcpy"
+#include "test-string.h"
+
+char *simple_mempcpy (char *, const char *, size_t);
+
+IMPL (simple_mempcpy, 0)
+IMPL (mempcpy, 1)
+
+char *
+simple_mempcpy (char *dst, const char *src, size_t n)
+{
+  while (n--)
+    *dst++ = *src++;
+  return dst;
+}
+
+#include "test-memcpy.c"
diff --git a/REORG.TODO/string/test-memrchr.c b/REORG.TODO/string/test-memrchr.c
new file mode 100644
index 0000000000..15483f5cb5
--- /dev/null
+++ b/REORG.TODO/string/test-memrchr.c
@@ -0,0 +1,186 @@
+/* Test and measure memrchr functions.
+   Copyright (C) 2013-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#define TEST_NAME "memrchr"
+#include "test-string.h"
+
+typedef char *(*proto_t) (const char *, int, size_t);
+char *simple_memrchr (const char *, int, size_t);
+
+IMPL (simple_memrchr, 0)
+IMPL (memrchr, 1)
+
+char *
+simple_memrchr (const char *s, int c, size_t n)
+{
+  s = s + n;
+  while (n--)
+    if (*--s == (char) c)
+      return (char *) s;
+  return NULL;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res)
+{
+  char *res = CALL (impl, s, c, n);
+  if (res != exp_res)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     res, exp_res);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align, size_t pos, size_t len, int seek_char)
+{
+  size_t i;
+  char *result;
+
+  align &= 7;
+  if (align + len >= page_size)
+    return;
+
+  for (i = 0; i < len; ++i)
+    {
+      buf1[align + i] = 1 + 23 * i % 127;
+      if (buf1[align + i] == seek_char)
+        buf1[align + i] = seek_char + 1;
+    }
+  buf1[align + len] = 0;
+
+  if (pos < len)
+    {
+      buf1[align + pos] = seek_char;
+      buf1[align + len] = -seek_char;
+      result = (char *) (buf1 + align + pos);
+    }
+  else
+    {
+      result = NULL;
+      buf1[align + len] = seek_char;
+    }
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, (char *) (buf1 + align), seek_char, len, result);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align, pos, len;
+  int seek_char;
+  char *result;
+  unsigned char *p = buf1 + page_size - 512;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align = random () & 15;
+      pos = random () & 511;
+      if (pos + align >= 512)
+	pos = 511 - align - (random () & 7);
+      len = random () & 511;
+      if (pos >= len)
+	len = pos + (random () & 7);
+      if (len + align >= 512)
+        len = 512 - align - (random () & 7);
+      seek_char = random () & 255;
+      j = len + align + 64;
+      if (j > 512)
+        j = 512;
+
+      for (i = 0; i < j; i++)
+	{
+	  if (i == pos + align)
+	    p[i] = seek_char;
+	  else
+	    {
+	      p[i] = random () & 255;
+	      if (p[i] == seek_char)
+		p[i] = seek_char + 13;
+	    }
+	}
+
+      if (pos < len)
+	result = (char *) (p + pos + align);
+      else
+	result = NULL;
+
+      FOR_EACH_IMPL (impl, 1)
+	if (CALL (impl, (char *) (p + align), seek_char, len) != result)
+	  {
+	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
+		   n, impl->name, align, seek_char, len, pos,
+		   CALL (impl, (char *) (p + align), seek_char, len),
+		   result, p);
+	    ret = 1;
+	  }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%20s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      /* Test len == 0.  */
+      do_test (i, i, 0, 0);
+      do_test (i, i, 0, 23);
+
+      do_test (0, 16 << i, 2048, 23);
+      do_test (i, 64, 256, 23);
+      do_test (0, 16 << i, 2048, 0);
+      do_test (i, 64, 256, 0);
+
+      do_test (0, i, 256, 23);
+      do_test (0, i, 256, 0);
+      do_test (i, i, 256, 23);
+      do_test (i, i, 256, 0);
+
+    }
+  for (i = 1; i < 32; ++i)
+    {
+      do_test (0, i, i + 1, 23);
+      do_test (0, i, i + 1, 0);
+      do_test (i, i, i + 1, 23);
+      do_test (i, i, i + 1, 0);
+
+      do_test (0, 1, i + 1, 23);
+      do_test (0, 2, i + 1, 0);
+      do_test (i, 1, i + 1, 23);
+      do_test (i, 2, i + 1, 0);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-memset.c b/REORG.TODO/string/test-memset.c
new file mode 100644
index 0000000000..ca1bfe1e3b
--- /dev/null
+++ b/REORG.TODO/string/test-memset.c
@@ -0,0 +1,267 @@
+/* Test memset functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifdef TEST_BZERO
+# ifdef TEST_EXPLICIT_BZERO
+#  define TEST_NAME "explicit_bzero"
+# else
+#  define TEST_NAME "bzero"
+# endif
+#else
+# ifndef WIDE
+#  define TEST_NAME "memset"
+# else
+#  define TEST_NAME "wmemset"
+# endif /* WIDE */
+#endif /* !TEST_BZERO */
+#define MIN_PAGE_SIZE 131072
+#include "test-string.h"
+
+#ifndef WIDE
+# define MEMSET memset
+# define CHAR char
+# define UCHAR unsigned char
+# define SIMPLE_MEMSET simple_memset
+# define MEMCMP memcmp
+# define BIG_CHAR CHAR_MAX
+#else
+# include <wchar.h>
+# define MEMSET wmemset
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define SIMPLE_MEMSET simple_wmemset
+# define MEMCMP wmemcmp
+# define BIG_CHAR WCHAR_MAX
+#endif /* WIDE */
+
+CHAR *SIMPLE_MEMSET (CHAR *, int, size_t);
+
+#ifdef TEST_BZERO
+typedef void (*proto_t) (char *, size_t);
+void simple_bzero (char *, size_t);
+void builtin_bzero (char *, size_t);
+
+IMPL (simple_bzero, 0)
+IMPL (builtin_bzero, 0)
+#ifdef TEST_EXPLICIT_BZERO
+IMPL (explicit_bzero, 1)
+#else
+IMPL (bzero, 1)
+#endif
+
+void
+simple_bzero (char *s, size_t n)
+{
+  SIMPLE_MEMSET (s, 0, n);
+}
+
+void
+builtin_bzero (char *s, size_t n)
+{
+  __builtin_bzero (s, n);
+}
+#else
+typedef CHAR *(*proto_t) (CHAR *, int, size_t);
+
+IMPL (SIMPLE_MEMSET, 0)
+# ifndef WIDE
+char *builtin_memset (char *, int, size_t);
+IMPL (builtin_memset, 0)
+# endif /* !WIDE */
+IMPL (MEMSET, 1)
+
+# ifndef WIDE
+char *
+builtin_memset (char *s, int c, size_t n)
+{
+  return __builtin_memset (s, c, n);
+}
+# endif /* !WIDE */
+#endif /* !TEST_BZERO */
+
+CHAR *
+inhibit_loop_to_libcall
+SIMPLE_MEMSET (CHAR *s, int c, size_t n)
+{
+  CHAR *r = s, *end = s + n;
+  while (r < end)
+    *r++ = c;
+  return s;
+}
+
+static void
+do_one_test (impl_t *impl, CHAR *s, int c __attribute ((unused)), size_t n)
+{
+  CHAR tstbuf[n];
+#ifdef TEST_BZERO
+  simple_bzero (tstbuf, n);
+  CALL (impl, s, n);
+  if (memcmp (s, tstbuf, n) != 0)
+#else
+  CHAR *res = CALL (impl, s, c, n);
+  if (res != s
+      || SIMPLE_MEMSET (tstbuf, c, n) != tstbuf
+      || MEMCMP (s, tstbuf, n) != 0)
+#endif /* !TEST_BZERO */
+    {
+      error (0, 0, "Wrong result in function %s", impl->name);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align, int c, size_t len)
+{
+  align &= 7;
+  if ((align + len) * sizeof (CHAR) > page_size)
+    return;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, (CHAR *) (buf1) + align, c, len);
+}
+
+#ifndef TEST_BZERO
+static void
+do_random_tests (void)
+{
+  size_t i, j, k, n, align, len, size;
+  int c, o;
+  UCHAR *p, *res;
+  UCHAR *p2 = (UCHAR *) buf2;
+
+  for (i = 0; i < 65536 / sizeof (CHAR); ++i)
+    p2[i] = random () & BIG_CHAR;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      if ((random () & 31) == 0)
+	size = 65536 / sizeof (CHAR);
+      else
+	size = 512;
+      p = (UCHAR *) (buf1 + page_size) - size;
+      len = random () & (size - 1);
+      align = size - len - (random () & 31);
+      if (align > size)
+	align = size - len;
+      if ((random () & 7) == 0)
+	align &= ~63;
+      if ((random () & 7) == 0)
+	c = 0;
+      else
+	c = random () & BIG_CHAR;
+      o = random () & BIG_CHAR;
+      if (o == c)
+	o = (c + 1) & BIG_CHAR;
+      j = len + align + 128;
+      if (j > size)
+	j = size;
+      if (align >= 128)
+	k = align - 128;
+      else
+	k = 0;
+      for (i = k; i < align; ++i)
+	p[i] = o;
+      for (i = align + len; i < j; ++i)
+	p[i] = o;
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  for (i = 0; i < len; ++i)
+	    {
+	      p[i + align] = p2[i];
+	      if (p[i + align] == c)
+		p[i + align] = o;
+	    }
+	  res = (UCHAR *) CALL (impl, (CHAR *) p + align, c, len);
+	  if (res != p + align)
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd) %p != %p",
+		     n, impl->name, align, c, len, res, p + align);
+	      ret = 1;
+	    }
+	  for (i = k; i < align; ++i)
+	    if (p[i] != o)
+	      {
+		error (0, 0, "Iteration %zd - garbage before %s (%zd, %d, %zd)",
+		       n, impl->name, align, c, len);
+		ret = 1;
+		break;
+	      }
+	  for (; i < align + len; ++i)
+	    if (p[i] != c)
+	      {
+		error (0, 0, "Iteration %zd - not cleared correctly %s (%zd, %d, %zd)",
+		       n, impl->name, align, c, len);
+		ret = 1;
+		break;
+	      }
+	  for (; i < j; ++i)
+	    if (p[i] != o)
+	      {
+		error (0, 0, "Iteration %zd - garbage after %s (%zd, %d, %zd)",
+		       n, impl->name, align, c, len);
+		ret = 1;
+		break;
+	      }
+	}
+    }
+}
+#endif /* !TEST_BZERO */
+
+int
+test_main (void)
+{
+  size_t i;
+  int c = 0;
+
+  test_init ();
+
+  printf ("%24s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+#ifndef TEST_BZERO
+  for (c = -65; c <= 130; c += 65)
+#endif
+    {
+      for (i = 0; i < 18; ++i)
+	do_test (0, c, 1 << i);
+      for (i = 1; i < 32; ++i)
+	{
+	  do_test (i, c, i);
+	  if (i & (i - 1))
+	    do_test (0, c, i);
+	}
+      do_test (1, c, 14);
+      do_test (3, c, 1024);
+      do_test (4, c, 64);
+      do_test (2, c, 25);
+    }
+
+#ifndef TEST_BZERO
+  do_random_tests ();
+#endif
+
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-rawmemchr.c b/REORG.TODO/string/test-rawmemchr.c
new file mode 100644
index 0000000000..2a53e71026
--- /dev/null
+++ b/REORG.TODO/string/test-rawmemchr.c
@@ -0,0 +1,165 @@
+/* Test and measure memchr functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+
+#define TEST_MAIN
+#define TEST_NAME "rawmemchr"
+#include "test-string.h"
+
+typedef char *(*proto_t) (const char *, int);
+char *simple_rawmemchr (const char *, int);
+
+IMPL (simple_rawmemchr, 0)
+IMPL (rawmemchr, 1)
+
+char *
+simple_rawmemchr (const char *s, int c)
+{
+  while (1)
+    if (*s++ == (char) c)
+      return (char *) s - 1;
+  return NULL;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s, int c, char *exp_res)
+{
+  char *res = CALL (impl, s, c);
+  if (res != exp_res)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     res, exp_res);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align, size_t pos, size_t len, int seek_char)
+{
+  size_t i;
+  char *result;
+
+  align &= 7;
+  if (align + len >= page_size)
+    return;
+
+  for (i = 0; i < len; ++i)
+    {
+      buf1[align + i] = 1 + 23 * i % 127;
+      if (buf1[align + i] == seek_char)
+	buf1[align + i] = seek_char + 1;
+    }
+  buf1[align + len] = 0;
+
+  assert (pos < len);
+
+  buf1[align + pos] = seek_char;
+  buf1[align + len] = -seek_char;
+  result = (char *) (buf1 + align + pos);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, (char *) (buf1 + align), seek_char, result);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align, pos, len;
+  int seek_char;
+  char *result;
+  unsigned char *p = buf1 + page_size - 512;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align = random () & 15;
+      pos = random () & 511;
+      if (pos + align >= 512)
+	pos = 511 - align - (random () & 7);
+      len = random () & 511;
+      if (len + align >= 512)
+	len = 512 - align - (random () & 7);
+      if (pos >= len)
+	continue;
+      seek_char = random () & 255;
+      j = len + align + 64;
+      if (j > 512)
+	j = 512;
+
+      for (i = 0; i < j; i++)
+	{
+	  if (i == pos + align)
+	    p[i] = seek_char;
+	  else
+	    {
+	      p[i] = random () & 255;
+	      if (i < pos + align && p[i] == seek_char)
+		p[i] = seek_char + 13;
+	    }
+	}
+
+      assert (pos < len);
+      size_t r = random ();
+      if ((r & 31) == 0)
+	len = ~(uintptr_t) (p + align) - ((r >> 5) & 31);
+      result = (char *) (p + pos + align);
+
+      FOR_EACH_IMPL (impl, 1)
+	if (CALL (impl, (char *) (p + align), seek_char) != result)
+	  {
+	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
+		   n, impl->name, align, seek_char, len, pos,
+		   CALL (impl, (char *) (p + align), seek_char),
+		   result, p);
+	    ret = 1;
+	  }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%20s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 7; ++i)
+    {
+      do_test (0, 16 << i, 2048, 23);
+      do_test (i, 64, 256, 23);
+      do_test (0, 16 << i, 2048, 0);
+      do_test (i, 64, 256, 0);
+    }
+  for (i = 1; i < 32; ++i)
+    {
+      do_test (0, i, i + 1, 23);
+      do_test (0, i, i + 1, 0);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-stpcpy.c b/REORG.TODO/string/test-stpcpy.c
new file mode 100644
index 0000000000..5e31abf962
--- /dev/null
+++ b/REORG.TODO/string/test-stpcpy.c
@@ -0,0 +1,52 @@
+/* Test stpcpy functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define STRCPY_RESULT(dst, len) ((dst) + (len))
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "stpcpy"
+#else
+# define TEST_NAME "wcpcpy"
+#endif /* !WIDE */
+#include "test-string.h"
+#ifndef WIDE
+# define CHAR char
+# define SIMPLE_STPCPY simple_stpcpy
+# define STPCPY stpcpy
+#else
+# include <wchar.h>
+# define CHAR wchar_t
+# define SIMPLE_STPCPY simple_wcpcpy
+# define STPCPY wcpcpy
+#endif /* !WIDE */
+
+CHAR *SIMPLE_STPCPY (CHAR *, const CHAR *);
+
+IMPL (SIMPLE_STPCPY, 0)
+IMPL (STPCPY, 1)
+
+CHAR *
+SIMPLE_STPCPY (CHAR *dst, const CHAR *src)
+{
+  while ((*dst++ = *src++) != '\0');
+  return dst - 1;
+}
+
+#undef CHAR
+#include "test-strcpy.c"
diff --git a/REORG.TODO/string/test-stpncpy.c b/REORG.TODO/string/test-stpncpy.c
new file mode 100644
index 0000000000..5b26ae5e4f
--- /dev/null
+++ b/REORG.TODO/string/test-stpncpy.c
@@ -0,0 +1,79 @@
+/* Test and measure stpncpy functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define STRNCPY_RESULT(dst, len, n) ((dst) + ((len) > (n) ? (n) : (len)))
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "stpncpy"
+#else
+# define TEST_NAME "wcpncpy"
+#endif /* WIDE */
+#include "test-string.h"
+#ifndef WIDE
+# define CHAR char
+# define SIMPLE_STPNCPY simple_stpncpy
+# define STUPID_STPNCPY stupid_stpncpy
+# define STPNCPY stpncpy
+# define STRNLEN strnlen
+#else
+# include <wchar.h>
+# define CHAR wchar_t
+# define SIMPLE_STPNCPY simple_wcpncpy
+# define STUPID_STPNCPY stupid_wcpncpy
+# define STPNCPY wcpncpy
+# define STRNLEN wcsnlen
+#endif /* WIDE */
+
+CHAR *SIMPLE_STPNCPY (CHAR *, const CHAR *, size_t);
+CHAR *STUPID_STPNCPY (CHAR *, const CHAR *, size_t);
+
+IMPL (STUPID_STPNCPY, 0)
+IMPL (SIMPLE_STPNCPY, 0)
+IMPL (STPNCPY, 1)
+
+CHAR *
+SIMPLE_STPNCPY (CHAR *dst, const CHAR *src, size_t n)
+{
+  while (n--)
+    if ((*dst++ = *src++) == '\0')
+      {
+	size_t i;
+
+	for (i = 0; i < n; ++i)
+	  dst[i] = '\0';
+	return dst - 1;
+      }
+  return dst;
+}
+
+CHAR *
+STUPID_STPNCPY (CHAR *dst, const CHAR *src, size_t n)
+{
+  size_t nc = STRNLEN (src, n);
+  size_t i;
+
+  for (i = 0; i < nc; ++i)
+    dst[i] = src[i];
+  for (; i < n; ++i)
+    dst[i] = '\0';
+  return dst + nc;
+}
+
+#undef CHAR
+#include "test-strncpy.c"
diff --git a/REORG.TODO/string/test-strcasecmp.c b/REORG.TODO/string/test-strcasecmp.c
new file mode 100644
index 0000000000..9c333f0072
--- /dev/null
+++ b/REORG.TODO/string/test-strcasecmp.c
@@ -0,0 +1,270 @@
+/* Test and measure strcasecmp functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <locale.h>
+#include <ctype.h>
+#define TEST_MAIN
+#define TEST_NAME "strcasecmp"
+#include "test-string.h"
+
+typedef int (*proto_t) (const char *, const char *);
+static int simple_strcasecmp (const char *, const char *);
+static int stupid_strcasecmp (const char *, const char *);
+
+IMPL (stupid_strcasecmp, 0)
+IMPL (simple_strcasecmp, 0)
+IMPL (strcasecmp, 1)
+
+static int
+simple_strcasecmp (const char *s1, const char *s2)
+{
+  int ret;
+
+  while ((ret = ((unsigned char) tolower (*s1)
+		 - (unsigned char) tolower (*s2))) == 0
+	 && *s1++)
+    ++s2;
+  return ret;
+}
+
+static int
+stupid_strcasecmp (const char *s1, const char *s2)
+{
+  size_t ns1 = strlen (s1) + 1, ns2 = strlen (s2) + 1;
+  size_t n = ns1 < ns2 ? ns1 : ns2;
+  int ret = 0;
+
+  while (n--)
+    {
+      if ((ret = ((unsigned char) tolower (*s1)
+		  - (unsigned char) tolower (*s2))) != 0)
+	break;
+      ++s1;
+      ++s2;
+    }
+  return ret;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result)
+{
+  int result = CALL (impl, s1, s2);
+  if ((exp_result == 0 && result != 0)
+      || (exp_result < 0 && result >= 0)
+      || (exp_result > 0 && result <= 0))
+    {
+      error (0, 0, "Wrong result in function %s %d %d", impl->name,
+	     result, exp_result);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char,
+	 int exp_result)
+{
+  size_t i;
+  char *s1, *s2;
+
+  if (len == 0)
+    return;
+
+  align1 &= 7;
+  if (align1 + len + 1 >= page_size)
+    return;
+
+  align2 &= 7;
+  if (align2 + len + 1 >= page_size)
+    return;
+
+  s1 = (char *) (buf1 + align1);
+  s2 = (char *) (buf2 + align2);
+
+  for (i = 0; i < len; i++)
+    {
+      s1[i] = toupper (1 + 23 * i % max_char);
+      s2[i] = tolower (s1[i]);
+    }
+
+  s1[len] = s2[len] = 0;
+  s1[len + 1] = 23;
+  s2[len + 1] = 24 + exp_result;
+  if ((s2[len - 1] == 'z' && exp_result == -1)
+      || (s2[len - 1] == 'a' && exp_result == 1))
+    s1[len - 1] += exp_result;
+  else
+    s2[len - 1] -= exp_result;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, s2, exp_result);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, pos, len1, len2;
+  int result;
+  long r;
+  unsigned char *p1 = buf1 + page_size - 512;
+  unsigned char *p2 = buf2 + page_size - 512;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align1 = random () & 31;
+      if (random () & 1)
+	align2 = random () & 31;
+      else
+	align2 = align1 + (random () & 24);
+      pos = random () & 511;
+      j = align1 > align2 ? align1 : align2;
+      if (pos + j >= 511)
+	pos = 510 - j - (random () & 7);
+      len1 = random () & 511;
+      if (pos >= len1 && (random () & 1))
+	len1 = pos + (random () & 7);
+      if (len1 + j >= 512)
+	len1 = 511 - j - (random () & 7);
+      if (pos >= len1)
+	len2 = len1;
+      else
+	len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
+      j = (pos > len2 ? pos : len2) + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; ++i)
+	{
+	  p1[i] = tolower (random () & 255);
+	  if (i < len1 + align1 && !p1[i])
+	    {
+	      p1[i] = tolower (random () & 255);
+	      if (!p1[i])
+		p1[i] = tolower (1 + (random () & 127));
+	    }
+	}
+      for (i = 0; i < j; ++i)
+	{
+	  p2[i] = toupper (random () & 255);
+	  if (i < len2 + align2 && !p2[i])
+	    {
+	      p2[i] = toupper (random () & 255);
+	      if (!p2[i])
+		toupper (p2[i] = 1 + (random () & 127));
+	    }
+	}
+
+      result = 0;
+      memcpy (p2 + align2, p1 + align1, pos);
+      if (pos < len1)
+	{
+	  if (tolower (p2[align2 + pos]) == p1[align1 + pos])
+	    {
+	      p2[align2 + pos] = toupper (random () & 255);
+	      if (tolower (p2[align2 + pos]) == p1[align1 + pos])
+		p2[align2 + pos] = toupper (p1[align1 + pos]
+					    + 3 + (random () & 127));
+	    }
+
+	  if (p1[align1 + pos] < tolower (p2[align2 + pos]))
+	    result = -1;
+	  else
+	    result = 1;
+	}
+      p1[len1 + align1] = 0;
+      p2[len2 + align2] = 0;
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2));
+	  /* Test whether on 64-bit architectures where ABI requires
+	     callee to promote has the promotion been done.  */
+	  asm ("" : "=g" (r) : "0" (r));
+	  if ((r == 0 && result)
+	      || (r < 0 && result >= 0)
+	      || (r > 0 && result <= 0))
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p",
+		     n, impl->name, align1, align2, len1, len2, pos, r, result, p1, p2);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+static void
+test_locale (const char *locale)
+{
+  size_t i;
+
+  if (setlocale (LC_CTYPE, locale) == NULL)
+    {
+      error (0, 0, "cannot set locale \"%s\"", locale);
+      ret = 1;
+    }
+
+  printf ("%-23s", locale);
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 16; ++i)
+    {
+      do_test (i, i, i, 127, 0);
+      do_test (i, i, i, 127, 1);
+      do_test (i, i, i, 127, -1);
+    }
+
+  for (i = 1; i < 10; ++i)
+    {
+      do_test (0, 0, 2 << i, 127, 0);
+      do_test (0, 0, 2 << i, 254, 0);
+      do_test (0, 0, 2 << i, 127, 1);
+      do_test (0, 0, 2 << i, 254, 1);
+      do_test (0, 0, 2 << i, 127, -1);
+      do_test (0, 0, 2 << i, 254, -1);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, 127, 0);
+      do_test (2 * i, i, 8 << i, 254, 0);
+      do_test (i, 2 * i, 8 << i, 127, 1);
+      do_test (2 * i, i, 8 << i, 254, 1);
+      do_test (i, 2 * i, 8 << i, 127, -1);
+      do_test (2 * i, i, 8 << i, 254, -1);
+    }
+
+  do_random_tests ();
+}
+
+int
+test_main (void)
+{
+  test_init ();
+
+  test_locale ("C");
+  test_locale ("en_US.ISO-8859-1");
+  test_locale ("en_US.UTF-8");
+  test_locale ("tr_TR.ISO-8859-9");
+  test_locale ("tr_TR.UTF-8");
+
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strcasestr.c b/REORG.TODO/string/test-strcasestr.c
new file mode 100644
index 0000000000..abb3916732
--- /dev/null
+++ b/REORG.TODO/string/test-strcasestr.c
@@ -0,0 +1,194 @@
+/* Test and measure strcasestr functions.
+   Copyright (C) 2010-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2010.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#define TEST_NAME "strcasestr"
+#include "test-string.h"
+
+
+#define STRCASESTR simple_strcasestr
+#define NO_ALIAS
+#define __strncasecmp strncasecmp
+#include "strcasestr.c"
+
+
+static char *
+stupid_strcasestr (const char *s1, const char *s2)
+{
+  ssize_t s1len = strlen (s1);
+  ssize_t s2len = strlen (s2);
+
+  if (s2len > s1len)
+    return NULL;
+
+  for (ssize_t i = 0; i <= s1len - s2len; ++i)
+    {
+      size_t j;
+      for (j = 0; j < s2len; ++j)
+	if (tolower (s1[i + j]) != tolower (s2[j]))
+	  break;
+      if (j == s2len)
+	return (char *) s1 + i;
+    }
+
+  return NULL;
+}
+
+
+typedef char *(*proto_t) (const char *, const char *);
+
+IMPL (stupid_strcasestr, 0)
+IMPL (simple_strcasestr, 0)
+IMPL (strcasestr, 1)
+
+
+static int
+check_result (impl_t *impl, const char *s1, const char *s2,
+	      char *exp_result)
+{
+  char *result = CALL (impl, s1, s2);
+  if (result != exp_result)
+    {
+      error (0, 0, "Wrong result in function %s %s %s", impl->name,
+	     result, exp_result);
+      ret = 1;
+      return -1;
+    }
+  return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+{
+  if (check_result (impl, s1, s2, exp_result) < 0)
+    return;
+}
+
+
+static void
+do_test (size_t align1, size_t align2, size_t len1, size_t len2,
+	 int fail)
+{
+  char *s1 = (char *) (buf1 + align1);
+  char *s2 = (char *) (buf2 + align2);
+
+  static const char d[] = "1234567890abcxyz";
+#define dl (sizeof (d) - 1)
+  char *ss2 = s2;
+  for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
+    {
+      size_t t = l > dl ? dl : l;
+      ss2 = mempcpy (ss2, d, t);
+    }
+  s2[len2] = '\0';
+
+  if (fail)
+    {
+      char *ss1 = s1;
+      for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
+	{
+	  size_t t = l > dl ? dl : l;
+	  memcpy (ss1, d, t);
+	  ++ss1[len2 > 7 ? 7 : len2 - 1];
+	  ss1 += t;
+	}
+    }
+  else
+    {
+      memset (s1, '0', len1);
+      for (size_t i = 0; i < len2; ++i)
+	s1[len1 - len2 + i] = toupper (s2[i]);
+    }
+  s1[len1] = '\0';
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2);
+}
+
+static void
+check1 (void)
+{
+  const char s1[] = "AOKB";
+  const char s2[] = "OK";
+  char *exp_result;
+
+  exp_result = stupid_strcasestr (s1, s2);
+  FOR_EACH_IMPL (impl, 0)
+    check_result (impl, s1, s2, exp_result);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  check1 ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (size_t klen = 2; klen < 32; ++klen)
+    for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
+      {
+	do_test (0, 0, hlen, klen, 0);
+	do_test (0, 0, hlen, klen, 1);
+	do_test (0, 3, hlen, klen, 0);
+	do_test (0, 3, hlen, klen, 1);
+	do_test (0, 9, hlen, klen, 0);
+	do_test (0, 9, hlen, klen, 1);
+	do_test (0, 15, hlen, klen, 0);
+	do_test (0, 15, hlen, klen, 1);
+
+	do_test (3, 0, hlen, klen, 0);
+	do_test (3, 0, hlen, klen, 1);
+	do_test (3, 3, hlen, klen, 0);
+	do_test (3, 3, hlen, klen, 1);
+	do_test (3, 9, hlen, klen, 0);
+	do_test (3, 9, hlen, klen, 1);
+	do_test (3, 15, hlen, klen, 0);
+	do_test (3, 15, hlen, klen, 1);
+
+	do_test (9, 0, hlen, klen, 0);
+	do_test (9, 0, hlen, klen, 1);
+	do_test (9, 3, hlen, klen, 0);
+	do_test (9, 3, hlen, klen, 1);
+	do_test (9, 9, hlen, klen, 0);
+	do_test (9, 9, hlen, klen, 1);
+	do_test (9, 15, hlen, klen, 0);
+	do_test (9, 15, hlen, klen, 1);
+
+	do_test (15, 0, hlen, klen, 0);
+	do_test (15, 0, hlen, klen, 1);
+	do_test (15, 3, hlen, klen, 0);
+	do_test (15, 3, hlen, klen, 1);
+	do_test (15, 9, hlen, klen, 0);
+	do_test (15, 9, hlen, klen, 1);
+	do_test (15, 15, hlen, klen, 0);
+	do_test (15, 15, hlen, klen, 1);
+      }
+
+  do_test (0, 0, page_size - 1, 16, 0);
+  do_test (0, 0, page_size - 1, 16, 1);
+
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strcat.c b/REORG.TODO/string/test-strcat.c
new file mode 100644
index 0000000000..01d180eb50
--- /dev/null
+++ b/REORG.TODO/string/test-strcat.c
@@ -0,0 +1,272 @@
+/* Test strcat functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "strcat"
+#else
+# define TEST_NAME "wcscat"
+#endif /* WIDE */
+#include "test-string.h"
+
+#ifndef WIDE
+# define STRCAT strcat
+# define CHAR char
+# define UCHAR unsigned char
+# define sfmt "s"
+# define SIMPLE_STRCAT simple_strcat
+# define STRLEN strlen
+# define STRCMP strcmp
+# define MEMSET memset
+# define MEMCPY memcpy
+# define MEMCMP memcmp
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+#else
+# include <wchar.h>
+# define STRCAT wcscat
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define sfmt "ls"
+# define SIMPLE_STRCAT simple_wcscat
+# define STRLEN wcslen
+# define STRCMP wcscmp
+# define MEMSET wmemset
+# define MEMCPY wmemcpy
+# define MEMCMP wmemcmp
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+#endif /* WIDE */
+
+typedef CHAR *(*proto_t) (CHAR *, const CHAR *);
+CHAR *SIMPLE_STRCAT (CHAR *, const CHAR *);
+
+IMPL (SIMPLE_STRCAT, 0)
+IMPL (STRCAT, 1)
+
+CHAR *
+SIMPLE_STRCAT (CHAR *dst, const CHAR *src)
+{
+  CHAR *ret = dst;
+  while (*dst++ != '\0');
+  --dst;
+  while ((*dst++ = *src++) != '\0');
+  return ret;
+}
+
+static void
+do_one_test (impl_t *impl, CHAR *dst, const CHAR *src)
+{
+  size_t k = STRLEN (dst);
+  if (CALL (impl, dst, src) != dst)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     CALL (impl, dst, src), dst);
+      ret = 1;
+      return;
+    }
+
+  if (STRCMP (dst + k, src) != 0)
+    {
+      error (0, 0, "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
+	     impl->name, dst, src);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len1, size_t len2, int max_char)
+{
+  size_t i;
+  CHAR *s1, *s2;
+
+  align1 &= 7;
+  if ((align1 + len1) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len1 + len2) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+  s2 = (CHAR *) (buf2) + align2;
+
+  for (i = 0; i < len1; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len1] = '\0';
+
+  for (i = 0; i < len2; i++)
+    s2[i] = 32 + 23 * i % (max_char - 32);
+
+  FOR_EACH_IMPL (impl, 0)
+    {
+      s2[len2] = '\0';
+      do_one_test (impl, s2, s1);
+    }
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len1, len2;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512;
+  UCHAR *p3 = (UCHAR *) buf1;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align1 = random () & 31;
+      if (random () & 1)
+	align2 = random () & 31;
+      else
+	align2 = align1 + (random () & 24);
+      len1 = random () & 511;
+      if (len1 + align2 > 512)
+	len2 = random () & 7;
+      else
+	len2 = (512 - len1 - align2) * (random () & (1024 * 1024 - 1))
+	       / (1024 * 1024);
+      j = align1;
+      if (align2 + len2 > j)
+	j = align2 + len2;
+      if (len1 + j >= 511)
+	len1 = 510 - j - (random () & 7);
+      if (len1 >= 512)
+	len1 = 0;
+      if (align1 + len1 < 512 - 8)
+	{
+	  j = 510 - align1 - len1 - (random () & 31);
+	  if (j > 0 && j < 512)
+	    align1 += j;
+	}
+      j = len1 + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len1 + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len1 + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+      for (i = 0; i < len2; i++)
+	{
+	  p3[i] = random () & BIG_CHAR;
+	  if (!p3[i])
+	    p3[i] = (random () & SMALL_CHAR) + 3;
+	}
+      p3[len2] = 0;
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  MEMSET (p2 - 64, '\1', align2 + 64);
+	  MEMSET (p2 + align2 + len2 + 1, '\1', 512 - align2 - len2 - 1);
+	  MEMCPY (p2 + align2, p3, len2 + 1);
+	  res = (UCHAR *) CALL (impl, (CHAR *) (p2 + align2),
+				(CHAR *) (p1 + align1));
+	  if (res != p2 + align2)
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd %zd) %p != %p",
+		     n, impl->name, align1, align2, len1, len2, res,
+		     p2 + align2);
+	      ret = 1;
+	    }
+	  for (j = 0; j < align2 + 64; ++j)
+	    {
+	      if (p2[j - 64] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len1, len2);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  if (MEMCMP (p2 + align2, p3, len2))
+	    {
+	      error (0, 0, "Iteration %zd - garbage in string before, %s (%zd, %zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len1, len2);
+	      ret = 1;
+	    }
+	  for (j = align2 + len1 + len2 + 1; j < 512; ++j)
+	    {
+	      if (p2[j] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len1, len2);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  if (MEMCMP (p1 + align1, p2 + align2 + len2, len1 + 1))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len1, len2);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, i, SMALL_CHAR);
+      do_test (0, 0, i, i, BIG_CHAR);
+      do_test (0, i, i, i, SMALL_CHAR);
+      do_test (i, 0, i, i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, 8 << i, SMALL_CHAR);
+      do_test (0, 0, 8 << i, 2 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, 2 << i, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, 1, SMALL_CHAR);
+      do_test (2 * i, i, 8 << i, 1, BIG_CHAR);
+      do_test (i, i, 8 << i, 10, SMALL_CHAR);
+      do_test (i, i, 8 << i, 10, BIG_CHAR);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strchr.c b/REORG.TODO/string/test-strchr.c
new file mode 100644
index 0000000000..de9a274f7b
--- /dev/null
+++ b/REORG.TODO/string/test-strchr.c
@@ -0,0 +1,296 @@
+/* Test STRCHR functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+   Added wcschr support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifndef WIDE
+# ifdef USE_FOR_STRCHRNUL
+#  define TEST_NAME "strchrnul"
+# else
+#  define TEST_NAME "strchr"
+# endif /* !USE_FOR_STRCHRNUL */
+#else
+# ifdef USE_FOR_STRCHRNUL
+#  define TEST_NAME "wcschrnul"
+# else
+#  define TEST_NAME "wcschr"
+# endif /* !USE_FOR_STRCHRNUL */
+#endif /* WIDE */
+#include "test-string.h"
+
+#ifndef WIDE
+# ifdef USE_FOR_STRCHRNUL
+#  define STRCHR strchrnul
+#  define stupid_STRCHR stupid_STRCHRNUL
+#  define simple_STRCHR simple_STRCHRNUL
+# else
+#  define STRCHR strchr
+# endif /* !USE_FOR_STRCHRNUL */
+# define STRLEN strlen
+# define CHAR char
+# define BIG_CHAR CHAR_MAX
+# define MIDDLE_CHAR 127
+# define SMALL_CHAR 23
+# define UCHAR unsigned char
+# define L(s) s
+#else
+# include <wchar.h>
+# ifdef USE_FOR_STRCHRNUL
+#  define STRCHR wcschrnul
+#  define stupid_STRCHR stupid_WCSCHRNUL
+#  define simple_STRCHR simple_WCSCHRNUL
+# else
+#  define STRCHR wcschr
+# endif /* !USE_FOR_STRCHRNUL */
+# define STRLEN wcslen
+# define CHAR wchar_t
+# define BIG_CHAR WCHAR_MAX
+# define MIDDLE_CHAR 1121
+# define SMALL_CHAR 851
+# define UCHAR wchar_t
+# define L(s) L ## s
+#endif /* WIDE */
+
+#ifdef USE_FOR_STRCHRNUL
+# define NULLRET(endptr) endptr
+#else
+# define NULLRET(endptr) NULL
+#endif /* !USE_FOR_STRCHRNUL */
+
+
+typedef CHAR *(*proto_t) (const CHAR *, int);
+
+CHAR *
+simple_STRCHR (const CHAR *s, int c)
+{
+  for (; *s != (CHAR) c; ++s)
+    if (*s == '\0')
+      return NULLRET ((CHAR *) s);
+  return (CHAR *) s;
+}
+
+CHAR *
+stupid_STRCHR (const CHAR *s, int c)
+{
+  size_t n = STRLEN (s) + 1;
+
+  while (n--)
+    if (*s++ == (CHAR) c)
+      return (CHAR *) s - 1;
+  return NULLRET ((CHAR *) s - 1);
+}
+
+IMPL (stupid_STRCHR, 0)
+IMPL (simple_STRCHR, 0)
+IMPL (STRCHR, 1)
+
+static int
+check_result (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
+{
+  CHAR *res = CALL (impl, s, c);
+  if (res != exp_res)
+    {
+      error (0, 0, "Wrong result in function %s %#x %p %p", impl->name,
+	     c, res, exp_res);
+      ret = 1;
+      return -1;
+    }
+  return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
+{
+  if (check_result (impl, s, c, exp_res) < 0)
+    return;
+}
+
+static void
+do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
+/* For wcschr: align here means align not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+{
+  size_t i;
+  CHAR *result;
+  CHAR *buf = (CHAR *) buf1;
+  align &= 15;
+  if ((align + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  for (i = 0; i < len; ++i)
+    {
+      buf[align + i] = 32 + 23 * i % max_char;
+      if (buf[align + i] == seek_char)
+	buf[align + i] = seek_char + 1;
+      else if (buf[align + i] == 0)
+	buf[align + i] = 1;
+    }
+  buf[align + len] = 0;
+
+  if (pos < len)
+    {
+      buf[align + pos] = seek_char;
+      result = buf + align + pos;
+    }
+  else if (seek_char == 0)
+    result = buf + align + len;
+  else
+    result = NULLRET (buf + align + len);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, buf + align, seek_char, result);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align, pos, len;
+  int seek_char;
+  CHAR *result;
+  UCHAR *p = (UCHAR *) (buf1 + page_size - 512 * sizeof (CHAR));
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* For wcschr: align here means align not in bytes, but in wchar_ts,
+	 in bytes it will equal to align * (sizeof (wchar_t)).  */
+      align = random () & 15;
+      pos = random () & 511;
+      seek_char = random () & 255;
+      if (pos + align >= 511)
+	pos = 510 - align - (random () & 7);
+      /* len for wcschr here isn't in bytes but it's number of wchar_t
+	 symbols.  */
+      len = random () & 511;
+      if ((pos == len && seek_char)
+	  || (pos > len && (random () & 1)))
+	len = pos + 1 + (random () & 7);
+      if (len + align >= 512)
+	len = 511 - align - (random () & 7);
+      if (pos == len && seek_char)
+	len = pos + 1;
+      j = (pos > len ? pos : len) + align + 64;
+      if (j > 512)
+	j = 512;
+
+      for (i = 0; i < j; i++)
+	{
+	  if (i == pos + align)
+	    p[i] = seek_char;
+	  else if (i == len + align)
+	    p[i] = 0;
+	  else
+	    {
+	      p[i] = random () & 255;
+	      if (i < pos + align && p[i] == seek_char)
+		p[i] = seek_char + 13;
+	      if (i < len + align && !p[i])
+		{
+		  p[i] = seek_char - 13;
+		  if (!p[i])
+		    p[i] = 140;
+		}
+	    }
+	}
+
+      if (pos <= len)
+	result = (CHAR *) (p + pos + align);
+      else if (seek_char == 0)
+	result = (CHAR *) (p + len + align);
+      else
+	result = NULLRET ((CHAR *) (p + len + align));
+
+      FOR_EACH_IMPL (impl, 1)
+	if (CALL (impl, (CHAR *) (p + align), seek_char) != result)
+	  {
+	    error (0, 0, "Iteration %zd - wrong result in function \
+		   %s (align in bytes: %zd, seek_char: %d, len: %zd, pos: %zd) %p != %p, p %p",
+		   n, impl->name, align * sizeof (CHAR), seek_char, len, pos,
+		   CALL (impl, (CHAR *) (p + align), seek_char), result, p);
+	    ret = 1;
+	  }
+    }
+}
+
+static void
+check1 (void)
+{
+  CHAR s[] __attribute__((aligned(16))) = L ("\xff");
+  CHAR c = L ('\xfe');
+  CHAR *exp_result = stupid_STRCHR (s, c);
+
+  FOR_EACH_IMPL (impl, 0)
+    check_result (impl, s, c, exp_result);
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  check1 ();
+
+  printf ("%20s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
+      do_test (i, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 64, 256, SMALL_CHAR, MIDDLE_CHAR);
+      do_test (i, 64, 256, SMALL_CHAR, BIG_CHAR);
+    }
+
+  for (i = 0; i < 32; ++i)
+    {
+      do_test (0, i, i + 1, SMALL_CHAR, MIDDLE_CHAR);
+      do_test (0, i, i + 1, SMALL_CHAR, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 16 << i, 2048, 0, MIDDLE_CHAR);
+      do_test (i, 16 << i, 2048, 0, MIDDLE_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 64, 256, 0, MIDDLE_CHAR);
+      do_test (i, 64, 256, 0, BIG_CHAR);
+    }
+
+  for (i = 0; i < 32; ++i)
+    {
+      do_test (0, i, i + 1, 0, MIDDLE_CHAR);
+      do_test (0, i, i + 1, 0, BIG_CHAR);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strchrnul.c b/REORG.TODO/string/test-strchrnul.c
new file mode 100644
index 0000000000..b8f79b1897
--- /dev/null
+++ b/REORG.TODO/string/test-strchrnul.c
@@ -0,0 +1,21 @@
+/* Test and measure strchrnul function.
+
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define USE_FOR_STRCHRNUL 1
+#include "test-strchr.c"
diff --git a/REORG.TODO/string/test-strcmp.c b/REORG.TODO/string/test-strcmp.c
new file mode 100644
index 0000000000..f7af219149
--- /dev/null
+++ b/REORG.TODO/string/test-strcmp.c
@@ -0,0 +1,409 @@
+/* Test and measure strcmp and wcscmp functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+   Added wcscmp support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifdef WIDE
+# define TEST_NAME "wcscmp"
+#else
+# define TEST_NAME "strcmp"
+#endif
+#include "test-string.h"
+
+#ifdef WIDE
+# include <wchar.h>
+
+# define L(str) L##str
+# define STRCMP wcscmp
+# define STRCPY wcscpy
+# define STRLEN wcslen
+# define MEMCPY wmemcpy
+# define SIMPLE_STRCMP simple_wcscmp
+# define STUPID_STRCMP stupid_wcscmp
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define CHARBYTES 4
+# define CHARBYTESLOG 2
+# define CHARALIGN __alignof__ (CHAR)
+# define MIDCHAR 0x7fffffff
+# define LARGECHAR 0xfffffffe
+# define CHAR__MAX WCHAR_MAX
+# define CHAR__MIN WCHAR_MIN
+
+/* Wcscmp uses signed semantics for comparison, not unsigned */
+/* Avoid using substraction since possible overflow */
+
+int
+simple_wcscmp (const wchar_t *s1, const wchar_t *s2)
+{
+  wchar_t c1, c2;
+  do
+    {
+      c1 = *s1++;
+      c2 = *s2++;
+      if (c2 == L'\0')
+      return c1 - c2;
+    }
+  while (c1 == c2);
+
+  return c1 < c2 ? -1 : 1;
+}
+
+int
+stupid_wcscmp (const wchar_t *s1, const wchar_t *s2)
+{
+  size_t ns1 = wcslen (s1) + 1;
+  size_t ns2 = wcslen (s2) + 1;
+  size_t n = ns1 < ns2 ? ns1 : ns2;
+  int ret = 0;
+
+  wchar_t c1, c2;
+
+  while (n--) {
+    c1 = *s1++;
+    c2 = *s2++;
+    if ((ret = c1 < c2 ? -1 : c1 == c2 ? 0 : 1) != 0)
+      break;
+  }
+  return ret;
+}
+
+#else
+# include <limits.h>
+
+# define L(str) str
+# define STRCMP strcmp
+# define STRCPY strcpy
+# define STRLEN strlen
+# define MEMCPY memcpy
+# define SIMPLE_STRCMP simple_strcmp
+# define STUPID_STRCMP stupid_strcmp
+# define CHAR char
+# define UCHAR unsigned char
+# define CHARBYTES 1
+# define CHARBYTESLOG 0
+# define CHARALIGN 1
+# define MIDCHAR 0x7f
+# define LARGECHAR 0xfe
+# define CHAR__MAX CHAR_MAX
+# define CHAR__MIN CHAR_MIN
+
+/* Strcmp uses unsigned semantics for comparison. */
+int
+simple_strcmp (const char *s1, const char *s2)
+{
+  int ret;
+
+  while ((ret = *(unsigned char *) s1 - *(unsigned char*) s2++) == 0 && *s1++);
+  return ret;
+}
+
+int
+stupid_strcmp (const char *s1, const char *s2)
+{
+  size_t ns1 = strlen (s1) + 1;
+  size_t ns2 = strlen (s2) + 1;
+  size_t n = ns1 < ns2 ? ns1 : ns2;
+  int ret = 0;
+
+  while (n--)
+    if ((ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) != 0)
+      break;
+  return ret;
+}
+#endif
+
+typedef int (*proto_t) (const CHAR *, const CHAR *);
+
+IMPL (STUPID_STRCMP, 1)
+IMPL (SIMPLE_STRCMP, 1)
+IMPL (STRCMP, 1)
+
+static int
+check_result (impl_t *impl,
+	     const CHAR *s1, const CHAR *s2,
+	     int exp_result)
+{
+  int result = CALL (impl, s1, s2);
+  if ((exp_result == 0 && result != 0)
+      || (exp_result < 0 && result >= 0)
+      || (exp_result > 0 && result <= 0))
+    {
+      error (0, 0, "Wrong result in function %s %d %d", impl->name,
+	     result, exp_result);
+      ret = 1;
+      return -1;
+    }
+
+  return 0;
+}
+
+static void
+do_one_test (impl_t *impl,
+	     const CHAR *s1, const CHAR *s2,
+	     int exp_result)
+{
+  if (check_result (impl, s1, s2, exp_result) < 0)
+    return;
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char,
+	 int exp_result)
+{
+  size_t i;
+
+  CHAR *s1, *s2;
+
+  if (len == 0)
+    return;
+
+  align1 &= 63;
+  if (align1 + (len + 1) * CHARBYTES >= page_size)
+    return;
+
+  align2 &= 63;
+  if (align2 + (len + 1) * CHARBYTES >= page_size)
+    return;
+
+  /* Put them close to the end of page.  */
+  i = align1 + CHARBYTES * (len + 2);
+  s1 = (CHAR *) (buf1 + ((page_size - i) / 16 * 16) + align1);
+  i = align2 + CHARBYTES * (len + 2);
+  s2 = (CHAR *) (buf2 + ((page_size - i) / 16 * 16)  + align2);
+
+  for (i = 0; i < len; i++)
+    s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char;
+
+  s1[len] = s2[len] = 0;
+  s1[len + 1] = 23;
+  s2[len + 1] = 24 + exp_result;
+  s2[len - 1] -= exp_result;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, s2, exp_result);
+}
+
+static void
+do_random_tests (void)
+{
+	UCHAR *p1 = (UCHAR *) (buf1 + page_size - 512 * CHARBYTES);
+	UCHAR *p2 = (UCHAR *) (buf2 + page_size - 512 * CHARBYTES);
+
+	for (size_t n = 0; n < ITERATIONS; n++)
+	  {
+	    /* for wcscmp case align1 and align2 mean here alignment
+	       in wchar_t symbols, it equal 4*k alignment in bytes, we
+	       don't check other alignments like for example
+	       p1 = (wchar_t *)(buf1 + 1)
+	       because it's wrong using of wchar_t type.  */
+	    size_t align1 = random () & 31;
+	    size_t align2;
+	    if (random () & 1)
+	      align2 = random () & 31;
+	    else
+	      align2 = align1 + (random () & 24);
+	    size_t pos = random () & 511;
+	    size_t j = align1 > align2 ? align1 : align2;
+	    if (pos + j >= 511)
+	      pos = 510 - j - (random () & 7);
+	    size_t len1 = random () & 511;
+	    if (pos >= len1 && (random () & 1))
+	      len1 = pos + (random () & 7);
+	    if (len1 + j >= 512)
+	      len1 = 511 - j - (random () & 7);
+	    size_t len2;
+	    if (pos >= len1)
+	      len2 = len1;
+	    else
+	      len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
+	    j = (pos > len2 ? pos : len2) + align1 + 64;
+	    if (j > 512)
+	      j = 512;
+	    for (size_t i = 0; i < j; ++i)
+	      {
+		p1[i] = random () & 255;
+		if (i < len1 + align1 && !p1[i])
+		  {
+		    p1[i] = random () & 255;
+		    if (!p1[i])
+		      p1[i] = 1 + (random () & 127);
+		  }
+	      }
+	    for (size_t i = 0; i < j; ++i)
+	      {
+		p2[i] = random () & 255;
+		if (i < len2 + align2 && !p2[i])
+		  {
+		    p2[i] = random () & 255;
+		    if (!p2[i])
+		      p2[i] = 1 + (random () & 127);
+		  }
+	      }
+
+	    int result = 0;
+	    MEMCPY (p2 + align2, p1 + align1, pos);
+	    if (pos < len1)
+	      {
+		if (p2[align2 + pos] == p1[align1 + pos])
+		  {
+		    p2[align2 + pos] = random () & 255;
+		    if (p2[align2 + pos] == p1[align1 + pos])
+		      p2[align2 + pos] = p1[align1 + pos] + 3 + (random () & 127);
+		  }
+
+		if (p1[align1 + pos] < p2[align2 + pos])
+		  result = -1;
+		else
+		  result = 1;
+	      }
+	    p1[len1 + align1] = 0;
+	    p2[len2 + align2] = 0;
+
+	    FOR_EACH_IMPL (impl, 1)
+	      {
+		int r = CALL (impl, (CHAR *) (p1 + align1), (CHAR *) (p2 + align2));
+		/* Test whether on 64-bit architectures where ABI requires
+		   callee to promote has the promotion been done.  */
+		asm ("" : "=g" (r) : "0" (r));
+		if ((r == 0 && result)
+		    || (r < 0 && result >= 0)
+		    || (r > 0 && result <= 0))
+		  {
+		    error (0, 0, "Iteration %zd - wrong result in function %s (align in bytes: %zd, align in bytes: %zd, len1:  %zd, len2: %zd, pos: %zd) %d != %d, p1 %p p2 %p",
+			   n, impl->name, (size_t) (p1 + align1) & 63, (size_t) (p1 + align2) & 63, len1, len2, pos, r, result, p1, p2);
+		    ret = 1;
+		  }
+	      }
+     }
+}
+
+static void
+check (void)
+{
+  CHAR *s1 = (CHAR *) (buf1 + 0xb2c);
+  CHAR *s2 = (CHAR *) (buf1 + 0xfd8);
+
+  STRCPY(s1, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs"));
+  STRCPY(s2, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV"));
+
+  /* Check correct working for negatives values */
+
+  s1[0] = 1;
+  s2[0] = 1;
+  s1[1] = 1;
+  s2[1] = 1;
+  s1[2] = -1;
+  s2[2] = 3;
+  s1[3] = 0;
+  s2[3] = -1;
+
+  /* Check possible overflow bug, actual more for wcscmp */
+
+  s1[7] = CHAR__MIN;
+  s2[7] = CHAR__MAX;
+
+  size_t l1 = STRLEN (s1);
+  size_t l2 = STRLEN (s2);
+
+  for (size_t i1 = 0; i1 < l1; i1++)
+    for (size_t i2 = 0; i2 < l2; i2++)
+      {
+		int exp_result = SIMPLE_STRCMP (s1 + i1, s2 + i2);
+		FOR_EACH_IMPL (impl, 0)
+		check_result (impl, s1 + i1, s2 + i2, exp_result);
+      }
+
+  /* Test cases where there are multiple zero bytes after the first.  */
+
+  for (size_t i = 0; i < 16 + 1; i++)
+    {
+      s1[i] = 0x00;
+      s2[i] = 0x00;
+    }
+
+  for (size_t i = 0; i < 16; i++)
+    {
+      int exp_result;
+
+      for (int val = 0x01; val < 0x100; val++)
+	{
+	  for (size_t j = 0; j < i; j++)
+	    {
+	      s1[j] = val;
+	      s2[j] = val;
+	    }
+
+	  s2[i] = val;
+
+	  exp_result = SIMPLE_STRCMP (s1, s2);
+	  FOR_EACH_IMPL (impl, 0)
+	    check_result (impl, s1, s2, exp_result);
+	}
+    }
+}
+
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+  check();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 32; ++i)
+    {
+      do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 0);
+      do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 1);
+      do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, -1);
+    }
+
+  for (i = 1; i < 10 + CHARBYTESLOG; ++i)
+    {
+      do_test (0, 0, 2 << i, MIDCHAR, 0);
+      do_test (0, 0, 2 << i, LARGECHAR, 0);
+      do_test (0, 0, 2 << i, MIDCHAR, 1);
+      do_test (0, 0, 2 << i, LARGECHAR, 1);
+      do_test (0, 0, 2 << i, MIDCHAR, -1);
+      do_test (0, 0, 2 << i, LARGECHAR, -1);
+      do_test (0, CHARBYTES * i, 2 << i, MIDCHAR, 1);
+      do_test (CHARBYTES * i, CHARBYTES * (i + 1), 2 << i, LARGECHAR, 1);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 0);
+      do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 0);
+      do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 1);
+      do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 1);
+      do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, -1);
+      do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, -1);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strcpy.c b/REORG.TODO/string/test-strcpy.c
new file mode 100644
index 0000000000..d4de65a590
--- /dev/null
+++ b/REORG.TODO/string/test-strcpy.c
@@ -0,0 +1,245 @@
+/* Test and measure strcpy functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+   Added wcscpy support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define sfmt "ls"
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define STRCMP wcscmp
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define sfmt "s"
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define STRCMP strcmp
+# define MEMCMP memcmp
+# define MEMSET memset
+#endif
+
+#ifndef STRCPY_RESULT
+# define STRCPY_RESULT(dst, len) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strcpy"
+# else
+#  define TEST_NAME "wcscpy"
+# endif
+# include "test-string.h"
+# ifndef WIDE
+#  define SIMPLE_STRCPY simple_strcpy
+#  define STRCPY strcpy
+# else
+#  define SIMPLE_STRCPY simple_wcscpy
+#  define STRCPY wcscpy
+# endif
+
+CHAR *SIMPLE_STRCPY (CHAR *, const CHAR *);
+
+IMPL (SIMPLE_STRCPY, 0)
+IMPL (STRCPY, 1)
+
+CHAR *
+SIMPLE_STRCPY (CHAR *dst, const CHAR *src)
+{
+  CHAR *ret = dst;
+  while ((*dst++ = *src++) != '\0');
+  return ret;
+}
+#endif
+
+typedef CHAR *(*proto_t) (CHAR *, const CHAR *);
+
+static void
+do_one_test (impl_t *impl, CHAR *dst, const CHAR *src,
+	     size_t len __attribute__((unused)))
+{
+  if (CALL (impl, dst, src) != STRCPY_RESULT (dst, len))
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     CALL (impl, dst, src), STRCPY_RESULT (dst, len));
+      ret = 1;
+      return;
+    }
+
+  if (STRCMP (dst, src) != 0)
+    {
+      error (0, 0,
+	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
+	     impl->name, dst, src);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char)
+{
+  size_t i;
+  CHAR *s1, *s2;
+/* For wcscpy: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof(CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof(CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+  s2 = (CHAR *) (buf2) + align2;
+
+  for (i = 0; i < len; i++)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s2, s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* For wcsrchr: align1 and align2 here mean align not in bytes,
+	 but in wchar_ts, in bytes it will equal to align * (sizeof
+	 (wchar_t)).  For strrchr we need to check all alignments from
+	 0 to 63 since some assembly implementations have separate
+	 prolog for alignments more 48. */
+
+      align1 = random () & (63 / sizeof(CHAR));
+      if (random () & 1)
+	align2 = random () & (63 / sizeof(CHAR));
+      else
+	align2 = align1 + (random () & 24);
+      len = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (len + j >= 511)
+	len = 510 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  MEMSET (p2 - 64, '\1', 512 + 64);
+	  res = (UCHAR *) CALL (impl, (CHAR *) (p2 + align2), (CHAR *) (p1 + align1));
+	  if (res != STRCPY_RESULT (p2 + align2, len))
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
+		     n, impl->name, align1, align2, len, res,
+		     STRCPY_RESULT (p2 + align2, len));
+	      ret = 1;
+	    }
+	  for (j = 0; j < align2 + 64; ++j)
+	    {
+	      if (p2[j - 64] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  for (j = align2 + len + 1; j < 512; ++j)
+	    {
+	      if (p2[j] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  if (MEMCMP (p1 + align1, p2 + align2, len + 1))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, SMALL_CHAR);
+      do_test (0, 0, i, BIG_CHAR);
+      do_test (0, i, i, SMALL_CHAR);
+      do_test (i, 0, i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
+      do_test (2 * i, i, 8 << i, BIG_CHAR);
+      do_test (i, i, 8 << i, SMALL_CHAR);
+      do_test (i, i, 8 << i, BIG_CHAR);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strcspn.c b/REORG.TODO/string/test-strcspn.c
new file mode 100644
index 0000000000..d83c1347d1
--- /dev/null
+++ b/REORG.TODO/string/test-strcspn.c
@@ -0,0 +1,81 @@
+/* Test strcspn functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define STRPBRK_RESULT(s, pos) (pos)
+#define RES_TYPE size_t
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "strcspn"
+#else
+# define TEST_NAME "wcscspn"
+#endif /* WIDE */
+#include "test-string.h"
+
+#ifndef WIDE
+# define STRCSPN strcspn
+# define CHAR char
+# define SIMPLE_STRCSPN simple_strcspn
+# define STUPID_STRCSPN stupid_strcspn
+# define STRLEN strlen
+#else
+# include <wchar.h>
+# define STRCSPN wcscspn
+# define CHAR wchar_t
+# define SIMPLE_STRCSPN simple_wcscspn
+# define STUPID_STRCSPN stupid_wcscspn
+# define STRLEN wcslen
+#endif /* WIDE */
+
+typedef size_t (*proto_t) (const CHAR *, const CHAR *);
+size_t SIMPLE_STRCSPN (const CHAR *, const CHAR *);
+size_t STUPID_STRCSPN (const CHAR *, const CHAR *);
+
+IMPL (STUPID_STRCSPN, 0)
+IMPL (SIMPLE_STRCSPN, 0)
+IMPL (STRCSPN, 1)
+
+size_t
+SIMPLE_STRCSPN (const CHAR *s, const CHAR *rej)
+{
+  const CHAR *r, *str = s;
+  CHAR c;
+
+  while ((c = *s++) != '\0')
+    for (r = rej; *r != '\0'; ++r)
+      if (*r == c)
+	return s - str - 1;
+  return s - str - 1;
+}
+
+size_t
+STUPID_STRCSPN (const CHAR *s, const CHAR *rej)
+{
+  size_t ns = STRLEN (s), nrej = STRLEN (rej);
+  size_t i, j;
+
+  for (i = 0; i < ns; ++i)
+    for (j = 0; j < nrej; ++j)
+      if (s[i] == rej[j])
+	return i;
+  return i;
+}
+
+#undef CHAR
+#undef STRLEN
+#include "test-strpbrk.c"
diff --git a/REORG.TODO/string/test-string.h b/REORG.TODO/string/test-string.h
new file mode 100644
index 0000000000..6e13bf4aa3
--- /dev/null
+++ b/REORG.TODO/string/test-string.h
@@ -0,0 +1,219 @@
+/* Test and measure string and memory functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/cdefs.h>
+
+typedef struct
+{
+  const char *name;
+  void (*fn) (void);
+  long test;
+} impl_t;
+extern impl_t __start_impls[], __stop_impls[];
+
+#define IMPL(name, test) \
+  impl_t tst_ ## name							\
+  __attribute__ ((section ("impls"), aligned (sizeof (void *))))	\
+       = { __STRING (name), (void (*) (void))name, test };
+
+#ifdef TEST_MAIN
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#undef __USE_STRING_INLINES
+
+/* We are compiled under _ISOMAC, so libc-symbols.h does not do this
+   for us.  */
+#include "config.h"
+#ifdef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
+# define inhibit_loop_to_libcall \
+    __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
+#else
+# define inhibit_loop_to_libcall
+#endif
+
+#include <getopt.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <error.h>
+#include <errno.h>
+#include <time.h>
+#include <ifunc-impl-list.h>
+#define GL(x) _##x
+#define GLRO(x) _##x
+
+
+# define TEST_FUNCTION test_main
+# define TIMEOUT (4 * 60)
+# define OPT_ITERATIONS 10000
+# define OPT_RANDOM 10001
+# define OPT_SEED 10002
+
+unsigned char *buf1, *buf2;
+int ret, do_srandom;
+unsigned int seed;
+size_t page_size;
+
+# ifndef ITERATIONS
+size_t iterations = 100000;
+#  define ITERATIONS_OPTIONS \
+  { "iterations", required_argument, NULL, OPT_ITERATIONS },
+#  define ITERATIONS_PROCESS \
+  case OPT_ITERATIONS:				\
+    iterations = strtoul (optarg, NULL, 0);	\
+    break;
+#  define ITERATIONS iterations
+# else
+#  define ITERATIONS_OPTIONS
+#  define ITERATIONS_PROCESS
+# endif
+
+# define CMDLINE_OPTIONS ITERATIONS_OPTIONS \
+  { "random", no_argument, NULL, OPT_RANDOM },	\
+  { "seed", required_argument, NULL, OPT_SEED },
+
+static void __attribute__ ((used))
+cmdline_process_function (int c)
+{
+  switch (c)
+    {
+      ITERATIONS_PROCESS
+      case OPT_RANDOM:
+        {
+          int fdr = open ("/dev/urandom", O_RDONLY);
+          if (fdr < 0 || read (fdr, &seed, sizeof (seed)) != sizeof (seed))
+            seed = time (NULL);
+          if (fdr >= 0)
+            close (fdr);
+          do_srandom = 1;
+          break;
+        }
+
+      case OPT_SEED:
+        seed = strtoul (optarg, NULL, 0);
+        do_srandom = 1;
+        break;
+    }
+}
+# define CMDLINE_PROCESS cmdline_process_function
+
+#define CALL(impl, ...)	\
+  (* (proto_t) (impl)->fn) (__VA_ARGS__)
+
+#ifdef TEST_NAME
+/* Increase size of FUNC_LIST if assert is triggered at run-time.  */
+static struct libc_ifunc_impl func_list[32];
+static int func_count;
+static int impl_count = -1;
+static impl_t *impl_array;
+
+# define FOR_EACH_IMPL(impl, notall) \
+  impl_t *impl;								\
+  int count;								\
+  if (impl_count == -1)							\
+    {									\
+      impl_count = 0;							\
+      if (func_count != 0)						\
+	{								\
+	  int f;							\
+	  impl_t *skip = NULL, *a;					\
+	  for (impl = __start_impls; impl < __stop_impls; ++impl)	\
+	    if (strcmp (impl->name, TEST_NAME) == 0)			\
+	      skip = impl;						\
+	    else							\
+	      impl_count++;						\
+	  a = impl_array = malloc ((impl_count + func_count) *		\
+				   sizeof (impl_t));			\
+	  for (impl = __start_impls; impl < __stop_impls; ++impl)	\
+	    if (impl != skip)						\
+	      *a++ = *impl;						\
+	  for (f = 0; f < func_count; f++)				\
+	    if (func_list[f].usable)					\
+	      {								\
+		a->name = func_list[f].name;				\
+		a->fn = func_list[f].fn;				\
+		a->test = 1;						\
+		a++;							\
+	      }								\
+	  impl_count = a - impl_array;					\
+	}								\
+      else								\
+        {								\
+	  impl_count = __stop_impls - __start_impls;			\
+	  impl_array = __start_impls;					\
+        }								\
+    }									\
+  impl = impl_array;							\
+  for (count = 0; count < impl_count; ++count, ++impl)			\
+    if (!notall || impl->test)
+#else
+# define FOR_EACH_IMPL(impl, notall) \
+  for (impl_t *impl = __start_impls; impl < __stop_impls; ++impl)	\
+    if (!notall || impl->test)
+#endif
+
+#ifndef BUF1PAGES
+# define BUF1PAGES 1
+#endif
+
+static void
+test_init (void)
+{
+#ifdef TEST_NAME
+  func_count = __libc_ifunc_impl_list (TEST_NAME, func_list,
+				       (sizeof func_list
+					/ sizeof func_list[0]));
+#endif
+
+  page_size = 2 * getpagesize ();
+#ifdef MIN_PAGE_SIZE
+  if (page_size < MIN_PAGE_SIZE)
+    page_size = MIN_PAGE_SIZE;
+#endif
+  buf1 = mmap (0, (BUF1PAGES + 1) * page_size, PROT_READ | PROT_WRITE,
+	       MAP_PRIVATE | MAP_ANON, -1, 0);
+  if (buf1 == MAP_FAILED)
+    error (EXIT_FAILURE, errno, "mmap failed");
+  if (mprotect (buf1 + BUF1PAGES * page_size, page_size, PROT_NONE))
+    error (EXIT_FAILURE, errno, "mprotect failed");
+  buf2 = mmap (0, 2 * page_size, PROT_READ | PROT_WRITE,
+	       MAP_PRIVATE | MAP_ANON, -1, 0);
+  if (buf2 == MAP_FAILED)
+    error (EXIT_FAILURE, errno, "mmap failed");
+  if (mprotect (buf2 + page_size, page_size, PROT_NONE))
+    error (EXIT_FAILURE, errno, "mprotect failed");
+  if (do_srandom)
+    {
+      printf ("Setting seed to 0x%x\n", seed);
+      srandom (seed);
+    }
+
+  memset (buf1, 0xa5, BUF1PAGES * page_size);
+  memset (buf2, 0x5a, page_size);
+}
+
+#endif
diff --git a/REORG.TODO/string/test-strlen.c b/REORG.TODO/string/test-strlen.c
new file mode 100644
index 0000000000..99be380e6e
--- /dev/null
+++ b/REORG.TODO/string/test-strlen.c
@@ -0,0 +1,167 @@
+/* Test and measure STRLEN functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+   Added wcslen support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "strlen"
+#else
+# define TEST_NAME "wcslen"
+#endif
+#include "test-string.h"
+
+#ifndef WIDE
+# define STRLEN strlen
+# define CHAR char
+# define MAX_CHAR CHAR_MAX
+#else
+# include <wchar.h>
+# define STRLEN wcslen
+# define CHAR wchar_t
+# define MAX_CHAR WCHAR_MAX
+#endif
+
+typedef size_t (*proto_t) (const CHAR *);
+
+size_t
+simple_STRLEN (const CHAR *s)
+{
+  const CHAR *p;
+
+  for (p = s; *p; ++p);
+  return p - s;
+}
+
+#ifndef WIDE
+size_t
+builtin_strlen (const CHAR *p)
+{
+  return __builtin_strlen (p);
+}
+IMPL (builtin_strlen, 0)
+#endif
+
+IMPL (simple_STRLEN, 0)
+IMPL (STRLEN, 1)
+
+
+static void
+do_one_test (impl_t *impl, const CHAR *s, size_t exp_len)
+{
+  size_t len = CALL (impl, s);
+  if (len != exp_len)
+    {
+      error (0, 0, "Wrong result in function %s %zd %zd", impl->name,
+	     len, exp_len);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align, size_t len)
+{
+  size_t i;
+
+  align &= 63;
+  if (align + sizeof(CHAR) * len >= page_size)
+    return;
+
+  CHAR *buf = (CHAR *) (buf1);
+
+  for (i = 0; i < len; ++i)
+    buf[align + i] = 1 + 11111 * i % MAX_CHAR;
+  buf[align + len] = 0;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, (CHAR *) (buf + align), len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align, len;
+  CHAR *p = (CHAR *) (buf1 + page_size - 512 * sizeof(CHAR));
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align = random () & 15;
+      len = random () & 511;
+      if (len + align > 510)
+	len = 511 - align - (random () & 7);
+      j = len + align + 64;
+      if (j > 512)
+	j = 512;
+
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align)
+	    p[i] = 0;
+	  else
+	    {
+	      p[i] = random () & 255;
+	      if (i >= align && i < len + align && !p[i])
+		p[i] = (random () & 127) + 1;
+	    }
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	if (CALL (impl, (CHAR *) (p + align)) != len)
+	  {
+	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd) %zd != %zd, p %p",
+		   n, impl->name, align, CALL (impl, (CHAR *) (p + align)),
+		   len, p);
+	    ret = 1;
+	  }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%20s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  /* Checking with only 4 * N alignments for wcslen, other alignments are wrong for wchar_t type arrays*/
+
+  for (i = 1; i < 8; ++i)
+  {
+    do_test (sizeof(CHAR) * i, i);
+    do_test (0, i);
+  }
+
+  for (i = 2; i <= 12; ++i)
+    {
+      do_test (0, 1 << i);
+      do_test (sizeof(CHAR) * 7, 1 << i);
+      do_test (sizeof(CHAR) * i, 1 << i);
+      do_test (sizeof(CHAR) * i, (size_t)((1 << i) / 1.5));
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strncasecmp.c b/REORG.TODO/string/test-strncasecmp.c
new file mode 100644
index 0000000000..bf501cf798
--- /dev/null
+++ b/REORG.TODO/string/test-strncasecmp.c
@@ -0,0 +1,353 @@
+/* Test and measure strncasecmp functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <locale.h>
+#include <ctype.h>
+#define TEST_MAIN
+#define TEST_NAME "strncasecmp"
+#include "test-string.h"
+
+typedef int (*proto_t) (const char *, const char *, size_t);
+static int simple_strncasecmp (const char *, const char *, size_t);
+static int stupid_strncasecmp (const char *, const char *, size_t);
+
+IMPL (stupid_strncasecmp, 0)
+IMPL (simple_strncasecmp, 0)
+IMPL (strncasecmp, 1)
+
+static int
+simple_strncasecmp (const char *s1, const char *s2, size_t n)
+{
+  int ret;
+
+  if (n == 0)
+    return 0;
+
+  while ((ret = ((unsigned char) tolower (*s1)
+		 - (unsigned char) tolower (*s2))) == 0
+	 && *s1++)
+    {
+      if (--n == 0)
+	return 0;
+      ++s2;
+    }
+  return ret;
+}
+
+static int
+stupid_strncasecmp (const char *s1, const char *s2, size_t max)
+{
+  size_t ns1 = strlen (s1) + 1;
+  size_t ns2 = strlen (s2) + 1;
+  size_t n = ns1 < ns2 ? ns1 : ns2;
+  if (n > max)
+    n = max;
+  int ret = 0;
+
+  while (n--)
+    {
+      if ((ret = ((unsigned char) tolower (*s1)
+		  - (unsigned char) tolower (*s2))) != 0)
+	break;
+      ++s1;
+      ++s2;
+    }
+  return ret;
+}
+
+static int
+check_result (impl_t *impl, const char *s1, const char *s2, size_t n,
+	      int exp_result)
+{
+  int result = CALL (impl, s1, s2, n);
+  if ((exp_result == 0 && result != 0)
+      || (exp_result < 0 && result >= 0)
+      || (exp_result > 0 && result <= 0))
+    {
+      error (0, 0, "Wrong result in function %s %d %d", impl->name,
+	     result, exp_result);
+      ret = 1;
+      return -1;
+    }
+
+  return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
+	     int exp_result)
+{
+  if (check_result (impl, s1, s2, n, exp_result) < 0)
+    return;
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char,
+	 int exp_result)
+{
+  size_t i;
+  char *s1, *s2;
+
+  if (len == 0)
+    return;
+
+  align1 &= 7;
+  if (align1 + len + 1 >= page_size)
+    return;
+
+  align2 &= 7;
+  if (align2 + len + 1 >= page_size)
+    return;
+
+  s1 = (char *) (buf1 + align1);
+  s2 = (char *) (buf2 + align2);
+
+  for (i = 0; i < len; i++)
+    {
+      s1[i] = toupper (1 + 23 * i % max_char);
+      s2[i] = tolower (s1[i]);
+    }
+
+  s1[len] = s2[len] = 0;
+  s1[len + 1] = 23;
+  s2[len + 1] = 24 + exp_result;
+  if ((s2[len - 1] == 'z' && exp_result == -1)
+      || (s2[len - 1] == 'a' && exp_result == 1))
+    s1[len - 1] += exp_result;
+  else
+    s2[len - 1] -= exp_result;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, s2, n, exp_result);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, pos, len1, len2;
+  int result;
+  long r;
+  unsigned char *p1 = buf1 + page_size - 512;
+  unsigned char *p2 = buf2 + page_size - 512;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align1 = random () & 31;
+      if (random () & 1)
+	align2 = random () & 31;
+      else
+	align2 = align1 + (random () & 24);
+      pos = random () & 511;
+      j = align1 > align2 ? align1 : align2;
+      if (pos + j >= 511)
+	pos = 510 - j - (random () & 7);
+      len1 = random () & 511;
+      if (pos >= len1 && (random () & 1))
+	len1 = pos + (random () & 7);
+      if (len1 + j >= 512)
+	len1 = 511 - j - (random () & 7);
+      if (pos >= len1)
+	len2 = len1;
+      else
+	len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
+      j = (pos > len2 ? pos : len2) + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; ++i)
+	{
+	  p1[i] = tolower (random () & 255);
+	  if (i < len1 + align1 && !p1[i])
+	    {
+	      p1[i] = tolower (random () & 255);
+	      if (!p1[i])
+		p1[i] = tolower (1 + (random () & 127));
+	    }
+	}
+      for (i = 0; i < j; ++i)
+	{
+	  p2[i] = toupper (random () & 255);
+	  if (i < len2 + align2 && !p2[i])
+	    {
+	      p2[i] = toupper (random () & 255);
+	      if (!p2[i])
+		toupper (p2[i] = 1 + (random () & 127));
+	    }
+	}
+
+      result = 0;
+      memcpy (p2 + align2, p1 + align1, pos);
+      if (pos < len1)
+	{
+	  if (tolower (p2[align2 + pos]) == p1[align1 + pos])
+	    {
+	      p2[align2 + pos] = toupper (random () & 255);
+	      if (tolower (p2[align2 + pos]) == p1[align1 + pos])
+		p2[align2 + pos] = toupper (p1[align1 + pos]
+					    + 3 + (random () & 127));
+	    }
+
+	  if (p1[align1 + pos] < tolower (p2[align2 + pos]))
+	    result = -1;
+	  else
+	    result = 1;
+	}
+      p1[len1 + align1] = 0;
+      p2[len2 + align2] = 0;
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2),
+		    pos + 1 + (random () & 255));
+	  /* Test whether on 64-bit architectures where ABI requires
+	     callee to promote has the promotion been done.  */
+	  asm ("" : "=g" (r) : "0" (r));
+	  if ((r == 0 && result)
+	      || (r < 0 && result >= 0)
+	      || (r > 0 && result <= 0))
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p",
+		     n, impl->name, align1, align2, len1, len2, pos, r, result, p1, p2);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+/* Regression test for BZ #12205 */
+static void
+bz12205 (void)
+{
+  static char cp [4096+16] __attribute__ ((aligned(4096)));
+  static char gotrel[4096] __attribute__ ((aligned(4096)));
+  char *s1 = cp + 0xffa;
+  char *s2 = gotrel + 0xcbe;
+  int exp_result;
+  size_t n = 6;
+
+  strcpy (s1, "gottpoff");
+  strcpy (s2, "GOTPLT");
+
+  exp_result = simple_strncasecmp (s1, s2, n);
+  FOR_EACH_IMPL (impl, 0)
+    check_result (impl, s1, s2, n, exp_result);
+}
+
+/* Regression test for BZ #14195 */
+static void
+bz14195 (void)
+{
+  const char *empty_string  = "";
+  FOR_EACH_IMPL (impl, 0)
+    check_result (impl, empty_string, "", 5, 0);
+}
+
+static void
+test_locale (const char *locale)
+{
+  size_t i;
+
+  if (setlocale (LC_CTYPE, locale) == NULL)
+    {
+      error (0, 0, "cannot set locale \"%s\"", locale);
+      ret = 1;
+    }
+
+  bz12205 ();
+  bz14195 ();
+
+  printf ("%23s", locale);
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 16; ++i)
+    {
+      do_test (i, i, i - 1, i, 127, 0);
+
+      do_test (i, i, i, i, 127, 0);
+      do_test (i, i, i, i, 127, 1);
+      do_test (i, i, i, i, 127, -1);
+
+      do_test (i, i, i + 1, i, 127, 0);
+      do_test (i, i, i + 1, i, 127, 1);
+      do_test (i, i, i + 1, i, 127, -1);
+    }
+
+  for (i = 1; i < 10; ++i)
+    {
+      do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0);
+      do_test (0, 0, 2 << i, 2 << i, 254, 0);
+      do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0);
+
+      do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0);
+
+      do_test (0, 0, 2 << i, 2 << i, 127, 1);
+      do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1);
+
+      do_test (0, 0, 2 << i, 2 << i, 254, 1);
+      do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1);
+
+      do_test (0, 0, 2 << i, 2 << i, 127, -1);
+      do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1);
+
+      do_test (0, 0, 2 << i, 2 << i, 254, -1);
+      do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0);
+      do_test (i, 2 * i, 8 << i, 8 << i, 127, 0);
+      do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0);
+
+      do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0);
+      do_test (2 * i, i, 8 << i, 8 << i, 254, 0);
+      do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0);
+
+      do_test (i, 2 * i, 8 << i, 8 << i, 127, 1);
+      do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1);
+
+      do_test (2 * i, i, 8 << i, 8 << i, 254, 1);
+      do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1);
+
+      do_test (i, 2 * i, 8 << i, 8 << i, 127, -1);
+      do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1);
+
+      do_test (2 * i, i, 8 << i, 8 << i, 254, -1);
+      do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1);
+    }
+
+  do_random_tests ();
+}
+
+int
+test_main (void)
+{
+  test_init ();
+
+  test_locale ("C");
+  test_locale ("en_US.ISO-8859-1");
+  test_locale ("en_US.UTF-8");
+  test_locale ("tr_TR.ISO-8859-9");
+  test_locale ("tr_TR.UTF-8");
+
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strncat.c b/REORG.TODO/string/test-strncat.c
new file mode 100644
index 0000000000..66d58e534d
--- /dev/null
+++ b/REORG.TODO/string/test-strncat.c
@@ -0,0 +1,322 @@
+/* Test strncat functions.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   Contributed by Intel Corporation.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "strncat"
+#else
+# define TEST_NAME "wcsncat"
+#endif /* WIDE */
+#include "test-string.h"
+
+#ifndef WIDE
+# define STRNCAT strncat
+# define CHAR char
+# define UCHAR unsigned char
+# define SIMPLE_STRNCAT simple_strncat
+# define STUPID_STRNCAT stupid_strncat
+# define STRLEN strlen
+# define MEMSET memset
+# define MEMCPY memcpy
+# define MEMCMP memcmp
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+#else
+# include <wchar.h>
+# define STRNCAT wcsncat
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define SIMPLE_STRNCAT simple_wcsncat
+# define STUPID_STRNCAT stupid_wcsncat
+# define STRLEN wcslen
+# define MEMSET wmemset
+# define MEMCPY wmemcpy
+# define MEMCMP wmemcmp
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+#endif /* WIDE */
+
+typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t);
+CHAR *STUPID_STRNCAT (CHAR *, const CHAR *, size_t);
+CHAR *SIMPLE_STRNCAT (CHAR *, const CHAR *, size_t);
+
+IMPL (STUPID_STRNCAT, 0)
+IMPL (STRNCAT, 2)
+
+CHAR *
+STUPID_STRNCAT (CHAR *dst, const CHAR *src, size_t n)
+{
+  CHAR *ret = dst;
+  while (*dst++ != '\0');
+  --dst;
+  while (n--)
+    if ((*dst++ = *src++) == '\0')
+      return ret;
+  *dst = '\0';
+  return ret;
+}
+
+static void
+do_one_test (impl_t *impl, CHAR *dst, const CHAR *src, size_t n)
+{
+  size_t k = STRLEN (dst);
+  if (CALL (impl, dst, src, n) != dst)
+    {
+      error (0, 0, "Wrong result in function %s %p != %p", impl->name,
+	     CALL (impl, dst, src, n), dst);
+      ret = 1;
+      return;
+    }
+
+  size_t len = STRLEN (src);
+  if (MEMCMP (dst + k, src, len + 1 > n ? n : len + 1) != 0)
+    {
+      error (0, 0, "Incorrect concatenation in function %s",
+	     impl->name);
+      ret = 1;
+      return;
+    }
+  if (n < len && dst[k + n] != '\0')
+    {
+      error (0, 0, "There is no zero in the end of output string in %s",
+	     impl->name);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len1, size_t len2,
+	 size_t n, int max_char)
+{
+  size_t i;
+  CHAR *s1, *s2;
+
+  align1 &= 7;
+  if ((align1 + len1) * sizeof (CHAR) >= page_size)
+    return;
+  if ((align1 + n) * sizeof (CHAR) > page_size)
+    return;
+  align2 &= 7;
+  if ((align2 + len1 + len2) * sizeof (CHAR) >= page_size)
+    return;
+  if ((align2 + len1 + n) * sizeof (CHAR) > page_size)
+    return;
+  s1 = (CHAR *) (buf1) + align1;
+  s2 = (CHAR *) (buf2) + align2;
+
+  for (i = 0; i < len1; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len1] = '\0';
+
+  for (i = 0; i < len2; i++)
+    s2[i] = 32 + 23 * i % (max_char - 32);
+
+  FOR_EACH_IMPL (impl, 0)
+    {
+      s2[len2] = '\0';
+      do_one_test (impl, s2, s1, n);
+    }
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len1, len2, N;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512;
+  UCHAR *p3 = (UCHAR *) buf1;
+  UCHAR *res;
+  fprintf (stdout, "Number of iterations in random test = %zd\n",
+	   ITERATIONS);
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      N = random () & 255;
+      align1 = random () & 31;
+      if (random () & 1)
+	align2 = random () & 31;
+      else
+	align2 = align1 + (random () & 24);
+      len1 = random () & 511;
+      if (len1 + align2 > 512)
+	len2 = random () & 7;
+      else
+	len2 = (512 - len1 - align2) * (random () & (1024 * 1024 - 1))
+	  / (1024 * 1024);
+      j = align1;
+      if (align2 + len2 > j)
+	j = align2 + len2;
+      if (len1 + j >= 511)
+	len1 = 510 - j - (random () & 7);
+      if (len1 >= 512)
+	len1 = 0;
+      if (align1 + len1 < 512 - 8)
+	{
+	  j = 510 - align1 - len1 - (random () & 31);
+	  if (j > 0 && j < 512)
+	    align1 += j;
+	}
+      j = len1 + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len1 + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len1 + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+      for (i = 0; i < len2; i++)
+	{
+	  p3[i] = random () & BIG_CHAR;
+	  if (!p3[i])
+	    p3[i] = (random () & SMALL_CHAR) + 3;
+	}
+      p3[len2] = 0;
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  MEMSET (p2 - 64, '\1', align2 + 64);
+	  MEMSET (p2 + align2 + len2 + 1, '\1', 512 - align2 - len2 - 1);
+	  MEMCPY (p2 + align2, p3, len2 + 1);
+	  res = (UCHAR *) CALL (impl, (CHAR *) (p2 + align2),
+				(CHAR *) (p1 + align1), N);
+	  if (res != p2 + align2)
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s "
+		     "(%zd, %zd, %zd, %zd, %zd) %p != %p",
+		     n, impl->name, align1, align2, len1, len2, N,
+		     res, p2 + align2);
+	      ret = 1;
+	    }
+	  for (j = 0; j < align2 + 64; ++j)
+	    {
+	      if (p2[j - 64] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage before dst, %s "
+			 "%zd, %zd, %zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len1, len2, N);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  if (MEMCMP (p2 + align2, p3, len2))
+	    {
+	      error (0, 0, "Iteration %zd - garbage in string before, %s "
+		     "(%zd, %zd, %zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len1, len2, N);
+	      ret = 1;
+	    }
+
+	  if ((len1 + 1) > N)
+	    j = align2 + N + 1 + len2;
+	  else
+	    j = align2 + len1 + 1 + len2;
+	  for (; j < 512; ++j)
+	    {
+	      if (p2[j] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage after, %s "
+			 "(%zd, %zd, %zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len1, len2, N);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  if (len1 + 1 > N)
+	    {
+	      if (p2[align2 + N + len2] != '\0')
+		{
+		  error (0, 0, "Iteration %zd - there is no zero at the "
+			 "end of output string, %s (%zd, %zd, %zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len1, len2, N);
+		  ret = 1;
+		}
+	    }
+	  if (MEMCMP (p1 + align1, p2 + align2 + len2,
+		      (len1 + 1) > N ? N : len1 + 1))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s "
+		     "(%zd, %zd, %zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len1, len2, N);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i, n;
+
+  test_init ();
+
+  printf ("%28s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (n = 2; n <= 2048; n*=4)
+    {
+      do_test (0, 2, 2, 2, n, SMALL_CHAR);
+      do_test (0, 0, 4, 4, n, SMALL_CHAR);
+      do_test (4, 0, 4, 4, n, BIG_CHAR);
+      do_test (0, 0, 8, 8, n, SMALL_CHAR);
+      do_test (0, 8, 8, 8, n, SMALL_CHAR);
+
+      do_test (0, 2, 2, 2, SIZE_MAX, SMALL_CHAR);
+      do_test (0, 0, 4, 4, SIZE_MAX, SMALL_CHAR);
+      do_test (4, 0, 4, 4, SIZE_MAX, BIG_CHAR);
+      do_test (0, 0, 8, 8, SIZE_MAX, SMALL_CHAR);
+      do_test (0, 8, 8, 8, SIZE_MAX, SMALL_CHAR);
+
+      for (i = 1; i < 8; ++i)
+	{
+	  do_test (0, 0, 8 << i, 8 << i, n, SMALL_CHAR);
+	  do_test (8 - i, 2 * i, 8 << i, 8 << i, n, SMALL_CHAR);
+	  do_test (0, 0, 8 << i, 2 << i, n, SMALL_CHAR);
+	  do_test (8 - i, 2 * i, 8 << i, 2 << i, n, SMALL_CHAR);
+
+	  do_test (0, 0, 8 << i, 8 << i, SIZE_MAX, SMALL_CHAR);
+	  do_test (8 - i, 2 * i, 8 << i, 8 << i, SIZE_MAX, SMALL_CHAR);
+	  do_test (0, 0, 8 << i, 2 << i, SIZE_MAX, SMALL_CHAR);
+	  do_test (8 - i, 2 * i, 8 << i, 2 << i, SIZE_MAX, SMALL_CHAR);
+	}
+
+      for (i = 1; i < 8; ++i)
+	{
+	  do_test (i, 2 * i, 8 << i, 1, n, SMALL_CHAR);
+	  do_test (2 * i, i, 8 << i, 1, n, BIG_CHAR);
+	  do_test (i, i, 8 << i, 10, n, SMALL_CHAR);
+
+	  do_test (i, 2 * i, 8 << i, 1, SIZE_MAX, SMALL_CHAR);
+	  do_test (2 * i, i, 8 << i, 1, SIZE_MAX, BIG_CHAR);
+	  do_test (i, i, 8 << i, 10, SIZE_MAX, SMALL_CHAR);
+	}
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strncmp.c b/REORG.TODO/string/test-strncmp.c
new file mode 100644
index 0000000000..fe3c4e3320
--- /dev/null
+++ b/REORG.TODO/string/test-strncmp.c
@@ -0,0 +1,479 @@
+/* Test strncmp and wcsncmp functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifdef WIDE
+# define TEST_NAME "wcsncmp"
+#else
+# define TEST_NAME "strncmp"
+#endif
+#include "test-string.h"
+
+#ifdef WIDE
+# include <wchar.h>
+
+# define L(str) L##str
+# define STRNCMP wcsncmp
+# define STRCPY wcscpy
+# define STRDUP wcsdup
+# define MEMCPY wmemcpy
+# define SIMPLE_STRNCMP simple_wcsncmp
+# define STUPID_STRNCMP stupid_wcsncmp
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define CHARBYTES 4
+# define CHAR__MAX WCHAR_MAX
+# define CHAR__MIN WCHAR_MIN
+
+/* Wcsncmp uses signed semantics for comparison, not unsigned.
+   Avoid using substraction since possible overflow */
+int
+simple_wcsncmp (const CHAR *s1, const CHAR *s2, size_t n)
+{
+  wchar_t c1, c2;
+
+  while (n--)
+    {
+      c1 = *s1++;
+      c2 = *s2++;
+      if (c1 == L('\0') || c1 != c2)
+	return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0);
+    }
+  return 0;
+}
+
+int
+stupid_wcsncmp (const CHAR *s1, const CHAR *s2, size_t n)
+{
+  wchar_t c1, c2;
+  size_t ns1 = wcsnlen (s1, n) + 1, ns2 = wcsnlen (s2, n) + 1;
+
+  n = ns1 < n ? ns1 : n;
+  n = ns2 < n ? ns2 : n;
+
+  while (n--)
+    {
+      c1 = *s1++;
+      c2 = *s2++;
+      if (c1 != c2)
+	return c1 > c2 ? 1 : -1;
+    }
+  return 0;
+}
+
+#else
+# define L(str) str
+# define STRNCMP strncmp
+# define STRCPY strcpy
+# define STRDUP strdup
+# define MEMCPY memcpy
+# define SIMPLE_STRNCMP simple_strncmp
+# define STUPID_STRNCMP stupid_strncmp
+# define CHAR char
+# define UCHAR unsigned char
+# define CHARBYTES 1
+# define CHAR__MAX CHAR_MAX
+# define CHAR__MIN CHAR_MIN
+
+/* Strncmp uses unsigned semantics for comparison. */
+int
+simple_strncmp (const char *s1, const char *s2, size_t n)
+{
+  int ret = 0;
+
+  while (n-- && (ret = *(unsigned char *) s1 - * (unsigned char *) s2++) == 0
+	 && *s1++);
+  return ret;
+}
+
+int
+stupid_strncmp (const char *s1, const char *s2, size_t n)
+{
+  size_t ns1 = strnlen (s1, n) + 1, ns2 = strnlen (s2, n) + 1;
+  int ret = 0;
+
+  n = ns1 < n ? ns1 : n;
+  n = ns2 < n ? ns2 : n;
+  while (n-- && (ret = *(unsigned char *) s1++ - * (unsigned char *) s2++) == 0);
+  return ret;
+}
+
+#endif
+
+typedef int (*proto_t) (const CHAR *, const CHAR *, size_t);
+
+IMPL (STUPID_STRNCMP, 0)
+IMPL (SIMPLE_STRNCMP, 0)
+IMPL (STRNCMP, 1)
+
+
+static int
+check_result (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t n,
+	     int exp_result)
+{
+  int result = CALL (impl, s1, s2, n);
+  if ((exp_result == 0 && result != 0)
+      || (exp_result < 0 && result >= 0)
+      || (exp_result > 0 && result <= 0))
+    {
+      error (0, 0, "Wrong result in function %s %d %d", impl->name,
+	     result, exp_result);
+      ret = 1;
+      return -1;
+    }
+
+  return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t n,
+	     int exp_result)
+{
+  if (check_result (impl, s1, s2, n, exp_result) < 0)
+    return;
+}
+
+static void
+do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char,
+	 int exp_result)
+{
+  size_t i, align_n;
+  CHAR *s1, *s2;
+
+  align1 &= ~(CHARBYTES - 1);
+  align2 &= ~(CHARBYTES - 1);
+
+  if (n == 0)
+    {
+      s1 = (CHAR *) (buf1 + page_size);
+      s2 = (CHAR *) (buf2 + page_size);
+
+      FOR_EACH_IMPL (impl, 0)
+	do_one_test (impl, s1, s2, n, 0);
+
+      return;
+    }
+
+  align1 &= 15;
+  align2 &= 15;
+  align_n = (page_size - n * CHARBYTES) & 15;
+
+  s1 = (CHAR *) (buf1 + page_size - n * CHARBYTES);
+  s2 = (CHAR *) (buf2 + page_size - n * CHARBYTES);
+
+  if (align1 < align_n)
+    s1 = (CHAR *) ((char *) s1 - (align_n - align1));
+
+  if (align2 < align_n)
+    s2 = (CHAR *) ((char *) s2 - (align_n - align2));
+
+  for (i = 0; i < n; i++)
+    s1[i] = s2[i] = 1 + 23 * i % max_char;
+
+  if (len < n)
+    {
+      s1[len] = 0;
+      s2[len] = 0;
+      if (exp_result < 0)
+	s2[len] = 32;
+      else if (exp_result > 0)
+	s1[len] = 64;
+    }
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, s2, n, exp_result);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char,
+	 int exp_result)
+{
+  size_t i;
+  CHAR *s1, *s2;
+
+  align1 &= ~(CHARBYTES - 1);
+  align2 &= ~(CHARBYTES - 1);
+
+  if (n == 0)
+    return;
+
+  align1 &= 63;
+  if (align1 + (n + 1) * CHARBYTES >= page_size)
+    return;
+
+  align2 &= 63;
+  if (align2 + (n + 1) * CHARBYTES >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1 + align1);
+  s2 = (CHAR *) (buf2 + align2);
+
+  for (i = 0; i < n; i++)
+    s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char;
+
+  s1[n] = 24 + exp_result;
+  s2[n] = 23;
+  s1[len] = 0;
+  s2[len] = 0;
+  if (exp_result < 0)
+    s2[len] = 32;
+  else if (exp_result > 0)
+    s1[len] = 64;
+  if (len >= n)
+    s2[n - 1] -= exp_result;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, s2, n, exp_result);
+}
+
+static void
+do_page_test (size_t offset1, size_t offset2, CHAR *s2)
+{
+  CHAR *s1;
+  int exp_result;
+
+  if (offset1 * CHARBYTES  >= page_size || offset2 * CHARBYTES >= page_size)
+    return;
+
+  s1 = (CHAR *) buf1;
+  s1 += offset1;
+  s2 += offset2;
+
+  exp_result= *s1;
+
+  FOR_EACH_IMPL (impl, 0)
+    {
+      check_result (impl, s1, s2, page_size, -exp_result);
+      check_result (impl, s2, s1, page_size, exp_result);
+    }
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, pos, len1, len2, size;
+  int result;
+  long r;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size - 512 * CHARBYTES);
+  UCHAR *p2 = (UCHAR *) (buf2 + page_size - 512 * CHARBYTES);
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align1 = random () & 31;
+      if (random () & 1)
+	align2 = random () & 31;
+      else
+	align2 = align1 + (random () & 24);
+      pos = random () & 511;
+      size = random () & 511;
+      j = align1 > align2 ? align1 : align2;
+      if (pos + j >= 511)
+	pos = 510 - j - (random () & 7);
+      len1 = random () & 511;
+      if (pos >= len1 && (random () & 1))
+	len1 = pos + (random () & 7);
+      if (len1 + j >= 512)
+	len1 = 511 - j - (random () & 7);
+      if (pos >= len1)
+	len2 = len1;
+      else
+	len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
+      j = (pos > len2 ? pos : len2) + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; ++i)
+	{
+	  p1[i] = random () & 255;
+	  if (i < len1 + align1 && !p1[i])
+	    {
+	      p1[i] = random () & 255;
+	      if (!p1[i])
+		p1[i] = 1 + (random () & 127);
+	    }
+	}
+      for (i = 0; i < j; ++i)
+	{
+	  p2[i] = random () & 255;
+	  if (i < len2 + align2 && !p2[i])
+	    {
+	      p2[i] = random () & 255;
+	      if (!p2[i])
+		p2[i] = 1 + (random () & 127);
+	    }
+	}
+
+      result = 0;
+      MEMCPY (p2 + align2, p1 + align1, pos);
+      if (pos < len1)
+	{
+	  if (p2[align2 + pos] == p1[align1 + pos])
+	    {
+	      p2[align2 + pos] = random () & 255;
+	      if (p2[align2 + pos] == p1[align1 + pos])
+		p2[align2 + pos] = p1[align1 + pos] + 3 + (random () & 127);
+	    }
+
+	  if (pos < size)
+	    {
+	      if (p1[align1 + pos] < p2[align2 + pos])
+		result = -1;
+	      else
+		result = 1;
+	    }
+	}
+      p1[len1 + align1] = 0;
+      p2[len2 + align2] = 0;
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  r = CALL (impl, (CHAR *) (p1 + align1), (CHAR *) (p2 + align2), size);
+	  /* Test whether on 64-bit architectures where ABI requires
+	     callee to promote has the promotion been done.  */
+	  asm ("" : "=g" (r) : "0" (r));
+	  if ((r == 0 && result)
+	      || (r < 0 && result >= 0)
+	      || (r > 0 && result <= 0))
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p",
+		     n, impl->name, align1, align2, len1, len2, pos, size, r, result, p1, p2);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+static void
+check1 (void)
+{
+  CHAR *s1 = (CHAR *) (buf1 + 0xb2c);
+  CHAR *s2 = (CHAR *) (buf1 + 0xfd8);
+  size_t i, offset;
+  int exp_result;
+
+  STRCPY(s1, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs"));
+  STRCPY(s2, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV"));
+
+  /* Check possible overflow bug for wcsncmp */
+  s1[4] = CHAR__MAX;
+  s2[4] = CHAR__MIN;
+
+  for (offset = 0; offset < 6; offset++)
+    {
+      for (i = 0; i < 80; i++)
+	{
+	  exp_result = SIMPLE_STRNCMP (s1 + offset, s2 + offset, i);
+	  FOR_EACH_IMPL (impl, 0)
+	    check_result (impl, s1 + offset, s2 + offset, i, exp_result);
+	}
+    }
+}
+
+static void
+check2 (void)
+{
+  size_t i;
+  CHAR *s1, *s2;
+
+  s1 = (CHAR *) buf1;
+  for (i = 0; i < (page_size / CHARBYTES) - 1; i++)
+    s1[i] = 23;
+  s1[i] = 0;
+
+  s2 = STRDUP (s1);
+
+  for (i = 0; i < 64; ++i)
+    do_page_test ((3988 / CHARBYTES) + i, (2636 / CHARBYTES), s2);
+
+  free (s2);
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  check1 ();
+  check2 ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i =0; i < 16; ++i)
+    {
+      do_test (0, 0, 8, i, 127, 0);
+      do_test (0, 0, 8, i, 127, -1);
+      do_test (0, 0, 8, i, 127, 1);
+      do_test (i, i, 8, i, 127, 0);
+      do_test (i, i, 8, i, 127, 1);
+      do_test (i, i, 8, i, 127, -1);
+      do_test (i, 2 * i, 8, i, 127, 0);
+      do_test (2 * i, i, 8, i, 127, 1);
+      do_test (i, 3 * i, 8, i, 127, -1);
+      do_test (0, 0, 8, i, 255, 0);
+      do_test (0, 0, 8, i, 255, -1);
+      do_test (0, 0, 8, i, 255, 1);
+      do_test (i, i, 8, i, 255, 0);
+      do_test (i, i, 8, i, 255, 1);
+      do_test (i, i, 8, i, 255, -1);
+      do_test (i, 2 * i, 8, i, 255, 0);
+      do_test (2 * i, i, 8, i, 255, 1);
+      do_test (i, 3 * i, 8, i, 255, -1);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, 16 << i, 127, 0);
+      do_test (0, 0, 8 << i, 16 << i, 127, 1);
+      do_test (0, 0, 8 << i, 16 << i, 127, -1);
+      do_test (0, 0, 8 << i, 16 << i, 255, 0);
+      do_test (0, 0, 8 << i, 16 << i, 255, 1);
+      do_test (0, 0, 8 << i, 16 << i, 255, -1);
+      do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 0);
+      do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 1);
+      do_test (2 * i, i, 8 << i, 16 << i, 255, 0);
+      do_test (2 * i, i, 8 << i, 16 << i, 255, 1);
+    }
+
+  do_test_limit (0, 0, 0, 0, 127, 0);
+  do_test_limit (4, 0, 21, 20, 127, 0);
+  do_test_limit (0, 4, 21, 20, 127, 0);
+  do_test_limit (8, 0, 25, 24, 127, 0);
+  do_test_limit (0, 8, 25, 24, 127, 0);
+
+  for (i = 0; i < 8; ++i)
+    {
+      do_test_limit (0, 0, 17 - i, 16 - i, 127, 0);
+      do_test_limit (0, 0, 17 - i, 16 - i, 255, 0);
+      do_test_limit (0, 0, 15 - i, 16 - i, 127, 0);
+      do_test_limit (0, 0, 15 - i, 16 - i, 127, 1);
+      do_test_limit (0, 0, 15 - i, 16 - i, 127, -1);
+      do_test_limit (0, 0, 15 - i, 16 - i, 255, 0);
+      do_test_limit (0, 0, 15 - i, 16 - i, 255, 1);
+      do_test_limit (0, 0, 15 - i, 16 - i, 255, -1);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strncpy.c b/REORG.TODO/string/test-strncpy.c
new file mode 100644
index 0000000000..43f9c236f1
--- /dev/null
+++ b/REORG.TODO/string/test-strncpy.c
@@ -0,0 +1,323 @@
+/* Test strncpy functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+# define STRNLEN wcsnlen
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define MEMCMP memcmp
+# define MEMSET memset
+# define STRNLEN strnlen
+#endif /* !WIDE */
+
+
+#ifndef STRNCPY_RESULT
+# define STRNCPY_RESULT(dst, len, n) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strncpy"
+# else
+#  define TEST_NAME "wcsncpy"
+# endif /* WIDE */
+# include "test-string.h"
+# ifndef WIDE
+#  define SIMPLE_STRNCPY simple_strncpy
+#  define STUPID_STRNCPY stupid_strncpy
+#  define STRNCPY strncpy
+# else
+#  define SIMPLE_STRNCPY simple_wcsncpy
+#  define STUPID_STRNCPY stupid_wcsncpy
+#  define STRNCPY wcsncpy
+# endif /* WIDE */
+
+CHAR *SIMPLE_STRNCPY (CHAR *, const CHAR *, size_t);
+CHAR *STUPID_STRNCPY (CHAR *, const CHAR *, size_t);
+
+IMPL (STUPID_STRNCPY, 0)
+IMPL (SIMPLE_STRNCPY, 0)
+IMPL (STRNCPY, 1)
+
+CHAR *
+SIMPLE_STRNCPY (CHAR *dst, const CHAR *src, size_t n)
+{
+  CHAR *ret = dst;
+  while (n--)
+    if ((*dst++ = *src++) == '\0')
+      {
+	while (n--)
+	  *dst++ = '\0';
+	return ret;
+      }
+  return ret;
+}
+
+CHAR *
+STUPID_STRNCPY (CHAR *dst, const CHAR *src, size_t n)
+{
+  size_t nc = STRNLEN (src, n);
+  size_t i;
+
+  for (i = 0; i < nc; ++i)
+    dst[i] = src[i];
+  for (; i < n; ++i)
+    dst[i] = '\0';
+  return dst;
+}
+#endif /* !STRNCPY_RESULT */
+
+typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t);
+
+static void
+do_one_test (impl_t *impl, CHAR *dst, const CHAR *src, size_t len, size_t n)
+{
+  if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, len, n))
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     CALL (impl, dst, src, n), dst);
+      ret = 1;
+      return;
+    }
+
+  if (memcmp (dst, src, (len > n ? n : len) * sizeof (CHAR)) != 0)
+    {
+      error (0, 0, "Wrong result in function %s", impl->name);
+      ret = 1;
+      return;
+    }
+
+  if (n > len)
+    {
+      size_t i;
+
+      for (i = len; i < n; ++i)
+	if (dst [i] != '\0')
+	  {
+	    error (0, 0, "Wrong result in function %s", impl->name);
+	    ret = 1;
+	    return;
+	  }
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+  size_t i;
+  CHAR *s1, *s2;
+
+/* For wcsncpy: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)).  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+  s2 = (CHAR *) (buf2) + align2;
+
+  for (i = 0; i < len; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+  for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64;
+       ++i)
+    s1[i] = 32 + 32 * i % (max_char - 32);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s2, s1, len, n);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size, mode;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* For wcsncpy: align1 and align2 here mean align not in bytes,
+	 but in wchar_ts, in bytes it will equal to align * (sizeof
+	 (wchar_t)).  */
+
+      mode = random ();
+      if (mode & 1)
+	{
+	  size = random () & 255;
+	  align1 = 512 - size - (random () & 15);
+	  if (mode & 2)
+	    align2 = align1 - (random () & 24);
+	  else
+	    align2 = align1 - (random () & 31);
+	  if (mode & 4)
+	    {
+	      j = align1;
+	      align1 = align2;
+	      align2 = j;
+	    }
+	  if (mode & 8)
+	    len = size - (random () & 31);
+	  else
+	    len = 512;
+	  if (len >= 512)
+	    len = random () & 511;
+	}
+      else
+	{
+	  align1 = random () & 31;
+	  if (mode & 2)
+	    align2 = random () & 31;
+	  else
+	    align2 = align1 + (random () & 24);
+	  len = random () & 511;
+	  j = align1;
+	  if (align2 > j)
+	    j = align2;
+	  if (mode & 4)
+	    {
+	      size = random () & 511;
+	      if (size + j > 512)
+		size = 512 - j - (random () & 31);
+	    }
+	  else
+	    size = 512 - j;
+	  if ((mode & 8) && len + j >= 512)
+	    len = 512 - j - (random () & 7);
+	}
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  MEMSET (p2 - 64, '\1', 512 + 64);
+	  res = (UCHAR *) CALL (impl, (CHAR *) (p2 + align2),
+				(CHAR *) (p1 + align1), size);
+	  if (res != STRNCPY_RESULT (p2 + align2, len, size))
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
+		     n, impl->name, align1, align2, len, res,
+		     STRNCPY_RESULT (p2 + align2, len, size));
+	      ret = 1;
+	    }
+	  for (j = 0; j < align2 + 64; ++j)
+	    {
+	      if (p2[j - 64] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  j = align2 + len + 1;
+	  if (size + align2 > j)
+	    j = size + align2;
+	  for (; j < 512; ++j)
+	    {
+	      if (p2[j] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  for (j = align2 + len + 1; j < align2 + size; ++j)
+	    if (p2[j])
+	      {
+		error (0, 0, "Iteration %zd - garbage after size, %s (%zd, %zd, %zd)",
+		       n, impl->name, align1, align2, len);
+		ret = 1;
+		break;
+	      }
+	  j = len + 1;
+	  if (size < j)
+	    j = size;
+	  if (MEMCMP (p1 + align1, p2 + align2, j))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, 16, 16, SMALL_CHAR);
+      do_test (i, i, 16, 16, BIG_CHAR);
+      do_test (i, 2 * i, 16, 16, SMALL_CHAR);
+      do_test (2 * i, i, 16, 16, BIG_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strnlen.c b/REORG.TODO/string/test-strnlen.c
new file mode 100644
index 0000000000..e56cdb6708
--- /dev/null
+++ b/REORG.TODO/string/test-strnlen.c
@@ -0,0 +1,248 @@
+/* Test strlen functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "strnlen"
+#else
+# define TEST_NAME "wcsnlen"
+#endif /* !WIDE */
+#include "test-string.h"
+
+#ifndef WIDE
+# define STRNLEN strnlen
+# define CHAR char
+# define BIG_CHAR CHAR_MAX
+# define MIDDLE_CHAR 127
+# define SIMPLE_STRNLEN simple_strnlen
+#else
+# include <wchar.h>
+# define STRNLEN wcsnlen
+# define CHAR wchar_t
+# define BIG_CHAR WCHAR_MAX
+# define MIDDLE_CHAR 1121
+# define SIMPLE_STRNLEN simple_wcsnlen
+#endif /* !WIDE */
+
+typedef size_t (*proto_t) (const CHAR *, size_t);
+size_t SIMPLE_STRNLEN (const CHAR *, size_t);
+
+IMPL (SIMPLE_STRNLEN, 0)
+IMPL (STRNLEN, 1)
+
+size_t
+SIMPLE_STRNLEN (const CHAR *s, size_t maxlen)
+{
+  size_t i;
+
+  for (i = 0; i < maxlen && s[i]; ++i);
+  return i;
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *s, size_t maxlen, size_t exp_len)
+{
+  size_t len = CALL (impl, s, maxlen);
+  if (len != exp_len)
+    {
+      error (0, 0, "Wrong result in function %s %zd %zd", impl->name,
+	     len, exp_len);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align, size_t len, size_t maxlen, int max_char)
+{
+  size_t i;
+
+  align &= 63;
+  if ((align + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  CHAR *buf = (CHAR *) (buf1);
+
+  for (i = 0; i < len; ++i)
+    buf[align + i] = 1 + 11111 * i % max_char;
+  buf[align + len] = 0;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, (CHAR *) (buf + align), maxlen, MIN (len, maxlen));
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align, len;
+  CHAR *p = (CHAR *) (buf1 + page_size - 512 * sizeof (CHAR));
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align = random () & 15;
+      len = random () & 511;
+      if (len + align > 510)
+	len = 511 - align - (random () & 7);
+      j = len + align + 64;
+      if (j > 512)
+	j = 512;
+
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align)
+	    p[i] = 0;
+	  else
+	    {
+	      p[i] = random () & 255;
+	      if (i >= align && i < len + align && !p[i])
+		p[i] = (random () & 127) + 1;
+	    }
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  if (len > 0
+	      && CALL (impl, (CHAR *) (p + align), len - 1) != len - 1)
+	    {
+	      error (0, 0, "Iteration %zd (limited) - wrong result in function %s (%zd) %zd != %zd, p %p",
+		     n, impl->name, align,
+		     CALL (impl, (CHAR *) (p + align), len - 1), len - 1, p);
+	      ret = 1;
+	    }
+	  if (CALL (impl, (CHAR *) (p + align), len) != len)
+	    {
+	      error (0, 0, "Iteration %zd (exact) - wrong result in function %s (%zd) %zd != %zd, p %p",
+		     n, impl->name, align,
+		     CALL (impl, (CHAR *) (p + align), len), len, p);
+	      ret = 1;
+	    }
+	  if (CALL (impl, (CHAR *) (p + align), len + 1) != len)
+	    {
+	      error (0, 0, "Iteration %zd (long) - wrong result in function %s (%zd) %zd != %zd, p %p",
+		     n, impl->name, align,
+		     CALL (impl, (CHAR *) (p + align), len + 1), len, p);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+/* Tests meant to unveil fail on implementation that does not access bytes
+   around the page boundary accordingly.  */
+static void
+do_page_tests (void)
+{
+  size_t i, exp_len, start_offset, offset;
+  /* Calculate the null character offset.  */
+  size_t last_offset = (page_size / sizeof (CHAR)) - 1;
+
+  CHAR *s = (CHAR *) buf2;
+  memset (s, 65, (last_offset - 1));
+  s[last_offset] = 0;
+
+  /* Place short strings ending at page boundary.  */
+  offset = last_offset;
+  for (i = 0; i < 128; i++)
+    {
+      /* Decrease offset to stress several sizes and alignments.  */
+      offset--;
+      exp_len = last_offset - offset;
+      FOR_EACH_IMPL (impl, 0)
+        {
+          /* Varies maxlen value to cover the cases where it is:
+               - larger than length;
+               - slightly greater than length;
+               - equal to length;
+               - slightly less than length.  */
+          do_one_test (impl, (CHAR *) (s + offset), page_size, exp_len);
+          do_one_test (impl, (CHAR *) (s + offset), exp_len + 1, exp_len);
+          do_one_test (impl, (CHAR *) (s + offset), exp_len, exp_len);
+          if (exp_len > 0)
+            do_one_test (impl, (CHAR *) (s + offset), exp_len - 1, exp_len - 1);
+        }
+    }
+
+  /* Place long strings ending at page boundary.  */
+  start_offset = (last_offset + 1) / 2;
+  for (i = 0; i < 64; ++i)
+    {
+      /* Increase offset to stress several alignments.  */
+      offset = start_offset + i;
+      if (offset >= (last_offset + 1))
+        break;
+      exp_len = last_offset - offset;
+      FOR_EACH_IMPL (impl, 0)
+        {
+          /* Checks only for maxlen much larger than length because smaller
+             values are already covered in do_random_tests function.  */
+          do_one_test (impl, (CHAR *) (s + offset), page_size, exp_len);
+        }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%20s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, i, i - 1, MIDDLE_CHAR);
+      do_test (0, i, i, MIDDLE_CHAR);
+      do_test (0, i, i + 1, MIDDLE_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, i - 1, MIDDLE_CHAR);
+      do_test (i, i, i, MIDDLE_CHAR);
+      do_test (i, i, i + 1, MIDDLE_CHAR);
+    }
+
+  for (i = 2; i <= 10; ++i)
+    {
+      do_test (0, 1 << i, 5000, MIDDLE_CHAR);
+      do_test (1, 1 << i, 5000, MIDDLE_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    do_test (0, i, 5000, BIG_CHAR);
+
+  for (i = 1; i < 8; ++i)
+    do_test (i, i, 5000, BIG_CHAR);
+
+  for (i = 2; i <= 10; ++i)
+    {
+      do_test (0, 1 << i, 5000, BIG_CHAR);
+      do_test (1, 1 << i, 5000, BIG_CHAR);
+    }
+
+  do_random_tests ();
+  do_page_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strpbrk.c b/REORG.TODO/string/test-strpbrk.c
new file mode 100644
index 0000000000..4d680ab354
--- /dev/null
+++ b/REORG.TODO/string/test-strpbrk.c
@@ -0,0 +1,267 @@
+/* Test and measure strpbrk functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef WIDE
+# define CHAR char
+# define UCHAR unsigned char
+# define STRLEN strlen
+# define STRCHR strchr
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+#else
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define STRLEN wcslen
+# define STRCHR wcschr
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+#endif /* WIDE */
+
+#ifndef STRPBRK_RESULT
+# define STRPBRK_RESULT(s, pos) ((s)[(pos)] ? (s) + (pos) : NULL)
+# define RES_TYPE CHAR *
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strpbrk"
+# else
+#  define TEST_NAME "wcspbrk"
+# endif /* WIDE */
+# include "test-string.h"
+
+# ifndef WIDE
+#  define STRPBRK strpbrk
+#  define SIMPLE_STRPBRK simple_strpbrk
+#  define STUPID_STRPBRK stupid_strpbrk
+# else
+#  include <wchar.h>
+#  define STRPBRK wcspbrk
+#  define SIMPLE_STRPBRK simple_wcspbrk
+#  define STUPID_STRPBRK stupid_wcspbrk
+# endif /* WIDE */
+
+typedef CHAR *(*proto_t) (const CHAR *, const CHAR *);
+CHAR *SIMPLE_STRPBRK (const CHAR *, const CHAR *);
+CHAR *STUPID_STRPBRK (const CHAR *, const CHAR *);
+
+IMPL (STUPID_STRPBRK, 0)
+IMPL (SIMPLE_STRPBRK, 0)
+IMPL (STRPBRK, 1)
+
+CHAR *
+SIMPLE_STRPBRK (const CHAR *s, const CHAR *rej)
+{
+  const CHAR *r;
+  CHAR c;
+
+  while ((c = *s++) != '\0')
+    for (r = rej; *r != '\0'; ++r)
+      if (*r == c)
+	return (CHAR *) s - 1;
+  return NULL;
+}
+
+CHAR *
+STUPID_STRPBRK (const CHAR *s, const CHAR *rej)
+{
+  size_t ns = STRLEN (s), nrej = STRLEN (rej);
+  size_t i, j;
+
+  for (i = 0; i < ns; ++i)
+    for (j = 0; j < nrej; ++j)
+      if (s[i] == rej[j])
+	return (CHAR *) s + i;
+  return NULL;
+}
+#endif /* !STRPBRK_RESULT */
+
+static void
+do_one_test (impl_t *impl, const CHAR *s, const CHAR *rej, RES_TYPE exp_res)
+{
+  RES_TYPE res = CALL (impl, s, rej);
+  if (res != exp_res)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     (void *) res, (void *) exp_res);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align, size_t pos, size_t len)
+{
+  size_t i;
+  int c;
+  RES_TYPE result;
+  CHAR *rej, *s;
+
+  align &= 7;
+  if ((align + pos + 10) * sizeof (CHAR) >= page_size || len > 240)
+    return;
+
+  rej = (CHAR *) (buf2) + (random () & 255);
+  s = (CHAR *) (buf1) + align;
+
+  for (i = 0; i < len; ++i)
+    {
+      rej[i] = random () & BIG_CHAR;
+      if (!rej[i])
+	rej[i] = random () & BIG_CHAR;
+      if (!rej[i])
+	rej[i] = 1 + (random () & SMALL_CHAR);
+    }
+  rej[len] = '\0';
+  for (c = 1; c <= BIG_CHAR; ++c)
+    if (STRCHR (rej, c) == NULL)
+      break;
+
+  for (i = 0; i < pos; ++i)
+    {
+      s[i] = random () & BIG_CHAR;
+      if (STRCHR (rej, s[i]))
+	{
+	  s[i] = random () & BIG_CHAR;
+	  if (STRCHR (rej, s[i]))
+	    s[i] = c;
+	}
+    }
+  s[pos] = rej[random () % (len + 1)];
+  if (s[pos])
+    {
+      for (i = pos + 1; i < pos + 10; ++i)
+	s[i] = random () & BIG_CHAR;
+      s[i] = '\0';
+    }
+  result = STRPBRK_RESULT (s, pos);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s, rej, result);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align, pos, len, rlen;
+  RES_TYPE result;
+  int c;
+  UCHAR *p = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *rej;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align = random () & 15;
+      pos = random () & 511;
+      if (pos + align >= 511)
+	pos = 510 - align - (random () & 7);
+      len = random () & 511;
+      if (pos >= len && (random () & 1))
+	len = pos + 1 + (random () & 7);
+      if (len + align >= 512)
+	len = 511 - align - (random () & 7);
+      if (random () & 1)
+	rlen = random () & 63;
+      else
+	rlen = random () & 15;
+      rej = (UCHAR *) (buf2 + page_size) - rlen - 1 - (random () & 7);
+      for (i = 0; i < rlen; ++i)
+	{
+	  rej[i] = random () & BIG_CHAR;
+	  if (!rej[i])
+	    rej[i] = random () & BIG_CHAR;
+	  if (!rej[i])
+	    rej[i] = 1 + (random () & SMALL_CHAR);
+	}
+      rej[i] = '\0';
+      for (c = 1; c <= BIG_CHAR; ++c)
+	if (STRCHR ((CHAR *) rej, c) == NULL)
+	  break;
+      j = (pos > len ? pos : len) + align + 64;
+      if (j > 512)
+	j = 512;
+
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align)
+	    p[i] = '\0';
+	  else if (i == pos + align)
+	    p[i] = rej[random () % (rlen + 1)];
+	  else if (i < align || i > pos + align)
+	    p[i] = random () & BIG_CHAR;
+	  else
+	    {
+	      p[i] = random () & BIG_CHAR;
+	      if (STRCHR ((CHAR *) rej, p[i]))
+		{
+		  p[i] = random () & BIG_CHAR;
+		  if (STRCHR ((CHAR *) rej, p[i]))
+		    p[i] = c;
+		}
+	    }
+	}
+
+      result = STRPBRK_RESULT ((CHAR *) (p + align), pos < len ? pos : len);
+
+      FOR_EACH_IMPL (impl, 1)
+	if (CALL (impl, (CHAR *) (p + align), (CHAR *) rej) != result)
+	  {
+	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %p, %zd, %zd, %zd) %p != %p",
+		   n, impl->name, align, rej, rlen, pos, len,
+		   (void *) CALL (impl, (CHAR *) (p + align), (CHAR *) rej),
+		   (void *) result);
+	    ret = 1;
+	  }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%32s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < 32; ++i)
+    {
+      do_test (0, 512, i);
+      do_test (i, 512, i);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 16 << i, 4);
+      do_test (i, 16 << i, 4);
+    }
+
+  for (i = 1; i < 8; ++i)
+    do_test (i, 64, 10);
+
+  for (i = 0; i < 64; ++i)
+    do_test (0, i, 6);
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strrchr.c b/REORG.TODO/string/test-strrchr.c
new file mode 100644
index 0000000000..10c070aef1
--- /dev/null
+++ b/REORG.TODO/string/test-strrchr.c
@@ -0,0 +1,247 @@
+/* Test and measure STRCHR functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+   Added wcsrrchr support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>,
+   2011.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifdef WIDE
+# define TEST_NAME "wcsrchr"
+#else
+# define TEST_NAME "strrchr"
+#endif
+#include "test-string.h"
+
+#ifdef WIDE
+# include <wchar.h>
+# define SIMPLE_STRRCHR simple_wcsrchr
+# define STRRCHR wcsrchr
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+#else
+# define SIMPLE_STRRCHR simple_strrchr
+# define STRRCHR strrchr
+# define CHAR char
+# define UCHAR unsigned char
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+#endif
+
+typedef CHAR *(*proto_t) (const CHAR *, int);
+CHAR *SIMPLE_STRRCHR (const CHAR *, int);
+
+IMPL (SIMPLE_STRRCHR, 0)
+IMPL (STRRCHR, 1)
+
+CHAR *
+SIMPLE_STRRCHR (const CHAR *s, int c)
+{
+  const CHAR *ret = NULL;
+
+  for (; *s != '\0'; ++s)
+    if (*s == (CHAR) c)
+      ret = s;
+
+  return (CHAR *) (c == '\0' ? s : ret);
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *s, int c, CHAR *exp_res)
+{
+  CHAR *res = CALL (impl, s, c);
+  if (res != exp_res)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     res, exp_res);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
+/* For wcsrchr: align here means align not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+{
+  size_t i;
+  CHAR *result;
+  CHAR *buf = (CHAR *) buf1;
+
+  align &= 7;
+  if ( (align + len) * sizeof(CHAR) >= page_size)
+    return;
+
+  for (i = 0; i < len; ++i)
+    {
+      buf[align + i] = (random () * random ()) & max_char;
+      if (!buf[align + i])
+	buf[align + i] = (random () * random ()) & max_char;
+      if (!buf[align + i])
+	buf[align + i] = 1;
+      if ((i > pos || pos >= len) && buf[align + i] == seek_char)
+	buf[align + i] = seek_char + 10 + (random () & 15);
+    }
+  buf[align + len] = 0;
+
+  if (pos < len)
+    {
+      buf[align + pos] = seek_char;
+      result = (CHAR *) (buf + align + pos);
+    }
+  else if (seek_char == 0)
+    result = (CHAR *) (buf + align + len);
+  else
+    result = NULL;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, (CHAR *) (buf + align), seek_char, result);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align, pos, len;
+  int seek_char;
+  CHAR *result;
+  UCHAR *p = (UCHAR *) (buf1 + page_size) - 512;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align = random () & (63 / sizeof(CHAR));
+      /* For wcsrchr: align here means align not in bytes, but in wchar_ts,
+	 in bytes it will equal to align * (sizeof (wchar_t)).
+	 For strrchr we need to check all alignments from 0 to 63 since
+	 some assembly implementations have separate prolog for alignments
+	 more 48. */
+      pos = random () & 511;
+      if (pos + align >= 511)
+	pos = 510 - align - (random () & 7);
+      len = random () & 511;
+      /* len for wcschr here isn't in bytes but it's number of wchar_t
+	 symbols.  */
+      if (pos >= len)
+	len = pos + (random () & 7);
+      if (len + align >= 512)
+	len = 511 - align - (random () & 7);
+      seek_char = random () & 255;
+      if (seek_char && pos == len)
+	{
+	  if (pos)
+	    --pos;
+	  else
+	    ++len;
+	}
+      j = len + align + 64;
+      if (j > 512)
+	j = 512;
+
+      for (i = 0; i < j; i++)
+	{
+	  if (i == pos + align)
+	    p[i] = seek_char;
+	  else if (i == len + align)
+	    p[i] = 0;
+	  else
+	    {
+	      p[i] = random () & 255;
+	      if (((i > pos + align && i < len + align) || pos > len)
+		  && p[i] == seek_char)
+		p[i] = seek_char + 13;
+	      if (i < len + align && !p[i])
+		{
+		  p[i] = seek_char - 13;
+		  if (!p[i])
+		    p[i] = 140;
+		}
+	    }
+	}
+
+      if (pos <= len)
+	result = (CHAR *) (p + pos + align);
+      else if (seek_char == 0)
+	result = (CHAR *) (p + len + align);
+      else
+	result = NULL;
+
+      FOR_EACH_IMPL (impl, 1)
+	if (CALL (impl, (CHAR *) (p + align), seek_char) != result)
+	  {
+	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
+		   n, impl->name, align, seek_char, len, pos,
+		   CALL (impl, (CHAR *) (p + align), seek_char), result, p);
+	    ret = 1;
+	  }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%20s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 16 << i, 2048, 23, SMALL_CHAR);
+      do_test (i, 16 << i, 2048, 23, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 64, 256, 23, SMALL_CHAR);
+      do_test (i, 64, 256, 23, BIG_CHAR);
+    }
+
+  for (i = 0; i < 32; ++i)
+    {
+      do_test (0, i, i + 1, 23, SMALL_CHAR);
+      do_test (0, i, i + 1, 23, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 16 << i, 2048, 0, SMALL_CHAR);
+      do_test (i, 16 << i, 2048, 0, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 64, 256, 0, SMALL_CHAR);
+      do_test (i, 64, 256, 0, BIG_CHAR);
+    }
+
+  for (i = 0; i < 32; ++i)
+    {
+      do_test (0, i, i + 1, 0, SMALL_CHAR);
+      do_test (0, i, i + 1, 0, BIG_CHAR);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strspn.c b/REORG.TODO/string/test-strspn.c
new file mode 100644
index 0000000000..d26331fb6d
--- /dev/null
+++ b/REORG.TODO/string/test-strspn.c
@@ -0,0 +1,245 @@
+/* Test and measure strspn functions.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifndef WIDE
+# define TEST_NAME "strspn"
+#else
+# define TEST_NAME "wcsspn"
+#endif /* WIDE */
+#include "test-string.h"
+
+#ifndef WIDE
+# define STRSPN strspn
+# define CHAR char
+# define UCHAR unsigned char
+# define SIMPLE_STRSPN simple_strspn
+# define STUPID_STRSPN stupid_strspn
+# define STRLEN strlen
+# define STRCHR strchr
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+#else
+# include <wchar.h>
+# define STRSPN wcsspn
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define SIMPLE_STRSPN simple_wcsspn
+# define STUPID_STRSPN stupid_wcsspn
+# define STRLEN wcslen
+# define STRCHR wcschr
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+#endif /* WIDE */
+
+typedef size_t (*proto_t) (const CHAR *, const CHAR *);
+size_t SIMPLE_STRSPN (const CHAR *, const CHAR *);
+size_t STUPID_STRSPN (const CHAR *, const CHAR *);
+
+IMPL (STUPID_STRSPN, 0)
+IMPL (SIMPLE_STRSPN, 0)
+IMPL (STRSPN, 1)
+
+size_t
+SIMPLE_STRSPN (const CHAR *s, const CHAR *acc)
+{
+  const CHAR *r, *str = s;
+  CHAR c;
+
+  while ((c = *s++) != '\0')
+    {
+      for (r = acc; *r != '\0'; ++r)
+	if (*r == c)
+	  break;
+      if (*r == '\0')
+	return s - str - 1;
+    }
+  return s - str - 1;
+}
+
+size_t
+STUPID_STRSPN (const CHAR *s, const CHAR *acc)
+{
+  size_t ns = STRLEN (s), nacc = STRLEN (acc);
+  size_t i, j;
+
+  for (i = 0; i < ns; ++i)
+    {
+      for (j = 0; j < nacc; ++j)
+	if (s[i] == acc[j])
+	  break;
+      if (j == nacc)
+	return i;
+    }
+  return i;
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *s, const CHAR *acc, size_t exp_res)
+{
+  size_t res = CALL (impl, s, acc);
+  if (res != exp_res)
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     (void *) res, (void *) exp_res);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align, size_t pos, size_t len)
+{
+  size_t i;
+  CHAR *acc, *s;
+
+  align &= 7;
+  if ((align + pos + 10) * sizeof (CHAR) >= page_size || len > 240 || ! len)
+    return;
+
+  acc = (CHAR *) (buf2) + (random () & 255);
+  s = (CHAR *) (buf1) + align;
+
+  for (i = 0; i < len; ++i)
+    {
+      acc[i] = random () & BIG_CHAR;
+      if (!acc[i])
+	acc[i] = random () & BIG_CHAR;
+      if (!acc[i])
+	acc[i] = 1 + (random () & SMALL_CHAR);
+    }
+  acc[len] = '\0';
+
+  for (i = 0; i < pos; ++i)
+    s[i] = acc[random () % len];
+  s[pos] = random () & BIG_CHAR;
+  if (STRCHR (acc, s[pos]))
+    s[pos] = '\0';
+  else
+    {
+      for (i = pos + 1; i < pos + 10; ++i)
+	s[i] = random () & BIG_CHAR;
+      s[i] = '\0';
+    }
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s, acc, pos);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align, pos, alen, len;
+  UCHAR *p = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *acc;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align = random () & 15;
+      if (random () & 1)
+	alen = random () & 63;
+      else
+	alen = random () & 15;
+      if (!alen)
+	pos = 0;
+      else
+	pos = random () & 511;
+      if (pos + align >= 511)
+	pos = 510 - align - (random () & 7);
+      len = random () & 511;
+      if (len + align >= 512)
+	len = 511 - align - (random () & 7);
+      acc = (UCHAR *) (buf2 + page_size) - alen - 1 - (random () & 7);
+      for (i = 0; i < alen; ++i)
+	{
+	  acc[i] = random () & BIG_CHAR;
+	  if (!acc[i])
+	    acc[i] = random () & BIG_CHAR;
+	  if (!acc[i])
+	    acc[i] = 1 + (random () & SMALL_CHAR);
+	}
+      acc[i] = '\0';
+      j = (pos > len ? pos : len) + align + 64;
+      if (j > 512)
+	j = 512;
+
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align)
+	    p[i] = '\0';
+	  else if (i == pos + align)
+	    {
+	      p[i] = random () & BIG_CHAR;
+	      if (STRCHR ((CHAR *) acc, p[i]))
+		p[i] = '\0';
+	    }
+	  else if (i < align || i > pos + align)
+	    p[i] = random () & BIG_CHAR;
+	  else
+	    p[i] = acc [random () % alen];
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	if (CALL (impl, (CHAR *) (p + align),
+		  (CHAR *) acc) != (pos < len ? pos : len))
+	  {
+	    error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %p, %zd, %zd, %zd) %zd != %zd",
+		   n, impl->name, align, acc, alen, pos, len,
+		   CALL (impl, (CHAR *) (p + align), (CHAR *) acc),
+		   (pos < len ? pos : len));
+	    ret = 1;
+	  }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%32s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < 32; ++i)
+    {
+      do_test (0, 512, i);
+      do_test (i, 512, i);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 16 << i, 4);
+      do_test (i, 16 << i, 4);
+    }
+
+  for (i = 1; i < 8; ++i)
+    do_test (i, 64, 10);
+
+  for (i = 0; i < 64; ++i)
+    do_test (0, i, 6);
+
+  do_random_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/test-strstr.c b/REORG.TODO/string/test-strstr.c
new file mode 100644
index 0000000000..33f221149a
--- /dev/null
+++ b/REORG.TODO/string/test-strstr.c
@@ -0,0 +1,212 @@
+/* Test and measure strstr functions.
+   Copyright (C) 2010-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2010.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#define TEST_NAME "strstr"
+#include "test-string.h"
+
+
+#define STRSTR simple_strstr
+#define libc_hidden_builtin_def(arg) /* nothing */
+#include "strstr.c"
+
+
+static char *
+stupid_strstr (const char *s1, const char *s2)
+{
+  ssize_t s1len = strlen (s1);
+  ssize_t s2len = strlen (s2);
+
+  if (s2len > s1len)
+    return NULL;
+
+  for (ssize_t i = 0; i <= s1len - s2len; ++i)
+    {
+      size_t j;
+      for (j = 0; j < s2len; ++j)
+	if (s1[i + j] != s2[j])
+	  break;
+      if (j == s2len)
+	return (char *) s1 + i;
+    }
+
+  return NULL;
+}
+
+
+typedef char *(*proto_t) (const char *, const char *);
+
+IMPL (stupid_strstr, 0)
+IMPL (simple_strstr, 0)
+IMPL (strstr, 1)
+
+
+static int
+check_result (impl_t *impl, const char *s1, const char *s2,
+	      char *exp_result)
+{
+  char *result = CALL (impl, s1, s2);
+  if (result != exp_result)
+    {
+      error (0, 0, "Wrong result in function %s %s %s", impl->name,
+	     result, exp_result);
+      ret = 1;
+      return -1;
+    }
+
+  return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+{
+  if (check_result (impl, s1, s2, exp_result) < 0)
+    return;
+}
+
+
+static void
+do_test (size_t align1, size_t align2, size_t len1, size_t len2,
+	 int fail)
+{
+  char *s1 = (char *) (buf1 + align1);
+  char *s2 = (char *) (buf2 + align2);
+
+  static const char d[] = "1234567890abcdef";
+#define dl (sizeof (d) - 1)
+  char *ss2 = s2;
+  for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
+    {
+      size_t t = l > dl ? dl : l;
+      ss2 = mempcpy (ss2, d, t);
+    }
+  s2[len2] = '\0';
+
+  if (fail)
+    {
+      char *ss1 = s1;
+      for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
+	{
+	  size_t t = l > dl ? dl : l;
+	  memcpy (ss1, d, t);
+	  ++ss1[len2 > 7 ? 7 : len2 - 1];
+	  ss1 += t;
+	}
+    }
+  else
+    {
+      memset (s1, '0', len1);
+      memcpy (s1 + len1 - len2, s2, len2);
+    }
+  s1[len1] = '\0';
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2);
+
+}
+
+static void
+check1 (void)
+{
+  const char s1[] =
+    "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_A7_20_EF_BF_BD";
+  const char s2[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
+  char *exp_result;
+
+  exp_result = stupid_strstr (s1, s2);
+  FOR_EACH_IMPL (impl, 0)
+    check_result (impl, s1, s2, exp_result);
+}
+
+static void
+check2 (void)
+{
+  const char s1[] = ", enable_static, \0, enable_shared, ";
+  char *exp_result;
+  char *s2 = (void *) buf1 + page_size - 18;
+
+  strcpy (s2, s1);
+  exp_result = stupid_strstr (s1, s1 + 18);
+  FOR_EACH_IMPL (impl, 0)
+    {
+      check_result (impl, s1, s1 + 18, exp_result);
+      check_result (impl, s2, s1 + 18, exp_result);
+    }
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  check1 ();
+  check2 ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (size_t klen = 2; klen < 32; ++klen)
+    for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
+      {
+	do_test (0, 0, hlen, klen, 0);
+	do_test (0, 0, hlen, klen, 1);
+	do_test (0, 3, hlen, klen, 0);
+	do_test (0, 3, hlen, klen, 1);
+	do_test (0, 9, hlen, klen, 0);
+	do_test (0, 9, hlen, klen, 1);
+	do_test (0, 15, hlen, klen, 0);
+	do_test (0, 15, hlen, klen, 1);
+
+	do_test (3, 0, hlen, klen, 0);
+	do_test (3, 0, hlen, klen, 1);
+	do_test (3, 3, hlen, klen, 0);
+	do_test (3, 3, hlen, klen, 1);
+	do_test (3, 9, hlen, klen, 0);
+	do_test (3, 9, hlen, klen, 1);
+	do_test (3, 15, hlen, klen, 0);
+	do_test (3, 15, hlen, klen, 1);
+
+	do_test (9, 0, hlen, klen, 0);
+	do_test (9, 0, hlen, klen, 1);
+	do_test (9, 3, hlen, klen, 0);
+	do_test (9, 3, hlen, klen, 1);
+	do_test (9, 9, hlen, klen, 0);
+	do_test (9, 9, hlen, klen, 1);
+	do_test (9, 15, hlen, klen, 0);
+	do_test (9, 15, hlen, klen, 1);
+
+	do_test (15, 0, hlen, klen, 0);
+	do_test (15, 0, hlen, klen, 1);
+	do_test (15, 3, hlen, klen, 0);
+	do_test (15, 3, hlen, klen, 1);
+	do_test (15, 9, hlen, klen, 0);
+	do_test (15, 9, hlen, klen, 1);
+	do_test (15, 15, hlen, klen, 0);
+	do_test (15, 15, hlen, klen, 1);
+      }
+
+  do_test (0, 0, page_size - 1, 16, 0);
+  do_test (0, 0, page_size - 1, 16, 1);
+
+  return ret;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/testcopy.c b/REORG.TODO/string/testcopy.c
new file mode 100644
index 0000000000..8c9dd4c500
--- /dev/null
+++ b/REORG.TODO/string/testcopy.c
@@ -0,0 +1,107 @@
+/* Copyright (C) 1990-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+
+int
+main (void)
+{
+  char *mem, *memp;
+  char *rand_mem;
+  char *lo_around, *hi_around;
+  int size, max_size;
+  int src_off, dst_off;
+  int i;
+  int space_around = 10;
+
+  max_size = 256;
+
+  mem = malloc (max_size + 2 * max_size + 2 * space_around);
+  rand_mem = malloc (max_size);
+  lo_around = malloc (space_around);
+  hi_around = malloc (space_around);
+  memp = mem + space_around;
+
+  /* Fill RAND_MEM with random bytes, each non-zero.  */
+  for (i = 0; i < max_size; i++)
+    {
+      int x;
+      do
+	x = random ();
+      while (x == 0);
+      rand_mem[i] = x;
+    }
+
+  for (size = 0; size < max_size; size++)
+    {
+      printf("phase %d\n", size);
+      for (src_off = 0; src_off <= 16; src_off++)
+	{
+	  for (dst_off = 0; dst_off <= 16; dst_off++)
+	    {
+	      /* Put zero around the intended destination, to check
+		 that it's not clobbered.  */
+	      for (i = 1; i < space_around; i++)
+		{
+		  memp[dst_off - i] = 0;
+		  memp[dst_off + size - 1 + i] = 0;
+		}
+
+	      /* Fill the source area with known contents.  */
+	      for (i = 0; i < size; i++)
+		memp[src_off + i] = rand_mem[i];
+
+	      /* Remember the contents around the destination area.
+		 (It might not be what we wrote some lines above, since
+		 the src area and the dst area overlap.)  */
+	      for (i = 1; i < space_around; i++)
+		{
+		  lo_around[i] = memp[dst_off - i];
+		  hi_around[i] = memp[dst_off + size - 1 + i];
+		}
+
+	      memmove (memp + dst_off, memp + src_off, size);
+
+	      /* Check that the destination area has the same
+		 contents we wrote to the source area.  */
+	      for (i = 0; i < size; i++)
+		{
+		  if (memp[dst_off + i] != rand_mem[i])
+		    abort ();
+		}
+
+	      /* Check that the area around the destination is not
+		 clobbered.  */
+	      for (i = 1; i < space_around; i++)
+		{
+		  if (memp[dst_off - i] != lo_around[i])
+		    abort ();
+		  if (memp[dst_off + size - 1 + i] != hi_around[i])
+		    abort ();
+		}
+	    }
+	}
+    }
+
+  puts ("Test succeeded.");
+
+  return 0;
+}
diff --git a/REORG.TODO/string/tester.c b/REORG.TODO/string/tester.c
new file mode 100644
index 0000000000..4b928b4f5e
--- /dev/null
+++ b/REORG.TODO/string/tester.c
@@ -0,0 +1,1685 @@
+/* Tester for string functions.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+/* Make sure we don't test the optimized inline functions if we want to
+   test the real implementation.  */
+#if !defined DO_STRING_INLINES
+#undef __USE_STRING_INLINES
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <fcntl.h>
+#include <libc-diag.h>
+
+
+#define	STREQ(a, b)	(strcmp((a), (b)) == 0)
+
+const char *it = "<UNSET>";	/* Routine name for message routines. */
+size_t errors = 0;
+
+/* Complain if condition is not true.  */
+static void
+check (int thing, int number)
+{
+  if (!thing)
+    {
+      printf ("%s flunked test %d\n", it, number);
+      ++errors;
+    }
+}
+
+/* Complain if first two args don't strcmp as equal.  */
+static void
+equal (const char *a, const char *b, int number)
+{
+  check (a != NULL && b != NULL && STREQ (a, b), number);
+}
+
+char one[50];
+char two[50];
+char *cp;
+
+static void
+test_strcmp (void)
+{
+  it = "strcmp";
+  check (strcmp ("", "") == 0, 1);		/* Trivial case. */
+  check (strcmp ("a", "a") == 0, 2);		/* Identity. */
+  check (strcmp ("abc", "abc") == 0, 3);	/* Multicharacter. */
+  check (strcmp ("abc", "abcd") < 0, 4);	/* Length mismatches. */
+  check (strcmp ("abcd", "abc") > 0, 5);
+  check (strcmp ("abcd", "abce") < 0, 6);	/* Honest miscompares. */
+  check (strcmp ("abce", "abcd") > 0, 7);
+  check (strcmp ("a\203", "a") > 0, 8);		/* Tricky if char signed. */
+  check (strcmp ("a\203", "a\003") > 0, 9);
+
+  {
+    char buf1[0x40], buf2[0x40];
+    int i, j;
+    for (i=0; i < 0x10; i++)
+      for (j = 0; j < 0x10; j++)
+	{
+	  int k;
+	  for (k = 0; k < 0x3f; k++)
+	    {
+	      buf1[k] = '0' ^ (k & 4);
+	      buf2[k] = '4' ^ (k & 4);
+	    }
+	  buf1[i] = buf1[0x3f] = 0;
+	  buf2[j] = buf2[0x3f] = 0;
+	  for (k = 0; k < 0xf; k++)
+	    {
+	      int cnum = 0x10+0x10*k+0x100*j+0x1000*i;
+	      check (strcmp (buf1+i,buf2+j) == 0, cnum);
+	      buf1[i+k] = 'A' + i + k;
+	      buf1[i+k+1] = 0;
+	      check (strcmp (buf1+i,buf2+j) > 0, cnum+1);
+	      check (strcmp (buf2+j,buf1+i) < 0, cnum+2);
+	      buf2[j+k] = 'B' + i + k;
+	      buf2[j+k+1] = 0;
+	      check (strcmp (buf1+i,buf2+j) < 0, cnum+3);
+	      check (strcmp (buf2+j,buf1+i) > 0, cnum+4);
+	      buf2[j+k] = 'A' + i + k;
+	      buf1[i] = 'A' + i + 0x80;
+	      check (strcmp (buf1+i,buf2+j) > 0, cnum+5);
+	      check (strcmp (buf2+j,buf1+i) < 0, cnum+6);
+	      buf1[i] = 'A' + i;
+	    }
+	}
+  }
+}
+
+#define SIMPLE_COPY(fn, n, str, ntest) \
+  do {									      \
+    int __n;								      \
+    char *cp;								      \
+    for (__n = 0; __n < (int) sizeof (one); ++__n)			      \
+      one[__n] = 'Z';							      \
+    fn (one, str);							      \
+    for (cp = one, __n = 0; __n < n; ++__n, ++cp)			      \
+      check (*cp == '0' + (n % 10), ntest);				      \
+    check (*cp == '\0', ntest);						      \
+  } while (0)
+
+static void
+test_strcpy (void)
+{
+  int i;
+  it = "strcpy";
+  check (strcpy (one, "abcd") == one, 1); /* Returned value. */
+  equal (one, "abcd", 2);		/* Basic test. */
+
+  (void) strcpy (one, "x");
+  equal (one, "x", 3);			/* Writeover. */
+  equal (one+2, "cd", 4);		/* Wrote too much? */
+
+  (void) strcpy (two, "hi there");
+  (void) strcpy (one, two);
+  equal (one, "hi there", 5);		/* Basic test encore. */
+  equal (two, "hi there", 6);		/* Stomped on source? */
+
+  (void) strcpy (one, "");
+  equal (one, "", 7);			/* Boundary condition. */
+
+  for (i = 0; i < 16; i++)
+    {
+      (void) strcpy (one + i, "hi there");	/* Unaligned destination. */
+      equal (one + i, "hi there", 8 + (i * 2));
+      (void) strcpy (two, one + i);		/* Unaligned source. */
+      equal (two, "hi there", 9 + (i * 2));
+    }
+
+  SIMPLE_COPY(strcpy, 0, "", 41);
+  SIMPLE_COPY(strcpy, 1, "1", 42);
+  SIMPLE_COPY(strcpy, 2, "22", 43);
+  SIMPLE_COPY(strcpy, 3, "333", 44);
+  SIMPLE_COPY(strcpy, 4, "4444", 45);
+  SIMPLE_COPY(strcpy, 5, "55555", 46);
+  SIMPLE_COPY(strcpy, 6, "666666", 47);
+  SIMPLE_COPY(strcpy, 7, "7777777", 48);
+  SIMPLE_COPY(strcpy, 8, "88888888", 49);
+  SIMPLE_COPY(strcpy, 9, "999999999", 50);
+  SIMPLE_COPY(strcpy, 10, "0000000000", 51);
+  SIMPLE_COPY(strcpy, 11, "11111111111", 52);
+  SIMPLE_COPY(strcpy, 12, "222222222222", 53);
+  SIMPLE_COPY(strcpy, 13, "3333333333333", 54);
+  SIMPLE_COPY(strcpy, 14, "44444444444444", 55);
+  SIMPLE_COPY(strcpy, 15, "555555555555555", 56);
+  SIMPLE_COPY(strcpy, 16, "6666666666666666", 57);
+
+  /* Simple test using implicitly coerced `void *' arguments.  */
+  const void *src = "frobozz";
+  void *dst = one;
+  check (strcpy (dst, src) == dst, 1);
+  equal (dst, "frobozz", 2);
+}
+
+static void
+test_stpcpy (void)
+{
+  it = "stpcpy";
+  check ((stpcpy (one, "a") - one) == 1, 1);
+  equal (one, "a", 2);
+
+  check ((stpcpy (one, "ab") - one) == 2, 3);
+  equal (one, "ab", 4);
+
+  check ((stpcpy (one, "abc") - one) == 3, 5);
+  equal (one, "abc", 6);
+
+  check ((stpcpy (one, "abcd") - one) == 4, 7);
+  equal (one, "abcd", 8);
+
+  check ((stpcpy (one, "abcde") - one) == 5, 9);
+  equal (one, "abcde", 10);
+
+  check ((stpcpy (one, "abcdef") - one) == 6, 11);
+  equal (one, "abcdef", 12);
+
+  check ((stpcpy (one, "abcdefg") - one) == 7, 13);
+  equal (one, "abcdefg", 14);
+
+  check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
+  equal (one, "abcdefgh", 16);
+
+  check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
+  equal (one, "abcdefghi", 18);
+
+  check ((stpcpy (one, "x") - one) == 1, 19);
+  equal (one, "x", 20);			/* Writeover. */
+  equal (one+2, "cdefghi", 21);		/* Wrote too much? */
+
+  check ((stpcpy (one, "xx") - one) == 2, 22);
+  equal (one, "xx", 23);		/* Writeover. */
+  equal (one+3, "defghi", 24);		/* Wrote too much? */
+
+  check ((stpcpy (one, "xxx") - one) == 3, 25);
+  equal (one, "xxx", 26);		/* Writeover. */
+  equal (one+4, "efghi", 27);		/* Wrote too much? */
+
+  check ((stpcpy (one, "xxxx") - one) == 4, 28);
+  equal (one, "xxxx", 29);		/* Writeover. */
+  equal (one+5, "fghi", 30);		/* Wrote too much? */
+
+  check ((stpcpy (one, "xxxxx") - one) == 5, 31);
+  equal (one, "xxxxx", 32);		/* Writeover. */
+  equal (one+6, "ghi", 33);		/* Wrote too much? */
+
+  check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
+  equal (one, "xxxxxx", 35);		/* Writeover. */
+  equal (one+7, "hi", 36);		/* Wrote too much? */
+
+  check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
+  equal (one, "xxxxxxx", 38);		/* Writeover. */
+  equal (one+8, "i", 39);		/* Wrote too much? */
+
+  check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
+  equal (one, "abc", 41);
+  equal (one + 4, "xxx", 42);
+
+  SIMPLE_COPY(stpcpy, 0, "", 43);
+  SIMPLE_COPY(stpcpy, 1, "1", 44);
+  SIMPLE_COPY(stpcpy, 2, "22", 45);
+  SIMPLE_COPY(stpcpy, 3, "333", 46);
+  SIMPLE_COPY(stpcpy, 4, "4444", 47);
+  SIMPLE_COPY(stpcpy, 5, "55555", 48);
+  SIMPLE_COPY(stpcpy, 6, "666666", 49);
+  SIMPLE_COPY(stpcpy, 7, "7777777", 50);
+  SIMPLE_COPY(stpcpy, 8, "88888888", 51);
+  SIMPLE_COPY(stpcpy, 9, "999999999", 52);
+  SIMPLE_COPY(stpcpy, 10, "0000000000", 53);
+  SIMPLE_COPY(stpcpy, 11, "11111111111", 54);
+  SIMPLE_COPY(stpcpy, 12, "222222222222", 55);
+  SIMPLE_COPY(stpcpy, 13, "3333333333333", 56);
+  SIMPLE_COPY(stpcpy, 14, "44444444444444", 57);
+  SIMPLE_COPY(stpcpy, 15, "555555555555555", 58);
+  SIMPLE_COPY(stpcpy, 16, "6666666666666666", 59);
+}
+
+static void
+test_stpncpy (void)
+{
+  it = "stpncpy";
+  memset (one, 'x', sizeof (one));
+  check (stpncpy (one, "abc", 2) == one + 2, 1);
+  check (stpncpy (one, "abc", 3) == one + 3, 2);
+  check (stpncpy (one, "abc", 4) == one + 3, 3);
+  check (one[3] == '\0' && one[4] == 'x', 4);
+  check (stpncpy (one, "abcd", 5) == one + 4, 5);
+  check (one[4] == '\0' && one[5] == 'x', 6);
+  check (stpncpy (one, "abcd", 6) == one + 4, 7);
+  check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
+}
+
+static void
+test_strcat (void)
+{
+  it = "strcat";
+  (void) strcpy (one, "ijk");
+  check (strcat (one, "lmn") == one, 1); /* Returned value. */
+  equal (one, "ijklmn", 2);		/* Basic test. */
+
+  (void) strcpy (one, "x");
+  (void) strcat (one, "yz");
+  equal (one, "xyz", 3);			/* Writeover. */
+  equal (one+4, "mn", 4);			/* Wrote too much? */
+
+  (void) strcpy (one, "gh");
+  (void) strcpy (two, "ef");
+  (void) strcat (one, two);
+  equal (one, "ghef", 5);			/* Basic test encore. */
+  equal (two, "ef", 6);			/* Stomped on source? */
+
+  (void) strcpy (one, "");
+  (void) strcat (one, "");
+  equal (one, "", 7);			/* Boundary conditions. */
+  (void) strcpy (one, "ab");
+  (void) strcat (one, "");
+  equal (one, "ab", 8);
+  (void) strcpy (one, "");
+  (void) strcat (one, "cd");
+  equal (one, "cd", 9);
+
+  int ntest = 10;
+  char buf1[80] __attribute__ ((aligned (16)));
+  char buf2[32] __attribute__ ((aligned (16)));
+  for (size_t n1 = 0; n1 < 16; ++n1)
+    for (size_t n2 = 0; n2 < 16; ++n2)
+      for (size_t n3 = 0; n3 < 32; ++n3)
+	{
+	  size_t olderrors = errors;
+
+	  memset (buf1, 'b', sizeof (buf1));
+
+	  memset (buf1 + n2, 'a', n3);
+	  buf1[n2 + n3] = '\0';
+	  strcpy (buf2 + n1, "123");
+
+	  check (strcat (buf1 + n2, buf2 + n1) == buf1 + n2, ntest);
+	  if (errors == olderrors)
+	    for (size_t i = 0; i < sizeof (buf1); ++i)
+	      {
+		if (i < n2)
+		  check (buf1[i] == 'b', ntest);
+		else if (i < n2 + n3)
+		  check (buf1[i] == 'a', ntest);
+		else if (i < n2 + n3 + 3)
+		  check (buf1[i] == "123"[i - (n2 + n3)], ntest);
+		else if (i == n2 + n3 + 3)
+		  check (buf1[i] == '\0', ntest);
+		else
+		  check (buf1[i] == 'b', ntest);
+
+		if (errors != olderrors)
+		  {
+		    printf ("n1=%zu, n2=%zu, n3=%zu, buf1=%02hhx",
+			    n1, n2, n3, buf1[0]);
+		    for (size_t j = 1; j < sizeof (buf1); ++j)
+		      printf (",%02hhx", buf1[j]);
+		    putchar_unlocked ('\n');
+		    break;
+		  }
+	      }
+	}
+}
+
+static void
+test_strncat (void)
+{
+  /* First test it as strcat, with big counts, then test the count
+     mechanism.  */
+  it = "strncat";
+  (void) strcpy (one, "ijk");
+  DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+  /* GCC 7 warns about the size passed to strncat being larger than
+     the size of the buffer; this is deliberately tested here..  */
+  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
+  check (strncat (one, "lmn", 99) == one, 1);	/* Returned value. */
+  DIAG_POP_NEEDS_COMMENT;
+  equal (one, "ijklmn", 2);		/* Basic test. */
+
+  (void) strcpy (one, "x");
+  DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+  /* GCC 7 warns about the size passed to strncat being larger than
+     the size of the buffer; this is deliberately tested here..  */
+  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
+  (void) strncat (one, "yz", 99);
+  DIAG_POP_NEEDS_COMMENT;
+  equal (one, "xyz", 3);		/* Writeover. */
+  equal (one+4, "mn", 4);		/* Wrote too much? */
+
+  (void) strcpy (one, "gh");
+  (void) strcpy (two, "ef");
+  DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+  /* GCC 7 warns about the size passed to strncat being larger than
+     the size of the buffer; this is deliberately tested here..  */
+  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
+  (void) strncat (one, two, 99);
+  DIAG_POP_NEEDS_COMMENT;
+  equal (one, "ghef", 5);			/* Basic test encore. */
+  equal (two, "ef", 6);			/* Stomped on source? */
+
+  (void) strcpy (one, "");
+  DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+  /* GCC 7 warns about the size passed to strncat being larger than
+     the size of the buffer; this is deliberately tested here..  */
+  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
+  (void) strncat (one, "", 99);
+  DIAG_POP_NEEDS_COMMENT;
+  equal (one, "", 7);			/* Boundary conditions. */
+  (void) strcpy (one, "ab");
+  DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+  /* GCC 7 warns about the size passed to strncat being larger than
+     the size of the buffer; this is deliberately tested here..  */
+  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
+  (void) strncat (one, "", 99);
+  DIAG_POP_NEEDS_COMMENT;
+  equal (one, "ab", 8);
+  (void) strcpy (one, "");
+  DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+  /* GCC 7 warns about the size passed to strncat being larger than
+     the size of the buffer; this is deliberately tested here..  */
+  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
+  (void) strncat (one, "cd", 99);
+  DIAG_POP_NEEDS_COMMENT;
+  equal (one, "cd", 9);
+
+  (void) strcpy (one, "ab");
+  (void) strncat (one, "cdef", 2);
+  equal (one, "abcd", 10);			/* Count-limited. */
+
+  (void) strncat (one, "gh", 0);
+  equal (one, "abcd", 11);			/* Zero count. */
+
+  (void) strncat (one, "gh", 2);
+  equal (one, "abcdgh", 12);		/* Count and length equal. */
+
+  DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+  /* GCC 7 warns about the size passed to strncat being larger than
+     the size of the buffer; this is deliberately tested here..  */
+  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
+  (void) strncat (one, "ij", (size_t)-1);	/* set sign bit in count */
+  DIAG_POP_NEEDS_COMMENT;
+  equal (one, "abcdghij", 13);
+
+  int ntest = 14;
+  char buf1[80] __attribute__ ((aligned (16)));
+  char buf2[32] __attribute__ ((aligned (16)));
+  for (size_t n1 = 0; n1 < 16; ++n1)
+    for (size_t n2 = 0; n2 < 16; ++n2)
+      for (size_t n3 = 0; n3 < 32; ++n3)
+	for (size_t n4 = 0; n4 < 16; ++n4)
+	  {
+	    size_t olderrors = errors;
+
+	    memset (buf1, 'b', sizeof (buf1));
+
+	    memset (buf1 + n2, 'a', n3);
+	    buf1[n2 + n3] = '\0';
+	    strcpy (buf2 + n1, "123");
+
+	    DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+	    /* GCC 7 warns about the size passed to strncat being
+	       larger than the size of the buffer; this is
+	       deliberately tested here..  */
+	    DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
+	    check (strncat (buf1 + n2, buf2 + n1, ~((size_t) 0) - n4)
+		   == buf1 + n2, ntest);
+	    DIAG_POP_NEEDS_COMMENT;
+	    if (errors == olderrors)
+	      for (size_t i = 0; i < sizeof (buf1); ++i)
+		{
+		  if (i < n2)
+		    check (buf1[i] == 'b', ntest);
+		  else if (i < n2 + n3)
+		    check (buf1[i] == 'a', ntest);
+		  else if (i < n2 + n3 + 3)
+		    check (buf1[i] == "123"[i - (n2 + n3)], ntest);
+		  else if (i == n2 + n3 + 3)
+		    check (buf1[i] == '\0', ntest);
+		  else
+		    check (buf1[i] == 'b', ntest);
+
+		  if (errors != olderrors)
+		    {
+		      printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
+			      n1, n2, n3, n4, buf1[0]);
+		      for (size_t j = 1; j < sizeof (buf1); ++j)
+			printf (",%02hhx", buf1[j]);
+		      putchar_unlocked ('\n');
+		      break;
+		    }
+		}
+	  }
+}
+
+static void
+test_strncmp (void)
+{
+  /* First test as strcmp with big counts, then test count code.  */
+  it = "strncmp";
+  check (strncmp ("", "", 99) == 0, 1);	/* Trivial case. */
+  check (strncmp ("a", "a", 99) == 0, 2);	/* Identity. */
+  check (strncmp ("abc", "abc", 99) == 0, 3);	/* Multicharacter. */
+  check (strncmp ("abc", "abcd", 99) < 0, 4);	/* Length unequal. */
+  check (strncmp ("abcd", "abc", 99) > 0, 5);
+  check (strncmp ("abcd", "abce", 99) < 0, 6);	/* Honestly unequal. */
+  check (strncmp ("abce", "abcd", 99) > 0, 7);
+  check (strncmp ("a\203", "a", 2) > 0, 8);	/* Tricky if '\203' < 0 */
+  check (strncmp ("a\203", "a\003", 2) > 0, 9);
+  check (strncmp ("abce", "abcd", 3) == 0, 10);	/* Count limited. */
+  check (strncmp ("abce", "abc", 3) == 0, 11);	/* Count == length. */
+  check (strncmp ("abcd", "abce", 4) < 0, 12);	/* Nudging limit. */
+  check (strncmp ("abc", "def", 0) == 0, 13);	/* Zero count. */
+  check (strncmp ("abc", "", (size_t)-1) > 0, 14);	/* set sign bit in count */
+  check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
+}
+
+static void
+test_strncpy (void)
+{
+  /* Testing is a bit different because of odd semantics.  */
+  it = "strncpy";
+  check (strncpy (one, "abc", 4) == one, 1);	/* Returned value. */
+  equal (one, "abc", 2);			/* Did the copy go right? */
+
+  (void) strcpy (one, "abcdefgh");
+  (void) strncpy (one, "xyz", 2);
+  equal (one, "xycdefgh", 3);			/* Copy cut by count. */
+
+  (void) strcpy (one, "abcdefgh");
+  (void) strncpy (one, "xyz", 3);		/* Copy cut just before NUL. */
+  equal (one, "xyzdefgh", 4);
+
+  (void) strcpy (one, "abcdefgh");
+  (void) strncpy (one, "xyz", 4);		/* Copy just includes NUL. */
+  equal (one, "xyz", 5);
+  equal (one+4, "efgh", 6);			/* Wrote too much? */
+
+  (void) strcpy (one, "abcdefgh");
+  (void) strncpy (one, "xyz", 5);		/* Copy includes padding. */
+  equal (one, "xyz", 7);
+  equal (one+4, "", 8);
+  equal (one+5, "fgh", 9);
+
+  (void) strcpy (one, "abc");
+  (void) strncpy (one, "xyz", 0);		/* Zero-length copy. */
+  equal (one, "abc", 10);
+
+  (void) strncpy (one, "", 2);		/* Zero-length source. */
+  equal (one, "", 11);
+  equal (one+1, "", 12);
+  equal (one+2, "c", 13);
+
+  (void) strcpy (one, "hi there");
+  (void) strncpy (two, one, 9);
+  equal (two, "hi there", 14);		/* Just paranoia. */
+  equal (one, "hi there", 15);		/* Stomped on source? */
+}
+
+static void
+test_strlen (void)
+{
+  it = "strlen";
+  check (strlen ("") == 0, 1);		/* Empty. */
+  check (strlen ("a") == 1, 2);		/* Single char. */
+  check (strlen ("abcd") == 4, 3);	/* Multiple chars. */
+  {
+    char buf[4096];
+    int i;
+    char *p;
+    for (i=0; i < 0x100; i++)
+      {
+	p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
+	strcpy (p, "OK");
+	strcpy (p+3, "BAD/WRONG");
+	check (strlen (p) == 2, 4+i);
+      }
+   }
+}
+
+static void
+test_strnlen (void)
+{
+  it = "strnlen";
+  check (strnlen ("", 10) == 0, 1);		/* Empty. */
+  check (strnlen ("a", 10) == 1, 2);		/* Single char. */
+  check (strnlen ("abcd", 10) == 4, 3);		/* Multiple chars. */
+  check (strnlen ("foo", (size_t) -1) == 3, 4);	/* limits of n. */
+  check (strnlen ("abcd", 0) == 0, 5);		/* Restricted. */
+  check (strnlen ("abcd", 1) == 1, 6);		/* Restricted. */
+  check (strnlen ("abcd", 2) == 2, 7);		/* Restricted. */
+  check (strnlen ("abcd", 3) == 3, 8);		/* Restricted. */
+  check (strnlen ("abcd", 4) == 4, 9);		/* Restricted. */
+
+  char buf[4096];
+  for (int i = 0; i < 0x100; ++i)
+    {
+      char *p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
+      strcpy (p, "OK");
+      strcpy (p + 3, "BAD/WRONG");
+      check (strnlen (p, 100) == 2, 10 + i);
+    }
+}
+
+static void
+test_strchr (void)
+{
+  it = "strchr";
+  check (strchr ("abcd", 'z') == NULL, 1);	/* Not found. */
+  (void) strcpy (one, "abcd");
+  check (strchr (one, 'c') == one+2, 2);	/* Basic test. */
+  check (strchr (one, 'd') == one+3, 3);	/* End of string. */
+  check (strchr (one, 'a') == one, 4);		/* Beginning. */
+  check (strchr (one, '\0') == one+4, 5);	/* Finding NUL. */
+  (void) strcpy (one, "ababa");
+  check (strchr (one, 'b') == one+1, 6);	/* Finding first. */
+  (void) strcpy (one, "");
+  check (strchr (one, 'b') == NULL, 7);		/* Empty string. */
+  check (strchr (one, '\0') == one, 8);		/* NUL in empty string. */
+  {
+    char buf[4096];
+    int i;
+    char *p;
+    for (i=0; i < 0x100; i++)
+      {
+	p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
+	strcpy (p, "OK");
+	strcpy (p+3, "BAD/WRONG");
+	check (strchr (p, '/') == NULL, 9+i);
+      }
+   }
+}
+
+static void
+test_strchrnul (void)
+{
+  const char *os;
+  it = "strchrnul";
+  cp = strchrnul ((os = "abcd"), 'z');
+  check (*cp == '\0', 1);			/* Not found. */
+  check (cp == os + 4, 2);
+  (void) strcpy (one, "abcd");
+  check (strchrnul (one, 'c') == one+2, 3);	/* Basic test. */
+  check (strchrnul (one, 'd') == one+3, 4);	/* End of string. */
+  check (strchrnul (one, 'a') == one, 5);	/* Beginning. */
+  check (strchrnul (one, '\0') == one+4, 6);	/* Finding NUL. */
+  (void) strcpy (one, "ababa");
+  check (strchrnul (one, 'b') == one+1, 7);	/* Finding first. */
+  (void) strcpy (one, "");
+  check (strchrnul (one, 'b') == one, 8);	/* Empty string. */
+  check (strchrnul (one, '\0') == one, 9);	/* NUL in empty string. */
+  {
+    char buf[4096];
+    int i;
+    char *p;
+    for (i=0; i < 0x100; i++)
+      {
+	p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
+	strcpy (p, "OK");
+	strcpy (p+3, "BAD/WRONG");
+	cp = strchrnul (p, '/');
+	check (*cp == '\0', 9+2*i);
+	check (cp == p+2, 10+2*i);
+      }
+   }
+}
+
+static void
+test_rawmemchr (void)
+{
+  it = "rawmemchr";
+  (void) strcpy (one, "abcd");
+  check (rawmemchr (one, 'c') == one+2, 1);	/* Basic test. */
+  check (rawmemchr (one, 'd') == one+3, 2);	/* End of string. */
+  check (rawmemchr (one, 'a') == one, 3);		/* Beginning. */
+  check (rawmemchr (one, '\0') == one+4, 4);	/* Finding NUL. */
+  (void) strcpy (one, "ababa");
+  check (rawmemchr (one, 'b') == one+1, 5);	/* Finding first. */
+  (void) strcpy (one, "");
+  check (rawmemchr (one, '\0') == one, 6);	/* NUL in empty string. */
+  {
+    char buf[4096];
+    int i;
+    char *p;
+    for (i=0; i < 0x100; i++)
+      {
+	p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
+	strcpy (p, "OK");
+	strcpy (p+3, "BAD/WRONG");
+	check (rawmemchr (p, 'R') == p+8, 6+i);
+      }
+   }
+}
+
+static void
+test_index (void)
+{
+  it = "index";
+  check (index ("abcd", 'z') == NULL, 1);	/* Not found. */
+  (void) strcpy (one, "abcd");
+  check (index (one, 'c') == one+2, 2);	/* Basic test. */
+  check (index (one, 'd') == one+3, 3);	/* End of string. */
+  check (index (one, 'a') == one, 4);	/* Beginning. */
+  check (index (one, '\0') == one+4, 5);	/* Finding NUL. */
+  (void) strcpy (one, "ababa");
+  check (index (one, 'b') == one+1, 6);	/* Finding first. */
+  (void) strcpy (one, "");
+  check (index (one, 'b') == NULL, 7);	/* Empty string. */
+  check (index (one, '\0') == one, 8);	/* NUL in empty string. */
+}
+
+static void
+test_strrchr (void)
+{
+  it = "strrchr";
+  check (strrchr ("abcd", 'z') == NULL, 1);	/* Not found. */
+  (void) strcpy (one, "abcd");
+  check (strrchr (one, 'c') == one+2, 2);	/* Basic test. */
+  check (strrchr (one, 'd') == one+3, 3);	/* End of string. */
+  check (strrchr (one, 'a') == one, 4);		/* Beginning. */
+  check (strrchr (one, '\0') == one+4, 5);	/* Finding NUL. */
+  (void) strcpy (one, "ababa");
+  check (strrchr (one, 'b') == one+3, 6);	/* Finding last. */
+  (void) strcpy (one, "");
+  check (strrchr (one, 'b') == NULL, 7);	/* Empty string. */
+  check (strrchr (one, '\0') == one, 8);	/* NUL in empty string. */
+  {
+    char buf[4096];
+    int i;
+    char *p;
+    for (i=0; i < 0x100; i++)
+      {
+	p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
+	strcpy (p, "OK");
+	strcpy (p+3, "BAD/WRONG");
+	check (strrchr (p, '/') == NULL, 9+i);
+      }
+   }
+}
+
+static void
+test_memrchr (void)
+{
+  size_t l;
+  it = "memrchr";
+  check (memrchr ("abcd", 'z', 5) == NULL, 1);	/* Not found. */
+  (void) strcpy (one, "abcd");
+  l = strlen (one) + 1;
+  check (memrchr (one, 'c', l) == one+2, 2);	/* Basic test. */
+  check (memrchr (one, 'd', l) == one+3, 3);	/* End of string. */
+  check (memrchr (one, 'a', l) == one, 4);		/* Beginning. */
+  check (memrchr (one, '\0', l) == one+4, 5);	/* Finding NUL. */
+  (void) strcpy (one, "ababa");
+  l = strlen (one) + 1;
+  check (memrchr (one, 'b', l) == one+3, 6);	/* Finding last. */
+  (void) strcpy (one, "");
+  l = strlen (one) + 1;
+  check (memrchr (one, 'b', l) == NULL, 7);	/* Empty string. */
+  check (memrchr (one, '\0', l) == one, 8);	/* NUL in empty string. */
+
+  /* now test all possible alignment and length combinations to catch
+     bugs due to unrolled loops (assuming unrolling is limited to no
+     more than 128 byte chunks: */
+  {
+    char buf[128 + sizeof(long)];
+    long align, len, i, pos, n = 9;
+
+    for (align = 0; align < (long) sizeof(long); ++align) {
+      for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
+	for (i = 0; i < len; ++i)
+	  buf[align + i] = 'x';		/* don't depend on memset... */
+
+	for (pos = len - 1; pos >= 0; --pos) {
+#if 0
+	  printf("align %d, len %d, pos %d\n", align, len, pos);
+#endif
+	  check(memrchr(buf + align, 'x', len) == buf + align + pos, n++);
+	  check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
+		n++);
+	  buf[align + pos] = '-';
+	}
+      }
+    }
+  }
+}
+
+static void
+test_rindex (void)
+{
+  it = "rindex";
+  check (rindex ("abcd", 'z') == NULL, 1);	/* Not found. */
+  (void) strcpy (one, "abcd");
+  check (rindex (one, 'c') == one+2, 2);	/* Basic test. */
+  check (rindex (one, 'd') == one+3, 3);	/* End of string. */
+  check (rindex (one, 'a') == one, 4);	/* Beginning. */
+  check (rindex (one, '\0') == one+4, 5);	/* Finding NUL. */
+  (void) strcpy (one, "ababa");
+  check (rindex (one, 'b') == one+3, 6);	/* Finding last. */
+  (void) strcpy (one, "");
+  check (rindex (one, 'b') == NULL, 7);	/* Empty string. */
+  check (rindex (one, '\0') == one, 8);	/* NUL in empty string. */
+}
+
+static void
+test_strpbrk (void)
+{
+  it = "strpbrk";
+  check(strpbrk("abcd", "z") == NULL, 1);	/* Not found. */
+  (void) strcpy(one, "abcd");
+  check(strpbrk(one, "c") == one+2, 2);	/* Basic test. */
+  check(strpbrk(one, "d") == one+3, 3);	/* End of string. */
+  check(strpbrk(one, "a") == one, 4);	/* Beginning. */
+  check(strpbrk(one, "") == NULL, 5);	/* Empty search list. */
+  check(strpbrk(one, "cb") == one+1, 6);	/* Multiple search. */
+  (void) strcpy(one, "abcabdea");
+  check(strpbrk(one, "b") == one+1, 7);	/* Finding first. */
+  check(strpbrk(one, "cb") == one+1, 8);	/* With multiple search. */
+  check(strpbrk(one, "db") == one+1, 9);	/* Another variant. */
+  (void) strcpy(one, "");
+  check(strpbrk(one, "bc") == NULL, 10);	/* Empty string. */
+  (void) strcpy(one, "");
+  check(strpbrk(one, "bcd") == NULL, 11);	/* Empty string. */
+  (void) strcpy(one, "");
+  check(strpbrk(one, "bcde") == NULL, 12);	/* Empty string. */
+  check(strpbrk(one, "") == NULL, 13);	/* Both strings empty. */
+  (void) strcpy(one, "abcabdea");
+  check(strpbrk(one, "befg") == one+1, 14);	/* Finding first. */
+  check(strpbrk(one, "cbr") == one+1, 15);	/* With multiple search. */
+  check(strpbrk(one, "db") == one+1, 16);	/* Another variant. */
+  check(strpbrk(one, "efgh") == one+6, 17);	/* And yet another. */
+}
+
+static void
+test_strstr (void)
+{
+  it = "strstr";
+  check(strstr("abcd", "z") == NULL, 1);	/* Not found. */
+  check(strstr("abcd", "abx") == NULL, 2);	/* Dead end. */
+  (void) strcpy(one, "abcd");
+  check(strstr(one, "c") == one+2, 3);	/* Basic test. */
+  check(strstr(one, "bc") == one+1, 4);	/* Multichar. */
+  check(strstr(one, "d") == one+3, 5);	/* End of string. */
+  check(strstr(one, "cd") == one+2, 6);	/* Tail of string. */
+  check(strstr(one, "abc") == one, 7);	/* Beginning. */
+  check(strstr(one, "abcd") == one, 8);	/* Exact match. */
+  check(strstr(one, "abcde") == NULL, 9);	/* Too long. */
+  check(strstr(one, "de") == NULL, 10);	/* Past end. */
+  check(strstr(one, "") == one, 11);	/* Finding empty. */
+  (void) strcpy(one, "ababa");
+  check(strstr(one, "ba") == one+1, 12);	/* Finding first. */
+  (void) strcpy(one, "");
+  check(strstr(one, "b") == NULL, 13);	/* Empty string. */
+  check(strstr(one, "") == one, 14);	/* Empty in empty string. */
+  (void) strcpy(one, "bcbca");
+  check(strstr(one, "bca") == one+2, 15);	/* False start. */
+  (void) strcpy(one, "bbbcabbca");
+  check(strstr(one, "bbca") == one+1, 16);	/* With overlap. */
+}
+
+static void
+test_strspn (void)
+{
+  it = "strspn";
+  check(strspn("abcba", "abc") == 5, 1);	/* Whole string. */
+  check(strspn("abcba", "ab") == 2, 2);	/* Partial. */
+  check(strspn("abc", "qx") == 0, 3);	/* None. */
+  check(strspn("", "ab") == 0, 4);	/* Null string. */
+  check(strspn("abc", "") == 0, 5);	/* Null search list. */
+}
+
+static void
+test_strcspn (void)
+{
+  it = "strcspn";
+  check(strcspn("abcba", "qx") == 5, 1);	/* Whole string. */
+  check(strcspn("abcba", "cx") == 2, 2);	/* Partial. */
+  check(strcspn("abc", "abc") == 0, 3);	/* None. */
+  check(strcspn("", "ab") == 0, 4);	/* Null string. */
+  check(strcspn("abc", "") == 3, 5);	/* Null search list. */
+}
+
+static void
+test_strtok (void)
+{
+  it = "strtok";
+  (void) strcpy(one, "first, second, third");
+  equal(strtok(one, ", "), "first", 1);	/* Basic test. */
+  equal(one, "first", 2);
+  equal(strtok((char *)NULL, ", "), "second", 3);
+  equal(strtok((char *)NULL, ", "), "third", 4);
+  check(strtok((char *)NULL, ", ") == NULL, 5);
+  (void) strcpy(one, ", first, ");
+  equal(strtok(one, ", "), "first", 6);	/* Extra delims, 1 tok. */
+  check(strtok((char *)NULL, ", ") == NULL, 7);
+  (void) strcpy(one, "1a, 1b; 2a, 2b");
+  equal(strtok(one, ", "), "1a", 8);	/* Changing delim lists. */
+  equal(strtok((char *)NULL, "; "), "1b", 9);
+  equal(strtok((char *)NULL, ", "), "2a", 10);
+  (void) strcpy(two, "x-y");
+  equal(strtok(two, "-"), "x", 11);	/* New string before done. */
+  equal(strtok((char *)NULL, "-"), "y", 12);
+  check(strtok((char *)NULL, "-") == NULL, 13);
+  (void) strcpy(one, "a,b, c,, ,d");
+  equal(strtok(one, ", "), "a", 14);	/* Different separators. */
+  equal(strtok((char *)NULL, ", "), "b", 15);
+  equal(strtok((char *)NULL, " ,"), "c", 16);	/* Permute list too. */
+  equal(strtok((char *)NULL, " ,"), "d", 17);
+  check(strtok((char *)NULL, ", ") == NULL, 18);
+  check(strtok((char *)NULL, ", ") == NULL, 19);	/* Persistence. */
+  (void) strcpy(one, ", ");
+  check(strtok(one, ", ") == NULL, 20);	/* No tokens. */
+  (void) strcpy(one, "");
+  check(strtok(one, ", ") == NULL, 21);	/* Empty string. */
+  (void) strcpy(one, "abc");
+  equal(strtok(one, ", "), "abc", 22);	/* No delimiters. */
+  check(strtok((char *)NULL, ", ") == NULL, 23);
+  (void) strcpy(one, "abc");
+  equal(strtok(one, ""), "abc", 24);	/* Empty delimiter list. */
+  check(strtok((char *)NULL, "") == NULL, 25);
+  (void) strcpy(one, "abcdefgh");
+  (void) strcpy(one, "a,b,c");
+  equal(strtok(one, ","), "a", 26);	/* Basics again... */
+  equal(strtok((char *)NULL, ","), "b", 27);
+  equal(strtok((char *)NULL, ","), "c", 28);
+  check(strtok((char *)NULL, ",") == NULL, 29);
+  equal(one+6, "gh", 30);			/* Stomped past end? */
+  equal(one, "a", 31);			/* Stomped old tokens? */
+  equal(one+2, "b", 32);
+  equal(one+4, "c", 33);
+}
+
+static void
+test_strtok_r (void)
+{
+  it = "strtok_r";
+  (void) strcpy(one, "first, second, third");
+  cp = NULL;	/* Always initialize cp to make sure it doesn't point to some old data.  */
+  equal(strtok_r(one, ", ", &cp), "first", 1);	/* Basic test. */
+  equal(one, "first", 2);
+  equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
+  equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
+  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
+  (void) strcpy(one, ", first, ");
+  cp = NULL;
+  equal(strtok_r(one, ", ", &cp), "first", 6);	/* Extra delims, 1 tok. */
+  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
+  (void) strcpy(one, "1a, 1b; 2a, 2b");
+  cp = NULL;
+  equal(strtok_r(one, ", ", &cp), "1a", 8);	/* Changing delim lists. */
+  equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
+  equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
+  (void) strcpy(two, "x-y");
+  cp = NULL;
+  equal(strtok_r(two, "-", &cp), "x", 11);	/* New string before done. */
+  equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
+  check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
+  (void) strcpy(one, "a,b, c,, ,d");
+  cp = NULL;
+  equal(strtok_r(one, ", ", &cp), "a", 14);	/* Different separators. */
+  equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
+  equal(strtok_r((char *)NULL, " ,", &cp), "c", 16);	/* Permute list too. */
+  equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
+  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
+  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19);	/* Persistence. */
+  (void) strcpy(one, ", ");
+  cp = NULL;
+  check(strtok_r(one, ", ", &cp) == NULL, 20);	/* No tokens. */
+  (void) strcpy(one, "");
+  cp = NULL;
+  check(strtok_r(one, ", ", &cp) == NULL, 21);	/* Empty string. */
+  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22);	/* Persistence. */
+  (void) strcpy(one, "abc");
+  cp = NULL;
+  equal(strtok_r(one, ", ", &cp), "abc", 23);	/* No delimiters. */
+  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
+  (void) strcpy(one, "abc");
+  cp = NULL;
+  equal(strtok_r(one, "", &cp), "abc", 25);	/* Empty delimiter list. */
+  check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
+  (void) strcpy(one, "abcdefgh");
+  (void) strcpy(one, "a,b,c");
+  cp = NULL;
+  equal(strtok_r(one, ",", &cp), "a", 27);	/* Basics again... */
+  equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
+  equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
+  check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
+  equal(one+6, "gh", 31);			/* Stomped past end? */
+  equal(one, "a", 32);				/* Stomped old tokens? */
+  equal(one+2, "b", 33);
+  equal(one+4, "c", 34);
+  strcpy (one, ":::");
+  cp = NULL;
+  check (strtok_r (one, ":", &cp) == NULL, 35);	/* Must store pointer in cp. */
+  check (strtok_r (NULL, ":", &cp) == NULL, 36);
+}
+
+static void
+test_strsep (void)
+{
+  char *ptr;
+  it = "strsep";
+  cp = strcpy(one, "first, second, third");
+  equal(strsep(&cp, ", "), "first", 1);	/* Basic test. */
+  equal(one, "first", 2);
+  equal(strsep(&cp, ", "), "", 3);
+  equal(strsep(&cp, ", "), "second", 4);
+  equal(strsep(&cp, ", "), "", 5);
+  equal(strsep(&cp, ", "), "third", 6);
+  check(strsep(&cp, ", ") == NULL, 7);
+  cp = strcpy(one, ", first, ");
+  equal(strsep(&cp, ", "), "", 8);
+  equal(strsep(&cp, ", "), "", 9);
+  equal(strsep(&cp, ", "), "first", 10);	/* Extra delims, 1 tok. */
+  equal(strsep(&cp, ", "), "", 11);
+  equal(strsep(&cp, ", "), "", 12);
+  check(strsep(&cp, ", ") == NULL, 13);
+  cp = strcpy(one, "1a, 1b; 2a, 2b");
+  equal(strsep(&cp, ", "), "1a", 14);	/* Changing delim lists. */
+  equal(strsep(&cp, ", "), "", 15);
+  equal(strsep(&cp, "; "), "1b", 16);
+  equal(strsep(&cp, ", "), "", 17);
+  equal(strsep(&cp, ", "), "2a", 18);
+  cp = strcpy(two, "x-y");
+  equal(strsep(&cp, "-"), "x", 19);	/* New string before done. */
+  equal(strsep(&cp, "-"), "y", 20);
+  check(strsep(&cp, "-") == NULL, 21);
+  cp = strcpy(one, "a,b, c,, ,d ");
+  equal(strsep(&cp, ", "), "a", 22);	/* Different separators. */
+  equal(strsep(&cp, ", "), "b", 23);
+  equal(strsep(&cp, " ,"), "", 24);
+  equal(strsep(&cp, " ,"), "c", 25);	/* Permute list too. */
+  equal(strsep(&cp, " ,"), "", 26);
+  equal(strsep(&cp, " ,"), "", 27);
+  equal(strsep(&cp, " ,"), "", 28);
+  equal(strsep(&cp, " ,"), "d", 29);
+  equal(strsep(&cp, " ,"), "", 30);
+  check(strsep(&cp, ", ") == NULL, 31);
+  check(strsep(&cp, ", ") == NULL, 32);	/* Persistence. */
+  cp = strcpy(one, ", ");
+  equal(strsep(&cp, ", "), "", 33);
+  equal(strsep(&cp, ", "), "", 34);
+  equal(strsep(&cp, ", "), "", 35);
+  check(strsep(&cp, ", ") == NULL, 36);	/* No tokens. */
+  cp = strcpy(one, "");
+  equal(strsep(&cp, ", "), "", 37);
+  check(strsep(&cp, ", ") == NULL, 38);	/* Empty string. */
+  cp = strcpy(one, "abc");
+  equal(strsep(&cp, ", "), "abc", 39);	/* No delimiters. */
+  check(strsep(&cp, ", ") == NULL, 40);
+  cp = strcpy(one, "abc");
+  equal(strsep(&cp, ""), "abc", 41);	/* Empty delimiter list. */
+  check(strsep(&cp, "") == NULL, 42);
+  (void) strcpy(one, "abcdefgh");
+  cp = strcpy(one, "a,b,c");
+  equal(strsep(&cp, ","), "a", 43);	/* Basics again... */
+  equal(strsep(&cp, ","), "b", 44);
+  equal(strsep(&cp, ","), "c", 45);
+  check(strsep(&cp, ",") == NULL, 46);
+  equal(one+6, "gh", 47);		/* Stomped past end? */
+  equal(one, "a", 48);			/* Stomped old tokens? */
+  equal(one+2, "b", 49);
+  equal(one+4, "c", 50);
+
+  {
+    char text[] = "This,is,a,test";
+    char *list = strdupa (text);
+    equal (strsep (&list, ","), "This", 51);
+    equal (strsep (&list, ","), "is", 52);
+    equal (strsep (&list, ","), "a", 53);
+    equal (strsep (&list, ","), "test", 54);
+    check (strsep (&list, ",") == NULL, 55);
+  }
+
+  cp = strcpy(one, "a,b, c,, ,d,");
+  equal(strsep(&cp, ","), "a", 56);	/* Different separators. */
+  equal(strsep(&cp, ","), "b", 57);
+  equal(strsep(&cp, ","), " c", 58);	/* Permute list too. */
+  equal(strsep(&cp, ","), "", 59);
+  equal(strsep(&cp, ","), " ", 60);
+  equal(strsep(&cp, ","), "d", 61);
+  equal(strsep(&cp, ","), "", 62);
+  check(strsep(&cp, ",") == NULL, 63);
+  check(strsep(&cp, ",") == NULL, 64);	/* Persistence. */
+
+  cp = strcpy(one, "a,b, c,, ,d,");
+  equal(strsep(&cp, "xy,"), "a", 65);	/* Different separators. */
+  equal(strsep(&cp, "x,y"), "b", 66);
+  equal(strsep(&cp, ",xy"), " c", 67);	/* Permute list too. */
+  equal(strsep(&cp, "xy,"), "", 68);
+  equal(strsep(&cp, "x,y"), " ", 69);
+  equal(strsep(&cp, ",xy"), "d", 70);
+  equal(strsep(&cp, "xy,"), "", 71);
+  check(strsep(&cp, "x,y") == NULL, 72);
+  check(strsep(&cp, ",xy") == NULL, 73);	/* Persistence. */
+
+  cp = strcpy(one, "ABC");
+  one[4] = ':';
+  equal(strsep(&cp, "C"), "AB", 74);	/* Access beyond NUL.  */
+  ptr = strsep(&cp, ":");
+  equal(ptr, "", 75);
+  check(ptr == one + 3, 76);
+  check(cp == NULL, 77);
+
+  cp = strcpy(one, "ABC");
+  one[4] = ':';
+  equal(strsep(&cp, "CD"), "AB", 78);	/* Access beyond NUL.  */
+  ptr = strsep(&cp, ":.");
+  equal(ptr, "", 79);
+  check(ptr == one + 3, 80);
+
+  cp = strcpy(one, "ABC");		/* No token in string.  */
+  equal(strsep(&cp, ","), "ABC", 81);
+  check(cp == NULL, 82);
+
+  *one = '\0';				/* Empty string. */
+  cp = one;
+  ptr = strsep(&cp, ",");
+  equal(ptr, "", 83);
+  check(ptr == one, 84);
+  check(cp == NULL, 85);
+
+  *one = '\0';				/* Empty string and no token. */
+  cp = one;
+  ptr = strsep(&cp, "");
+  equal(ptr, "", 86);
+  check(ptr == one , 87);
+  check(cp == NULL, 88);
+}
+
+static void
+test_memcmp (void)
+{
+  int cnt = 1;
+  char one[21];
+  char two[21];
+
+  it = "memcmp";
+  check(memcmp("a", "a", 1) == 0, cnt++);	/* Identity. */
+  check(memcmp("abc", "abc", 3) == 0, cnt++);	/* Multicharacter. */
+  check(memcmp("abcd", "abcf", 4) < 0, cnt++);	/* Honestly unequal. */
+  check(memcmp("abcf", "abcd", 4) > 0, cnt++);
+  check(memcmp("alph", "cold", 4) < 0, cnt++);
+  check(memcmp("a\203", "a\003", 2) > 0, cnt++);
+  check(memcmp("a\003", "a\203", 2) < 0, cnt++);
+  check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt++);
+  check(memcmp("abc\203", "abc\003", 4) > 0, cnt++);
+  check(memcmp("abc\003", "abc\203", 4) < 0, cnt++);
+  check(memcmp("abcf", "abcd", 3) == 0, cnt++);	/* Count limited. */
+  check(memcmp("abc", "def", 0) == 0, cnt++);	/* Zero count. */
+  /* Comparisons with shifting 4-byte boundaries. */
+  for (int i = 0; i < 4; ++i)
+    {
+      char *a = one + i;
+      char *b = two + i;
+      strncpy(a, "--------11112222", 16);
+      strncpy(b, "--------33334444", 16);
+      check(memcmp(b, a, 16) > 0, cnt++);
+      check(memcmp(a, b, 16) < 0, cnt++);
+    }
+}
+
+static void
+test_memchr (void)
+{
+  it = "memchr";
+  check(memchr("abcd", 'z', 4) == NULL, 1);	/* Not found. */
+  (void) strcpy(one, "abcd");
+  check(memchr(one, 'c', 4) == one+2, 2);	/* Basic test. */
+  check(memchr(one, ~0xff|'c', 4) == one+2, 2);	/* ignore highorder bits. */
+  check(memchr(one, 'd', 4) == one+3, 3);	/* End of string. */
+  check(memchr(one, 'a', 4) == one, 4);	/* Beginning. */
+  check(memchr(one, '\0', 5) == one+4, 5);	/* Finding NUL. */
+  (void) strcpy(one, "ababa");
+  check(memchr(one, 'b', 5) == one+1, 6);	/* Finding first. */
+  check(memchr(one, 'b', 0) == NULL, 7);	/* Zero count. */
+  check(memchr(one, 'a', 1) == one, 8);	/* Singleton case. */
+  (void) strcpy(one, "a\203b");
+  check(memchr(one, 0203, 3) == one+1, 9);	/* Unsignedness. */
+
+  /* now test all possible alignment and length combinations to catch
+     bugs due to unrolled loops (assuming unrolling is limited to no
+     more than 128 byte chunks: */
+  {
+    char buf[128 + sizeof(long)];
+    long align, len, i, pos;
+
+    for (align = 0; align < (long) sizeof(long); ++align) {
+      for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
+	for (i = 0; i < len; ++i) {
+	  buf[align + i] = 'x';		/* don't depend on memset... */
+	}
+	for (pos = 0; pos < len; ++pos) {
+#if 0
+	  printf("align %d, len %d, pos %d\n", align, len, pos);
+#endif
+	  check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
+	  check(memchr(buf + align, 'x', pos) == NULL, 11);
+	  buf[align + pos] = '-';
+	}
+      }
+    }
+  }
+}
+
+static void
+test_memcpy (void)
+{
+  int i;
+  it = "memcpy";
+  check(memcpy(one, "abc", 4) == one, 1);	/* Returned value. */
+  equal(one, "abc", 2);			/* Did the copy go right? */
+
+  (void) strcpy(one, "abcdefgh");
+  (void) memcpy(one+1, "xyz", 2);
+  equal(one, "axydefgh", 3);		/* Basic test. */
+
+  (void) strcpy(one, "abc");
+  (void) memcpy(one, "xyz", 0);
+  equal(one, "abc", 4);			/* Zero-length copy. */
+
+  (void) strcpy(one, "hi there");
+  (void) strcpy(two, "foo");
+  (void) memcpy(two, one, 9);
+  equal(two, "hi there", 5);		/* Just paranoia. */
+  equal(one, "hi there", 6);		/* Stomped on source? */
+
+  for (i = 0; i < 16; i++)
+    {
+      const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+      strcpy (one, x);
+      check (memcpy (one + i, "hi there", 9) == one + i,
+	     7 + (i * 6));		/* Unaligned destination. */
+      check (memcmp (one, x, i) == 0, 8 + (i * 6));  /* Wrote under? */
+      equal (one + i, "hi there", 9 + (i * 6));
+      check (one[i + 9] == 'x', 10 + (i * 6));       /* Wrote over? */
+      check (memcpy (two, one + i, 9) == two,
+	     11 + (i * 6));		/* Unaligned source. */
+      equal (two, "hi there", 12 + (i * 6));
+    }
+}
+
+static void
+test_mempcpy (void)
+{
+  int i;
+  it = "mempcpy";
+  check(mempcpy(one, "abc", 4) == one + 4, 1);	/* Returned value. */
+  equal(one, "abc", 2);			/* Did the copy go right? */
+
+  (void) strcpy(one, "abcdefgh");
+  (void) mempcpy(one+1, "xyz", 2);
+  equal(one, "axydefgh", 3);		/* Basic test. */
+
+  (void) strcpy(one, "abc");
+  (void) mempcpy(one, "xyz", 0);
+  equal(one, "abc", 4);			/* Zero-length copy. */
+
+  (void) strcpy(one, "hi there");
+  (void) strcpy(two, "foo");
+  (void) mempcpy(two, one, 9);
+  equal(two, "hi there", 5);		/* Just paranoia. */
+  equal(one, "hi there", 6);		/* Stomped on source? */
+
+  for (i = 0; i < 16; i++)
+    {
+      const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+      strcpy (one, x);
+      check (mempcpy (one + i, "hi there", 9) == one + i + 9,
+	     7 + (i * 6));		/* Unaligned destination. */
+      check (memcmp (one, x, i) == 0, 8 + (i * 6));  /* Wrote under? */
+      equal (one + i, "hi there", 9 + (i * 6));
+      check (one[i + 9] == 'x', 10 + (i * 6));       /* Wrote over? */
+      check (mempcpy (two, one + i, 9) == two + 9,
+	     11 + (i * 6));		/* Unaligned source. */
+      equal (two, "hi there", 12 + (i * 6));
+    }
+}
+
+static void
+test_memmove (void)
+{
+  it = "memmove";
+  check(memmove(one, "abc", 4) == one, 1);	/* Returned value. */
+  equal(one, "abc", 2);			/* Did the copy go right? */
+
+  (void) strcpy(one, "abcdefgh");
+  (void) memmove(one+1, "xyz", 2);
+  equal(one, "axydefgh", 3);		/* Basic test. */
+
+  (void) strcpy(one, "abc");
+  (void) memmove(one, "xyz", 0);
+  equal(one, "abc", 4);			/* Zero-length copy. */
+
+  (void) strcpy(one, "hi there");
+  (void) strcpy(two, "foo");
+  (void) memmove(two, one, 9);
+  equal(two, "hi there", 5);		/* Just paranoia. */
+  equal(one, "hi there", 6);		/* Stomped on source? */
+
+  (void) strcpy(one, "abcdefgh");
+  (void) memmove(one+1, one, 9);
+  equal(one, "aabcdefgh", 7);		/* Overlap, right-to-left. */
+
+  (void) strcpy(one, "abcdefgh");
+  (void) memmove(one+1, one+2, 7);
+  equal(one, "acdefgh", 8);		/* Overlap, left-to-right. */
+
+  (void) strcpy(one, "abcdefgh");
+  (void) memmove(one, one, 9);
+  equal(one, "abcdefgh", 9);		/* 100% overlap. */
+}
+
+static void
+test_memccpy (void)
+{
+  /* First test like memcpy, then the search part The SVID, the only
+     place where memccpy is mentioned, says overlap might fail, so we
+     don't try it.  Besides, it's hard to see the rationale for a
+     non-left-to-right memccpy.  */
+  it = "memccpy";
+  check(memccpy(one, "abc", 'q', 4) == NULL, 1);	/* Returned value. */
+  equal(one, "abc", 2);			/* Did the copy go right? */
+
+  (void) strcpy(one, "abcdefgh");
+  (void) memccpy(one+1, "xyz", 'q', 2);
+  equal(one, "axydefgh", 3);		/* Basic test. */
+
+  (void) strcpy(one, "abc");
+  (void) memccpy(one, "xyz", 'q', 0);
+  equal(one, "abc", 4);			/* Zero-length copy. */
+
+  (void) strcpy(one, "hi there");
+  (void) strcpy(two, "foo");
+  (void) memccpy(two, one, 'q', 9);
+  equal(two, "hi there", 5);		/* Just paranoia. */
+  equal(one, "hi there", 6);		/* Stomped on source? */
+
+  (void) strcpy(one, "abcdefgh");
+  (void) strcpy(two, "horsefeathers");
+  check(memccpy(two, one, 'f', 9) == two+6, 7);	/* Returned value. */
+  equal(one, "abcdefgh", 8);		/* Source intact? */
+  equal(two, "abcdefeathers", 9);		/* Copy correct? */
+
+  (void) strcpy(one, "abcd");
+  (void) strcpy(two, "bumblebee");
+  check(memccpy(two, one, 'a', 4) == two+1, 10);	/* First char. */
+  equal(two, "aumblebee", 11);
+  check(memccpy(two, one, 'd', 4) == two+4, 12);	/* Last char. */
+  equal(two, "abcdlebee", 13);
+  (void) strcpy(one, "xyz");
+  check(memccpy(two, one, 'x', 1) == two+1, 14);	/* Singleton. */
+  equal(two, "xbcdlebee", 15);
+}
+
+static void
+test_memset (void)
+{
+  int i;
+
+  it = "memset";
+  (void) strcpy(one, "abcdefgh");
+  check(memset(one+1, 'x', 3) == one+1, 1);	/* Return value. */
+  equal(one, "axxxefgh", 2);		/* Basic test. */
+
+  DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (5, 0)
+  /* GCC 5.0 warns about a zero-length memset because the arguments to memset
+     may be in the wrong order.  But we really want to test this.  */
+  DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args")
+#endif
+  (void) memset(one+2, 'y', 0);
+  equal(one, "axxxefgh", 3);		/* Zero-length set. */
+  DIAG_POP_NEEDS_COMMENT;
+
+  (void) memset(one+5, 0, 1);
+  equal(one, "axxxe", 4);			/* Zero fill. */
+  equal(one+6, "gh", 5);			/* And the leftover. */
+
+  (void) memset(one+2, 010045, 1);
+  equal(one, "ax\045xe", 6);		/* Unsigned char convert. */
+
+  /* Non-8bit fill character.  */
+  memset (one, 0x101, sizeof (one));
+  for (i = 0; i < (int) sizeof (one); ++i)
+    check (one[i] == '\01', 7);
+
+  /* Test for more complex versions of memset, for all alignments and
+     lengths up to 256. This test takes a little while, perhaps it should
+     be made weaker?  */
+  {
+    char data[512];
+    int j;
+    int k;
+    int c;
+
+    for (i = 0; i < 512; i++)
+      data[i] = 'x';
+    for (c = 0; c <= 'y'; c += 'y')  /* check for memset(,0,) and
+					memset(,'y',) */
+      for (j = 0; j < 256; j++)
+	for (i = 0; i < 256; i++)
+	  {
+	    memset (data + i, c, j);
+	    for (k = 0; k < i; k++)
+	      if (data[k] != 'x')
+		goto fail;
+	    for (k = i; k < i+j; k++)
+	      {
+		if (data[k] != c)
+		  goto fail;
+		data[k] = 'x';
+	      }
+	    for (k = i+j; k < 512; k++)
+	      if (data[k] != 'x')
+		goto fail;
+	    continue;
+
+	  fail:
+	    check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
+	  }
+  }
+}
+
+static void
+test_bcopy (void)
+{
+  /* Much like memcpy.  Berklix manual is silent about overlap, so
+     don't test it.  */
+  it = "bcopy";
+  (void) bcopy("abc", one, 4);
+  equal(one, "abc", 1);			/* Simple copy. */
+
+  (void) strcpy(one, "abcdefgh");
+  (void) bcopy("xyz", one+1, 2);
+  equal(one, "axydefgh", 2);		/* Basic test. */
+
+  (void) strcpy(one, "abc");
+  (void) bcopy("xyz", one, 0);
+  equal(one, "abc", 3);			/* Zero-length copy. */
+
+  (void) strcpy(one, "hi there");
+  (void) strcpy(two, "foo");
+  (void) bcopy(one, two, 9);
+  equal(two, "hi there", 4);		/* Just paranoia. */
+  equal(one, "hi there", 5);		/* Stomped on source? */
+}
+
+static void
+test_bzero (void)
+{
+  it = "bzero";
+  (void) strcpy(one, "abcdef");
+  bzero(one+2, 2);
+  equal(one, "ab", 1);			/* Basic test. */
+  equal(one+3, "", 2);
+  equal(one+4, "ef", 3);
+
+  (void) strcpy(one, "abcdef");
+  bzero(one+2, 0);
+  equal(one, "abcdef", 4);		/* Zero-length copy. */
+}
+
+static void
+test_strndup (void)
+{
+  char *p, *q;
+  it = "strndup";
+  p = strndup("abcdef", 12);
+  check(p != NULL, 1);
+  if (p != NULL)
+    {
+      equal(p, "abcdef", 2);
+      q = strndup(p + 1, 2);
+      check(q != NULL, 3);
+      if (q != NULL)
+	equal(q, "bc", 4);
+      free (q);
+    }
+  free (p);
+  p = strndup("abc def", 3);
+  check(p != NULL, 5);
+  if (p != NULL)
+    equal(p, "abc", 6);
+  free (p);
+}
+
+static void
+test_bcmp (void)
+{
+  it = "bcmp";
+  check(bcmp("a", "a", 1) == 0, 1);	/* Identity. */
+  check(bcmp("abc", "abc", 3) == 0, 2);	/* Multicharacter. */
+  check(bcmp("abcd", "abce", 4) != 0, 3);	/* Honestly unequal. */
+  check(bcmp("abce", "abcd", 4) != 0, 4);
+  check(bcmp("alph", "beta", 4) != 0, 5);
+  check(bcmp("abce", "abcd", 3) == 0, 6);	/* Count limited. */
+  check(bcmp("abc", "def", 0) == 0, 8);	/* Zero count. */
+}
+
+static void
+test_strerror (void)
+{
+  it = "strerror";
+  check(strerror(EDOM) != 0, 1);
+  check(strerror(ERANGE) != 0, 2);
+  check(strerror(ENOENT) != 0, 3);
+}
+
+static void
+test_strcasecmp (void)
+{
+  it = "strcasecmp";
+  /* Note that the locale is "C".  */
+  check(strcasecmp("a", "a") == 0, 1);
+  check(strcasecmp("a", "A") == 0, 2);
+  check(strcasecmp("A", "a") == 0, 3);
+  check(strcasecmp("a", "b") < 0, 4);
+  check(strcasecmp("c", "b") > 0, 5);
+  check(strcasecmp("abc", "AbC") == 0, 6);
+  check(strcasecmp("0123456789", "0123456789") == 0, 7);
+  check(strcasecmp("", "0123456789") < 0, 8);
+  check(strcasecmp("AbC", "") > 0, 9);
+  check(strcasecmp("AbC", "A") > 0, 10);
+  check(strcasecmp("AbC", "Ab") > 0, 11);
+  check(strcasecmp("AbC", "ab") > 0, 12);
+}
+
+static void
+test_strncasecmp (void)
+{
+  it = "strncasecmp";
+  /* Note that the locale is "C".  */
+  check(strncasecmp("a", "a", 5) == 0, 1);
+  check(strncasecmp("a", "A", 5) == 0, 2);
+  check(strncasecmp("A", "a", 5) == 0, 3);
+  check(strncasecmp("a", "b", 5) < 0, 4);
+  check(strncasecmp("c", "b", 5) > 0, 5);
+  check(strncasecmp("abc", "AbC", 5) == 0, 6);
+  check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
+  check(strncasecmp("", "0123456789", 10) < 0, 8);
+  check(strncasecmp("AbC", "", 5) > 0, 9);
+  check(strncasecmp("AbC", "A", 5) > 0, 10);
+  check(strncasecmp("AbC", "Ab", 5) > 0, 11);
+  check(strncasecmp("AbC", "ab", 5) > 0, 12);
+  check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
+  check(strncasecmp("AbC", "abc", 1) == 0, 14);
+  check(strncasecmp("AbC", "abc", 2) == 0, 15);
+  check(strncasecmp("AbC", "abc", 3) == 0, 16);
+  check(strncasecmp("AbC", "abcd", 3) == 0, 17);
+  check(strncasecmp("AbC", "abcd", 4) < 0, 18);
+  check(strncasecmp("ADC", "abcd", 1) == 0, 19);
+  check(strncasecmp("ADC", "abcd", 2) > 0, 20);
+}
+
+int
+main (void)
+{
+  int status;
+
+  /* Test strcmp first because we use it to test other things.  */
+  test_strcmp ();
+
+  /* Test strcpy next because we need it to set up other tests.  */
+  test_strcpy ();
+
+  /* A closely related function is stpcpy.  */
+  test_stpcpy ();
+
+  /* stpncpy.  */
+  test_stpncpy ();
+
+  /* strcat.  */
+  test_strcat ();
+
+  /* strncat.  */
+  test_strncat ();
+
+  /* strncmp.  */
+  test_strncmp ();
+
+  /* strncpy.  */
+  test_strncpy ();
+
+  /* strlen.  */
+  test_strlen ();
+
+  /* strnlen.  */
+  test_strnlen ();
+
+  /* strchr.  */
+  test_strchr ();
+
+  /* strchrnul.  */
+  test_strchrnul ();
+
+  /* rawmemchr.  */
+  test_rawmemchr ();
+
+  /* index - just like strchr.  */
+  test_index ();
+
+  /* strrchr.  */
+  test_strrchr ();
+
+  /* memrchr.  */
+  test_memrchr ();
+
+  /* rindex - just like strrchr.  */
+  test_rindex ();
+
+  /* strpbrk - somewhat like strchr.  */
+  test_strpbrk ();
+
+  /* strstr - somewhat like strchr.  */
+  test_strstr ();
+
+  /* strspn.  */
+  test_strspn ();
+
+  /* strcspn.  */
+  test_strcspn ();
+
+  /* strtok - the hard one.  */
+  test_strtok ();
+
+  /* strtok_r.  */
+  test_strtok_r ();
+
+  /* strsep.  */
+  test_strsep ();
+
+  /* memcmp.  */
+  test_memcmp ();
+
+  /* memchr.  */
+  test_memchr ();
+
+  /* memcpy - need not work for overlap.  */
+  test_memcpy ();
+
+  /* memmove - must work on overlap.  */
+  test_memmove ();
+
+  /* mempcpy */
+  test_mempcpy ();
+
+  /* memccpy.  */
+  test_memccpy ();
+
+  /* memset.  */
+  test_memset ();
+
+  /* bcopy.  */
+  test_bcopy ();
+
+  /* bzero.  */
+  test_bzero ();
+
+  /* bcmp - somewhat like memcmp.  */
+  test_bcmp ();
+
+  /* strndup.  */
+  test_strndup ();
+
+  /* strerror - VERY system-dependent.  */
+  test_strerror ();
+
+  /* strcasecmp.  Without locale dependencies.  */
+  test_strcasecmp ();
+
+  /* strncasecmp.  Without locale dependencies.  */
+  test_strncasecmp ();
+
+  if (errors == 0)
+    {
+      status = EXIT_SUCCESS;
+      puts("No errors.");
+    }
+  else
+    {
+      status = EXIT_FAILURE;
+      printf("%Zd errors.\n", errors);
+    }
+
+  return status;
+}
diff --git a/REORG.TODO/string/tst-bswap.c b/REORG.TODO/string/tst-bswap.c
new file mode 100644
index 0000000000..def6e2f28a
--- /dev/null
+++ b/REORG.TODO/string/tst-bswap.c
@@ -0,0 +1,75 @@
+/* Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <byteswap.h>
+#include <stdio.h>
+
+extern unsigned long long int wash (unsigned long long int a);
+
+int
+do_test (void)
+{
+  int result = 0;
+
+  /* Test the functions with constant arguments.  */
+  if (bswap_16 (0x1234) != 0x3412)
+    {
+      puts ("bswap_16 (constant) flunked");
+      result = 1;
+    }
+  if (bswap_32 (0x12345678) != 0x78563412)
+    {
+      puts ("bswap_32 (constant) flunked");
+      result = 1;
+    }
+  if (bswap_64 (0x1234567890abcdefULL) != 0xefcdab9078563412ULL)
+    {
+      puts ("bswap_64 (constant) flunked");
+      result = 1;
+    }
+
+  /* Test the functions with non-constant arguments.  */
+  if (bswap_16 (wash (0x1234)) != 0x3412)
+    {
+      puts ("bswap_16 (non-constant) flunked");
+      result = 1;
+    }
+  if (bswap_32 (wash (0x12345678)) != 0x78563412)
+    {
+      puts ("bswap_32 (non-constant) flunked");
+      result = 1;
+    }
+  if (bswap_64 (wash (0x1234567890abcdefULL)) != 0xefcdab9078563412ULL)
+    {
+      puts ("bswap_64 (non-constant) flunked");
+      result = 1;
+    }
+
+  return result;
+}
+
+
+unsigned long long int
+wash (unsigned long long int a)
+{
+  /* Do nothing.  This function simply exists to avoid that the compiler
+     regards the argument to the bswap_*() functions as constant.  */
+  return a + 0;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-cmp.c b/REORG.TODO/string/tst-cmp.c
new file mode 100644
index 0000000000..d7720194e9
--- /dev/null
+++ b/REORG.TODO/string/tst-cmp.c
@@ -0,0 +1,212 @@
+/* Alignment/padding coverage test for string comparison.
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This performs test comparisons with various (mis)alignments and
+   characters in the padding.  It is partly a regression test for bug
+   20327.  */
+
+#include <limits.h>
+#include <malloc.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int
+signum (int val)
+{
+  if (val < 0)
+    return -1;
+  if (val > 0)
+    return 1;
+  else
+    return 0;
+}
+
+static size_t
+max_size_t (size_t left, size_t right)
+{
+  if (left > right)
+    return left;
+  else
+    return right;
+}
+
+/* Wrappers for strncmp and strncasecmp which determine the maximum
+   string length in some, either based on the input string length, or
+   using fixed constants.  */
+
+static int
+strncmp_no_terminator (const char *left, const char *right)
+{
+  size_t left_len = strlen (left);
+  size_t right_len = strlen (right);
+  return strncmp (left, right, max_size_t (left_len, right_len));
+}
+
+static int
+strncasecmp_no_terminator (const char *left, const char *right)
+{
+  size_t left_len = strlen (left);
+  size_t right_len = strlen (right);
+  return strncasecmp (left, right, max_size_t (left_len, right_len));
+}
+
+static int
+strncmp_terminator (const char *left, const char *right)
+{
+  size_t left_len = strlen (left);
+  size_t right_len = strlen (right);
+  return strncmp (left, right, max_size_t (left_len, right_len));
+}
+
+static int
+strncasecmp_terminator (const char *left, const char *right)
+{
+  size_t left_len = strlen (left);
+  size_t right_len = strlen (right);
+  return strncasecmp (left, right, max_size_t (left_len, right_len));
+}
+
+static int
+strncmp_64 (const char *left, const char *right)
+{
+  return strncmp (left, right, 64);
+}
+
+static int
+strncasecmp_64 (const char *left, const char *right)
+{
+  return strncasecmp (left, right, 64);
+}
+
+static int
+strncmp_max (const char *left, const char *right)
+{
+  return strncmp (left, right, SIZE_MAX);
+}
+
+static int
+strncasecmp_max (const char *left, const char *right)
+{
+  return strncasecmp (left, right, SIZE_MAX);
+}
+
+int
+do_test (void)
+{
+  enum {
+    max_align = 64,
+    max_string_length = 33
+  };
+  size_t blob_size = max_align + max_string_length + 1;
+  char *left = memalign (max_align, blob_size);
+  char *right = memalign (max_align, blob_size);
+  if (left == NULL || right == NULL)
+    {
+      printf ("error: out of memory\n");
+      return 1;
+    }
+
+  const struct
+  {
+    const char *name;
+    int (*implementation) (const char *, const char *);
+  } functions[] =
+      {
+        { "strcmp", strcmp },
+        { "strcasecmp", strcasecmp },
+        { "strncmp (without NUL)", strncmp_no_terminator},
+        { "strncasecmp (without NUL)", strncasecmp_no_terminator},
+        { "strncmp (with NUL)", strncmp_terminator},
+        { "strncasecmp (with NUL)", strncasecmp_terminator},
+        { "strncmp (length 64)", strncmp_64},
+        { "strncasecmp (length 64)", strncasecmp_64},
+        { "strncmp (length SIZE_MAX)", strncmp_max},
+        { "strncasecmp (length SIZE_MAX)", strncasecmp_max},
+        { NULL, NULL }
+      };
+  const char *const strings[] =
+    {
+      "",
+      "0",
+      "01",
+      "01234567",
+      "0123456789abcde",
+      "0123456789abcdef",
+      "0123456789abcdefg",
+      "1",
+      "10",
+      "123456789abcdef",
+      "123456789abcdefg",
+      "23456789abcdef",
+      "23456789abcdefg",
+      "abcdefghijklmnopqrstuvwxyzABCDEF",
+      NULL
+    };
+  const unsigned char pads[] =
+    { 0, 1, 32, 64, 128, '0', '1', 'e', 'f', 'g', 127, 192, 255 };
+
+  bool errors = false;
+  for (int left_idx = 0; strings[left_idx] != NULL; ++left_idx)
+    for (int left_align = 0; left_align < max_align; ++left_align)
+      for (unsigned pad_left = 0; pad_left < sizeof (pads); ++pad_left)
+        {
+          memset (left, pads[pad_left], blob_size);
+          strcpy (left + left_align, strings[left_idx]);
+
+          for (int right_idx = 0; strings[right_idx] != NULL; ++right_idx)
+            for (unsigned pad_right = 0; pad_right < sizeof (pads);
+                 ++pad_right)
+              for (int right_align = 0; right_align < max_align;
+                   ++right_align)
+                {
+                  memset (right, pads[pad_right], blob_size);
+                  strcpy (right + right_align, strings[right_idx]);
+
+                  for (int func = 0; functions[func].name != NULL; ++func)
+                    {
+                      int expected = left_idx - right_idx;
+                      int actual = functions[func].implementation
+                        (left + left_align, right + right_align);
+                      if (signum (actual) != signum (expected))
+                        {
+                          printf ("error: mismatch for %s: %d\n"
+                                  "  left:  \"%s\"\n"
+                                  "  right: \"%s\"\n"
+                                  "  pad_left = %u, pad_right = %u,\n"
+                                  "  left_align = %d, right_align = %d\n",
+                                  functions[func].name, actual,
+                                  strings[left_idx], strings[right_idx],
+                                  pad_left, pad_right,
+                                  left_align, right_align);
+                          errors = true;
+                        }
+                    }
+                }
+        }
+  free (right);
+  free (left);
+  return errors;
+}
+
+/* The nested loops need a long time to complete on slower
+   machines.  */
+#define TIMEOUT 300
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-endian.c b/REORG.TODO/string/tst-endian.c
new file mode 100644
index 0000000000..b156ede199
--- /dev/null
+++ b/REORG.TODO/string/tst-endian.c
@@ -0,0 +1,134 @@
+#include <byteswap.h>
+#include <endian.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <libc-diag.h>
+
+#if __GNUC_PREREQ (6, 0)
+/* GCC 6.0 warns on big endian systems about:
+   htobeXX (beXXtoh (i)) != i
+   warning: self-comparison always evaluates to false [-Wtautological-compare]
+   because htobeXX(x) and beXXtoh(x) is defined to (x)
+   in string/endian.h on big endian systems.
+   The same applies to htoleXX/leXXtoh on little endian systems.  */
+# define DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE() \
+  DIAG_IGNORE_NEEDS_COMMENT (6, "-Wtautological-compare")
+#else
+# define DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE()
+#endif
+
+int
+do_test (void)
+{
+  int result = 0;
+
+  for (uint64_t i = 0; i < (~UINT64_C (0)) >> 2; i = (i << 1) + 3)
+    {
+      if (i < UINT64_C (65536))
+	{
+	  DIAG_PUSH_NEEDS_COMMENT;
+	  DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE ();
+	  if (htobe16 (be16toh (i)) != i)
+	    {
+	      printf ("htobe16 (be16toh (%" PRIx64 ")) == %" PRIx16 "\n",
+		      i, (uint16_t) htobe16 (be16toh (i)));
+	      result = 1;
+	    }
+	  if (htole16 (le16toh (i)) != i)
+	    {
+	      printf ("htole16 (le16toh (%" PRIx64 ")) == %" PRIx16 "\n",
+		      i, (uint16_t) htole16 (le16toh (i)));
+	      result = 1;
+	    }
+	  DIAG_POP_NEEDS_COMMENT;
+
+	  uint16_t n[2];
+	  n[__BYTE_ORDER == __LITTLE_ENDIAN] = bswap_16 (i);
+	  n[__BYTE_ORDER == __BIG_ENDIAN] = i;
+	  if (htole16 (i) != n[0])
+	    {
+	      printf ("htole16 (%" PRIx64 ") == %" PRIx16 " != %" PRIx16 "\n",
+		      i, (uint16_t) htole16 (i), n[0]);
+	      result = 1;
+	    }
+	  if (htobe16 (i) != n[1])
+	    {
+	      printf ("htobe16 (%" PRIx64 ") == %" PRIx16 " != %" PRIx16 "\n",
+		      i, (uint16_t) htobe16 (i), n[1]);
+	      result = 1;
+	    }
+	}
+
+      if (i < UINT64_C (4294967296))
+	{
+	  DIAG_PUSH_NEEDS_COMMENT;
+	  DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE ();
+	  if (htobe32 (be32toh (i)) != i)
+	    {
+	      printf ("htobe32 (be32toh (%" PRIx64 ")) == %" PRIx32 "\n",
+		      i, (uint32_t) htobe32 (be32toh (i)));
+	      result = 1;
+	    }
+	  if (htole32 (le32toh (i)) != i)
+	    {
+	      printf ("htole32 (le32toh (%" PRIx64 ")) == %" PRIx32 "\n",
+		      i, (uint32_t) htole32 (le32toh (i)));
+	      result = 1;
+	    }
+	  DIAG_POP_NEEDS_COMMENT;
+
+	  uint32_t n[2];
+	  n[__BYTE_ORDER == __LITTLE_ENDIAN] = bswap_32 (i);
+	  n[__BYTE_ORDER == __BIG_ENDIAN] = i;
+	  if (htole32 (i) != n[0])
+	    {
+	      printf ("htole32 (%" PRIx64 ") == %" PRIx32 " != %" PRIx32 "\n",
+		      i, (uint32_t) htole32 (i), n[0]);
+	      result = 1;
+	    }
+	  if (htobe32 (i) != n[1])
+	    {
+	      printf ("htobe32 (%" PRIx64 ") == %" PRIx32 " != %" PRIx32 "\n",
+		      i, (uint32_t) htobe32 (i), n[1]);
+	      result = 1;
+	    }
+	}
+
+      DIAG_PUSH_NEEDS_COMMENT;
+      DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE ();
+      if (htobe64 (be64toh (i)) != i)
+	{
+	  printf ("htobe64 (be64toh (%" PRIx64 ")) == %" PRIx64 "\n",
+		  i, htobe64 (be64toh (i)));
+	  result = 1;
+	}
+      if (htole64 (le64toh (i)) != i)
+	{
+	  printf ("htole64 (le64toh (%" PRIx64 ")) == %" PRIx64 "\n",
+		  i, htole64 (le64toh (i)));
+	  result = 1;
+	}
+      DIAG_POP_NEEDS_COMMENT;
+
+      uint64_t n[2];
+      n[__BYTE_ORDER == __LITTLE_ENDIAN] = bswap_64 (i);
+      n[__BYTE_ORDER == __BIG_ENDIAN] = i;
+      if (htole64 (i) != n[0])
+	{
+	  printf ("htole64 (%" PRIx64 ") == %" PRIx64 " != %" PRIx64 "\n",
+		  i, htole64 (i), n[0]);
+	  result = 1;
+	}
+      if (htobe64 (i) != n[1])
+	{
+	  printf ("htobe64 (%" PRIx64 ") == %" PRIx64 " != %" PRIx64 "\n",
+		  i, htobe64 (i), n[1]);
+	  result = 1;
+	}
+    }
+
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-inlcall.c b/REORG.TODO/string/tst-inlcall.c
new file mode 100644
index 0000000000..f39f2c33a0
--- /dev/null
+++ b/REORG.TODO/string/tst-inlcall.c
@@ -0,0 +1,84 @@
+/* Tester for calling inline string functions.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+/* Make sure we test the optimized inline functions.  */
+#define __USE_STRING_INLINES	1
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <fcntl.h>
+
+
+int
+do_test (void)
+{
+  int status;
+  int errors = 0;
+  char buf1[1000];
+  char *cp;
+  char ch;
+
+  cp = strcpy (buf1, "hello world");
+  if (strcmp ("hello world", cp++) != 0)
+    {
+      puts ("strcmp test 1 failed");
+      ++errors;
+    }
+
+  cp = buf1;
+  if (strcmp (cp++, "hello world") != 0)
+    {
+      puts ("strcmp test 2 failed");
+      ++errors;
+    }
+
+  ch = 'h';
+  if (strchr ("hello world", ch++) == NULL)
+    {
+      puts ("strchr test 1 failed");
+      ++errors;
+    }
+
+  const char * const hw = "hello world";
+  if (strpbrk (hw, "o") - hw != 4)
+    {
+      puts ("strpbrk test 1 failed");
+      ++errors;
+    }
+
+  if (errors == 0)
+    {
+      status = EXIT_SUCCESS;
+      puts ("No errors.");
+    }
+  else
+    {
+      status = EXIT_FAILURE;
+      printf ("%d errors.\n", errors);
+    }
+  return status;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-strcoll-overflow.c b/REORG.TODO/string/tst-strcoll-overflow.c
new file mode 100644
index 0000000000..826af4f8a8
--- /dev/null
+++ b/REORG.TODO/string/tst-strcoll-overflow.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 2013-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <support/check.h>
+#include <support/test-driver.h>
+
+/* Verify that strcoll does not crash for large strings for which it
+   cannot cache weight lookup results.  The size is large enough to
+   cause integer overflows on 32-bit as well as buffer overflows on
+   64-bit.  */
+#define SIZE 0x40000000ul
+
+int
+do_test (void)
+{
+  TEST_VERIFY_EXIT (setlocale (LC_COLLATE, "en_GB.UTF-8") != NULL);
+
+  char *p = malloc (SIZE);
+  if (p == NULL)
+    {
+      puts ("info: could not allocate memory, cannot run test");
+      return EXIT_UNSUPPORTED;
+    }
+
+  memset (p, 'x', SIZE - 1);
+  p[SIZE - 1] = 0;
+  printf ("info: strcoll result: %d\n", strcoll (p, p));
+  return 0;
+}
+
+/* This test can rung for a long time, but it should complete within
+   this time on reasonably current hardware.  */
+#define TIMEOUT 300
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-strfry.c b/REORG.TODO/string/tst-strfry.c
new file mode 100644
index 0000000000..e4e9018c5b
--- /dev/null
+++ b/REORG.TODO/string/tst-strfry.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <string.h>
+
+int
+do_test (void)
+{
+  char str[] = "this is a test";
+
+  strfry (str);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-strlen.c b/REORG.TODO/string/tst-strlen.c
new file mode 100644
index 0000000000..15fbc8bd7b
--- /dev/null
+++ b/REORG.TODO/string/tst-strlen.c
@@ -0,0 +1,57 @@
+/* Make sure we don't test the optimized inline functions if we want to
+   test the real implementation.  */
+#undef __USE_STRING_INLINES
+
+#include <stdio.h>
+#include <string.h>
+
+int
+do_test (void)
+{
+  static const size_t lens[] = { 0, 1, 0, 2, 0, 1, 0, 3,
+				 0, 1, 0, 2, 0, 1, 0, 4 };
+  char basebuf[24 + 32];
+  size_t base;
+
+  for (base = 0; base < 32; ++base)
+    {
+      char *buf = basebuf + base;
+      size_t words;
+
+      for (words = 0; words < 4; ++words)
+	{
+	  size_t last;
+	  memset (buf, 'a', words * 4);
+
+	  for (last = 0; last < 16; ++last)
+	    {
+	      buf[words * 4 + 0] = (last & 1) != 0 ? 'b' : '\0';
+	      buf[words * 4 + 1] = (last & 2) != 0 ? 'c' : '\0';
+	      buf[words * 4 + 2] = (last & 4) != 0 ? 'd' : '\0';
+	      buf[words * 4 + 3] = (last & 8) != 0 ? 'e' : '\0';
+	      buf[words * 4 + 4] = '\0';
+
+	      if (strlen (buf) != words * 4 + lens[last])
+		{
+		  printf ("\
+strlen failed for base=%Zu, words=%Zu, and last=%Zu (is %zd, expected %zd)\n",
+			  base, words, last,
+			  strlen (buf), words * 4 + lens[last]);
+		  return 1;
+		}
+
+	      if (strnlen (buf, -1) != words * 4 + lens[last])
+		{
+		  printf ("\
+strnlen failed for base=%Zu, words=%Zu, and last=%Zu (is %zd, expected %zd)\n",
+			  base, words, last,
+			  strnlen (buf, -1), words * 4 + lens[last]);
+		  return 1;
+		}
+	    }
+	}
+    }
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-strtok.c b/REORG.TODO/string/tst-strtok.c
new file mode 100644
index 0000000000..628e106a46
--- /dev/null
+++ b/REORG.TODO/string/tst-strtok.c
@@ -0,0 +1,25 @@
+/* Testcase for strtok reported by Andrew Church <achurch@achurch.org>.  */
+#include <stdio.h>
+#include <string.h>
+
+int
+do_test (void)
+{
+  char buf[1] = { 0 };
+  int result = 0;
+
+  if (strtok (buf, " ") != NULL)
+    {
+      puts ("first strtok call did not return NULL");
+      result = 1;
+    }
+  else if (strtok (NULL, " ") != NULL)
+    {
+      puts ("second strtok call did not return NULL");
+      result = 1;
+    }
+
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-strtok_r.c b/REORG.TODO/string/tst-strtok_r.c
new file mode 100644
index 0000000000..fc3ed60b63
--- /dev/null
+++ b/REORG.TODO/string/tst-strtok_r.c
@@ -0,0 +1,38 @@
+/* Test strtok_r regression for BZ #14229.
+   Copyright (C) 2012-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#define BUF1PAGES 1
+#include "test-string.h"
+
+int
+test_main (void)
+{
+  char line[] = "udf 75868 1 - Live 0xffffffffa0bfb000\n";
+  char **saveptrp;
+  char *tok;
+
+  test_init ();
+
+  /* Check strtok_r won't write beyond the size of (*saveptrp).  */
+  saveptrp = (char **) (buf1 + page_size - sizeof (*saveptrp));
+  tok = strtok_r (line, " \t", saveptrp);
+  return strcmp (tok, "udf") != 0;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-strxfrm.c b/REORG.TODO/string/tst-strxfrm.c
new file mode 100644
index 0000000000..ffe191c60d
--- /dev/null
+++ b/REORG.TODO/string/tst-strxfrm.c
@@ -0,0 +1,73 @@
+/* Based on a test case by Paul Eggert.  */
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+char const string[] = "";
+
+
+static int
+test (const char *locale)
+{
+  size_t bufsize;
+  size_t r;
+  size_t l;
+  char *buf;
+  locale_t loc;
+  int result = 0;
+
+  if (setlocale (LC_COLLATE, locale) == NULL)
+    {
+      printf ("cannot set locale \"%s\"\n", locale);
+      return 1;
+    }
+  bufsize = strxfrm (NULL, string, 0) + 1;
+  buf = malloc (bufsize);
+  if (buf == NULL)
+    {
+      printf ("cannot allocate %zd bytes\n", bufsize);
+      return 1;
+    }
+  r = strxfrm (buf, string, bufsize);
+  l = strlen (buf);
+  if (r != l)
+    {
+       printf ("locale \"%s\": strxfrm returned %zu, strlen returned %zu\n",
+	       locale, r, l);
+       result = 1;
+    }
+
+  loc = newlocale (1 << LC_ALL, locale, NULL);
+
+  r = strxfrm_l (buf, string, bufsize, loc);
+  l = strlen (buf);
+  if (r != l)
+    {
+       printf ("locale \"%s\": strxfrm_l returned %zu, strlen returned %zu\n",
+	       locale, r, l);
+       result = 1;
+    }
+
+  freelocale (loc);
+
+  free (buf);
+
+  return result;
+}
+
+
+int
+do_test (void)
+{
+  int result = 0;
+
+  result |= test ("C");
+  result |= test ("en_US.ISO-8859-1");
+  result |= test ("de_DE.UTF-8");
+
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-strxfrm2.c b/REORG.TODO/string/tst-strxfrm2.c
new file mode 100644
index 0000000000..12117e80d6
--- /dev/null
+++ b/REORG.TODO/string/tst-strxfrm2.c
@@ -0,0 +1,84 @@
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+
+int
+do_test (void)
+{
+  static const char test_locale[] = "de_DE.UTF-8";
+
+  int res = 0;
+
+  char buf[20];
+  size_t l1 = strxfrm (NULL, "ab", 0);
+  size_t l2 = strxfrm (buf, "ab", 1);
+  size_t l3 = strxfrm (buf, "ab", sizeof (buf));
+  if (l3 < sizeof (buf) && strlen (buf) != l3)
+    {
+      puts ("C locale l3 test failed");
+      res = 1;
+    }
+
+  size_t l4 = strxfrm (buf, "ab", l1 + 1);
+  if (l4 < l1 + 1 && strlen (buf) != l4)
+    {
+      puts ("C locale l4 test failed");
+      res = 1;
+    }
+
+  buf[l1] = 'Z';
+  size_t l5 = strxfrm (buf, "ab", l1);
+  if (buf[l1] != 'Z')
+    {
+      puts ("C locale l5 test failed");
+      res = 1;
+    }
+
+  if (l1 != l2 || l1 != l3 || l1 != l4 || l1 != l5)
+    {
+      puts ("C locale retval test failed");
+      res = 1;
+    }
+
+  if (setlocale (LC_ALL, test_locale) == NULL)
+    {
+      printf ("cannot set locale \"%s\"\n", test_locale);
+      res = 1;
+    }
+  else
+    {
+      l1 = strxfrm (NULL, "ab", 0);
+      l2 = strxfrm (buf, "ab", 1);
+      l3 = strxfrm (buf, "ab", sizeof (buf));
+      if (l3 < sizeof (buf) && strlen (buf) != l3)
+	{
+	  puts ("UTF-8 locale l3 test failed");
+	  res = 1;
+	}
+
+      l4 = strxfrm (buf, "ab", l1 + 1);
+      if (l4 < l1 + 1 && strlen (buf) != l4)
+	{
+	  puts ("UTF-8 locale l4 test failed");
+	  res = 1;
+	}
+
+      buf[l1] = 'Z';
+      l5 = strxfrm (buf, "ab", l1);
+      if (buf[l1] != 'Z')
+	{
+	  puts ("UTF-8 locale l5 test failed");
+	  res = 1;
+	}
+
+      if (l1 != l2 || l1 != l3 || l1 != l4 || l1 != l5)
+	{
+	  puts ("UTF-8 locale retval test failed");
+	  res = 1;
+	}
+    }
+
+  return res;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-svc.c b/REORG.TODO/string/tst-svc.c
new file mode 100644
index 0000000000..d5cf2c19c9
--- /dev/null
+++ b/REORG.TODO/string/tst-svc.c
@@ -0,0 +1,47 @@
+/* Test for strverscmp() */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define  MAX_STRINGS      256
+#define  MAX_LINE_SIZE    32
+
+static int
+compare (const void *p1, const void *p2)
+{
+  return strverscmp (*((char **) p1), *((char **) p2));
+}
+
+int
+do_test (void)
+{
+  char line[MAX_LINE_SIZE + 1];
+  char *str[MAX_STRINGS];
+  int  count = 0;
+  int  i, n;
+
+  while (count < MAX_STRINGS && fgets (line, MAX_LINE_SIZE, stdin) != NULL)
+    {
+      n = strlen (line) - 1;
+
+      if (line[n] == '\n')
+        line[n] = '\0';
+
+      str[count] = strdup (line);
+
+      if (str[count] == NULL)
+        exit (EXIT_FAILURE);
+
+      ++count;
+    }
+
+  qsort (str, count, sizeof (char *), compare);
+
+  for (i = 0; i < count; ++i)
+    puts (str[i]);
+
+  return EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-svc.expect b/REORG.TODO/string/tst-svc.expect
new file mode 100644
index 0000000000..6240112772
--- /dev/null
+++ b/REORG.TODO/string/tst-svc.expect
@@ -0,0 +1,33 @@
+000
+001
+00
+00a
+01
+01a
+0
+0a
+2.6.20
+2.6.21
+2.8
+2.8-0.4
+20
+21
+22
+212
+CP037
+CP345
+CP1257
+foo
+foo-0.4
+foo-0.4a
+foo-0.4b
+foo-0.5
+foo-0.10.5
+foo-3.01
+foo-3.0
+foo-3.0.0
+foo-3.0.1
+foo-3.2
+foo-3.10
+foo00
+foo0
diff --git a/REORG.TODO/string/tst-svc.input b/REORG.TODO/string/tst-svc.input
new file mode 100644
index 0000000000..247b1c48f9
--- /dev/null
+++ b/REORG.TODO/string/tst-svc.input
@@ -0,0 +1,33 @@
+0a
+00
+0
+01
+001
+01a
+00a
+000
+2.6.21
+20
+212
+21
+22
+foo0
+foo00
+foo-0.4
+foo-3.0
+foo
+foo-3.0.0
+foo-3.0.1
+foo-0.5
+2.6.20
+foo-0.4b
+foo-3.10
+foo-3.2
+foo-3.01
+foo-0.4a
+foo-0.10.5
+CP037
+CP1257
+CP345
+2.8-0.4
+2.8
diff --git a/REORG.TODO/string/tst-svc2.c b/REORG.TODO/string/tst-svc2.c
new file mode 100644
index 0000000000..c0aa03dc18
--- /dev/null
+++ b/REORG.TODO/string/tst-svc2.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static struct
+{
+  const char *str1;
+  const char *str2;
+} tests[] =
+  {
+    { "B0075022800016.gbp.corp.com", "B007502280067.gbp.corp.com" },
+    { "B0075022800016.gbp.corp.com", "B007502357019.GBP.CORP.COM" },
+    { "B007502280067.gbp.corp.com", "B007502357019.GBP.CORP.COM" }
+  };
+#define ntests (sizeof (tests) / sizeof (tests[0]))
+
+
+int
+compare (const char *str1, const char *str2, int exp)
+{
+  int c = strverscmp (str1, str2);
+  if (c != 0)
+    c /= abs (c);
+  return c != exp;
+}
+
+
+int
+do_test (void)
+{
+  int res = 0;
+  for (int i = 0; i < ntests; ++i)
+    {
+      if (compare (tests[i].str1, tests[i].str2, -1))
+	{
+	  printf ("FAIL: \"%s\" > \"%s\"\n", tests[i].str1, tests[i].str2);
+	  res = 1;
+	}
+      if (compare (tests[i].str2, tests[i].str1, +1))
+	{
+	  printf ("FAIL: \"%s\" > \"%s\"\n", tests[i].str2, tests[i].str1);
+	  res = 1;
+	}
+      char *copy1 = strdupa (tests[i].str1);
+      if (compare (tests[i].str1, copy1, 0))
+	{
+	  printf ("FAIL: \"%s\" != \"%s\"\n", tests[i].str1, copy1);
+	  res = 1;
+	}
+      char *copy2 = strdupa (tests[i].str2);
+      if (compare (tests[i].str2, copy2, 0))
+	{
+	  printf ("FAIL: \"%s\" != \"%s\"\n", tests[i].str2, copy2);
+	  res = 1;
+	}
+    }
+  return res;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/tst-xbzero-opt.c b/REORG.TODO/string/tst-xbzero-opt.c
new file mode 100644
index 0000000000..7c25632724
--- /dev/null
+++ b/REORG.TODO/string/tst-xbzero-opt.c
@@ -0,0 +1,298 @@
+/* Test that explicit_bzero block clears are not optimized out.
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This test is conceptually based on a test designed by Matthew
+   Dempsky for the OpenBSD regression suite:
+   <openbsd>/src/regress/lib/libc/explicit_bzero/explicit_bzero.c.
+   The basic idea is, we have a function that contains a
+   block-clearing operation (not necessarily explicit_bzero), after
+   which the block is dead, in the compiler-jargon sense.  Execute
+   that function while running on a user-allocated alternative
+   stack. Then we have another pointer to the memory region affected
+   by the block clear -- namely, the original allocation for the
+   alternative stack -- and can find out whether it actually happened.
+
+   The OpenBSD test uses sigaltstack and SIGUSR1 to get onto an
+   alternative stack.  This causes a number of awkward problems; some
+   operating systems (e.g. Solaris and OSX) wipe the signal stack upon
+   returning to the normal stack, there's no way to be sure that other
+   processes running on the same system will not interfere, and the
+   signal stack is very small so it's not safe to call printf there.
+   This implementation instead uses the <ucontext.h> coroutine
+   interface.  The coroutine stack is still too small to safely use
+   printf, but we know the OS won't erase it, so we can do all the
+   checks and printing from the normal stack.  */
+
+#define _GNU_SOURCE 1
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+/* A byte pattern that is unlikely to occur by chance: the first 16
+   prime numbers (OEIS A000040).  */
+static const unsigned char test_pattern[16] =
+{
+  2, 3, 5, 7,  11, 13, 17, 19,  23, 29, 31, 37,  41, 43, 47, 53
+};
+
+/* Immediately after each subtest returns, we call swapcontext to get
+   back onto the main stack.  That call might itself overwrite the
+   test pattern, so we fill a modest-sized buffer with copies of it
+   and check whether any of them survived.  */
+
+#define PATTERN_SIZE (sizeof test_pattern)
+#define PATTERN_REPS 32
+#define TEST_BUFFER_SIZE (PATTERN_SIZE * PATTERN_REPS)
+
+/* There are three subtests, two of which are sanity checks.
+   Each test follows this sequence:
+
+     main                      coroutine
+     ----                      --------
+     advance cur_subtest
+     swap
+                               call setup function
+                                 prepare test buffer
+                                 swap
+     verify that buffer
+     was filled in
+     swap
+                                 possibly clear buffer
+                                 return
+                               swap
+     check buffer again,
+     according to test
+     expectation
+
+   In the "no_clear" case, we don't do anything to the test buffer
+   between preparing it and letting it go out of scope, and we expect
+   to find it.  This confirms that the test buffer does get filled in
+   and we can find it from the stack buffer.  In the "ordinary_clear"
+   case, we clear it using memset.  Depending on the target, the
+   compiler may not be able to apply dead store elimination to the
+   memset call, so the test does not fail if the memset is not
+   eliminated.  Finally, the "explicit_clear" case uses explicit_bzero
+   and expects _not_ to find the test buffer, which is the real
+   test.  */
+
+static ucontext_t uc_main, uc_co;
+
+/* Always check the test buffer immediately after filling it; this
+   makes externally visible side effects depend on the buffer existing
+   and having been filled in.  */
+static inline __attribute__  ((always_inline)) void
+prepare_test_buffer (unsigned char *buf)
+{
+  for (unsigned int i = 0; i < PATTERN_REPS; i++)
+    memcpy (buf + i*PATTERN_SIZE, test_pattern, PATTERN_SIZE);
+
+  if (swapcontext (&uc_co, &uc_main))
+    abort ();
+}
+
+static void
+setup_no_clear (void)
+{
+  unsigned char buf[TEST_BUFFER_SIZE];
+  prepare_test_buffer (buf);
+}
+
+static void
+setup_ordinary_clear (void)
+{
+  unsigned char buf[TEST_BUFFER_SIZE];
+  prepare_test_buffer (buf);
+  memset (buf, 0, TEST_BUFFER_SIZE);
+}
+
+static void
+setup_explicit_clear (void)
+{
+  unsigned char buf[TEST_BUFFER_SIZE];
+  prepare_test_buffer (buf);
+  explicit_bzero (buf, TEST_BUFFER_SIZE);
+}
+
+enum test_expectation
+  {
+    EXPECT_NONE, EXPECT_SOME, EXPECT_ALL, NO_EXPECTATIONS
+  };
+struct subtest
+{
+  void (*setup_subtest) (void);
+  const char *label;
+  enum test_expectation expected;
+};
+static const struct subtest *cur_subtest;
+
+static const struct subtest subtests[] =
+{
+  { setup_no_clear,       "no clear",       EXPECT_SOME },
+  /* The memset may happen or not, depending on compiler
+     optimizations.  */
+  { setup_ordinary_clear, "ordinary clear", NO_EXPECTATIONS },
+  { setup_explicit_clear, "explicit clear", EXPECT_NONE },
+  { 0,                    0,                -1          }
+};
+
+static void
+test_coroutine (void)
+{
+  while (cur_subtest->setup_subtest)
+    {
+      cur_subtest->setup_subtest ();
+      if (swapcontext (&uc_co, &uc_main))
+	abort ();
+    }
+}
+
+/* All the code above this point runs on the coroutine stack.
+   All the code below this point runs on the main stack.  */
+
+static int test_status;
+static unsigned char *co_stack_buffer;
+static size_t co_stack_size;
+
+static unsigned int
+count_test_patterns (unsigned char *buf, size_t bufsiz)
+{
+  unsigned char *first = memmem (buf, bufsiz, test_pattern, PATTERN_SIZE);
+  if (!first)
+    return 0;
+  unsigned int cnt = 0;
+  for (unsigned int i = 0; i < PATTERN_REPS; i++)
+    {
+      unsigned char *p = first + i*PATTERN_SIZE;
+      if (p + PATTERN_SIZE - buf > bufsiz)
+	break;
+      if (memcmp (p, test_pattern, PATTERN_SIZE) == 0)
+	cnt++;
+    }
+  return cnt;
+}
+
+static void
+check_test_buffer (enum test_expectation expected,
+		   const char *label, const char *stage)
+{
+  unsigned int cnt = count_test_patterns (co_stack_buffer, co_stack_size);
+  switch (expected)
+    {
+    case EXPECT_NONE:
+      if (cnt == 0)
+	printf ("PASS: %s/%s: expected 0 got %d\n", label, stage, cnt);
+      else
+	{
+	  printf ("FAIL: %s/%s: expected 0 got %d\n", label, stage, cnt);
+	  test_status = 1;
+	}
+      break;
+
+    case EXPECT_SOME:
+      if (cnt > 0)
+	printf ("PASS: %s/%s: expected some got %d\n", label, stage, cnt);
+      else
+	{
+	  printf ("FAIL: %s/%s: expected some got 0\n", label, stage);
+	  test_status = 1;
+	}
+      break;
+
+     case EXPECT_ALL:
+      if (cnt == PATTERN_REPS)
+	printf ("PASS: %s/%s: expected %d got %d\n", label, stage,
+		PATTERN_REPS, cnt);
+      else
+	{
+	  printf ("FAIL: %s/%s: expected %d got %d\n", label, stage,
+		  PATTERN_REPS, cnt);
+	  test_status = 1;
+	}
+      break;
+
+    case NO_EXPECTATIONS:
+      printf ("INFO: %s/%s: found %d patterns%s\n", label, stage, cnt,
+	      cnt == 0 ? " (memset not eliminated)" : "");
+      break;
+
+    default:
+      printf ("ERROR: %s/%s: invalid value for 'expected' = %d\n",
+	      label, stage, (int)expected);
+      test_status = 1;
+    }
+}
+
+static void
+test_loop (void)
+{
+  cur_subtest = subtests;
+  while (cur_subtest->setup_subtest)
+    {
+      if (swapcontext (&uc_main, &uc_co))
+	abort ();
+      check_test_buffer (EXPECT_ALL, cur_subtest->label, "prepare");
+      if (swapcontext (&uc_main, &uc_co))
+	abort ();
+      check_test_buffer (cur_subtest->expected, cur_subtest->label, "test");
+      cur_subtest++;
+    }
+  /* Terminate the coroutine.  */
+  if (swapcontext (&uc_main, &uc_co))
+    abort ();
+}
+
+int
+do_test (void)
+{
+  size_t page_alignment = sysconf (_SC_PAGESIZE);
+  if (page_alignment < sizeof (void *))
+    page_alignment = sizeof (void *);
+
+  co_stack_size = SIGSTKSZ + TEST_BUFFER_SIZE;
+  if (co_stack_size < page_alignment * 4)
+    co_stack_size = page_alignment * 4;
+
+  void *p;
+  int err = posix_memalign (&p, page_alignment, co_stack_size);
+  if (err || !p)
+    {
+      printf ("ERROR: allocating alt stack: %s\n", strerror (err));
+      return 2;
+    }
+  co_stack_buffer = p;
+
+  if (getcontext (&uc_co))
+    {
+      printf ("ERROR: allocating coroutine context: %s\n", strerror (err));
+      return 2;
+    }
+  uc_co.uc_stack.ss_sp   = co_stack_buffer;
+  uc_co.uc_stack.ss_size = co_stack_size;
+  uc_co.uc_link          = &uc_main;
+  makecontext (&uc_co, test_coroutine, 0);
+
+  test_loop ();
+  return test_status;
+}
+
+#include <support/test-driver.c>
diff --git a/REORG.TODO/string/wordcopy.c b/REORG.TODO/string/wordcopy.c
new file mode 100644
index 0000000000..65961cd03a
--- /dev/null
+++ b/REORG.TODO/string/wordcopy.c
@@ -0,0 +1,416 @@
+/* _memcopy.c -- subroutines for memory copy functions.
+   Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
+
+#include <stddef.h>
+#include <memcopy.h>
+
+/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
+   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
+   Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
+
+#ifndef WORDCOPY_FWD_ALIGNED
+# define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned
+#endif
+
+void
+WORDCOPY_FWD_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1;
+
+  switch (len % 8)
+    {
+    case 2:
+      a0 = ((op_t *) srcp)[0];
+      srcp -= 6 * OPSIZ;
+      dstp -= 7 * OPSIZ;
+      len += 6;
+      goto do1;
+    case 3:
+      a1 = ((op_t *) srcp)[0];
+      srcp -= 5 * OPSIZ;
+      dstp -= 6 * OPSIZ;
+      len += 5;
+      goto do2;
+    case 4:
+      a0 = ((op_t *) srcp)[0];
+      srcp -= 4 * OPSIZ;
+      dstp -= 5 * OPSIZ;
+      len += 4;
+      goto do3;
+    case 5:
+      a1 = ((op_t *) srcp)[0];
+      srcp -= 3 * OPSIZ;
+      dstp -= 4 * OPSIZ;
+      len += 3;
+      goto do4;
+    case 6:
+      a0 = ((op_t *) srcp)[0];
+      srcp -= 2 * OPSIZ;
+      dstp -= 3 * OPSIZ;
+      len += 2;
+      goto do5;
+    case 7:
+      a1 = ((op_t *) srcp)[0];
+      srcp -= 1 * OPSIZ;
+      dstp -= 2 * OPSIZ;
+      len += 1;
+      goto do6;
+
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	return;
+      a0 = ((op_t *) srcp)[0];
+      srcp -= 0 * OPSIZ;
+      dstp -= 1 * OPSIZ;
+      goto do7;
+    case 1:
+      a1 = ((op_t *) srcp)[0];
+      srcp -=-1 * OPSIZ;
+      dstp -= 0 * OPSIZ;
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	goto do0;
+      goto do8;			/* No-op.  */
+    }
+
+  do
+    {
+    do8:
+      a0 = ((op_t *) srcp)[0];
+      ((op_t *) dstp)[0] = a1;
+    do7:
+      a1 = ((op_t *) srcp)[1];
+      ((op_t *) dstp)[1] = a0;
+    do6:
+      a0 = ((op_t *) srcp)[2];
+      ((op_t *) dstp)[2] = a1;
+    do5:
+      a1 = ((op_t *) srcp)[3];
+      ((op_t *) dstp)[3] = a0;
+    do4:
+      a0 = ((op_t *) srcp)[4];
+      ((op_t *) dstp)[4] = a1;
+    do3:
+      a1 = ((op_t *) srcp)[5];
+      ((op_t *) dstp)[5] = a0;
+    do2:
+      a0 = ((op_t *) srcp)[6];
+      ((op_t *) dstp)[6] = a1;
+    do1:
+      a1 = ((op_t *) srcp)[7];
+      ((op_t *) dstp)[7] = a0;
+
+      srcp += 8 * OPSIZ;
+      dstp += 8 * OPSIZ;
+      len -= 8;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  ((op_t *) dstp)[0] = a1;
+}
+
+/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
+   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
+   DSTP should be aligned for memory operations on `op_t's, but SRCP must
+   *not* be aligned.  */
+
+#ifndef WORDCOPY_FWD_DEST_ALIGNED
+# define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned
+#endif
+
+void
+WORDCOPY_FWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1, a2, a3;
+  int sh_1, sh_2;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp to make it aligned for copy.  */
+
+  sh_1 = 8 * (srcp % OPSIZ);
+  sh_2 = 8 * OPSIZ - sh_1;
+
+  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
+     it points in the middle of.  */
+  srcp &= -OPSIZ;
+
+  switch (len % 4)
+    {
+    case 2:
+      a1 = ((op_t *) srcp)[0];
+      a2 = ((op_t *) srcp)[1];
+      srcp -= 1 * OPSIZ;
+      dstp -= 3 * OPSIZ;
+      len += 2;
+      goto do1;
+    case 3:
+      a0 = ((op_t *) srcp)[0];
+      a1 = ((op_t *) srcp)[1];
+      srcp -= 0 * OPSIZ;
+      dstp -= 2 * OPSIZ;
+      len += 1;
+      goto do2;
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	return;
+      a3 = ((op_t *) srcp)[0];
+      a0 = ((op_t *) srcp)[1];
+      srcp -=-1 * OPSIZ;
+      dstp -= 1 * OPSIZ;
+      len += 0;
+      goto do3;
+    case 1:
+      a2 = ((op_t *) srcp)[0];
+      a3 = ((op_t *) srcp)[1];
+      srcp -=-2 * OPSIZ;
+      dstp -= 0 * OPSIZ;
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	goto do0;
+      goto do4;			/* No-op.  */
+    }
+
+  do
+    {
+    do4:
+      a0 = ((op_t *) srcp)[0];
+      ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
+    do3:
+      a1 = ((op_t *) srcp)[1];
+      ((op_t *) dstp)[1] = MERGE (a3, sh_1, a0, sh_2);
+    do2:
+      a2 = ((op_t *) srcp)[2];
+      ((op_t *) dstp)[2] = MERGE (a0, sh_1, a1, sh_2);
+    do1:
+      a3 = ((op_t *) srcp)[3];
+      ((op_t *) dstp)[3] = MERGE (a1, sh_1, a2, sh_2);
+
+      srcp += 4 * OPSIZ;
+      dstp += 4 * OPSIZ;
+      len -= 4;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
+}
+
+/* _wordcopy_bwd_aligned -- Copy block finishing right before
+   SRCP to block finishing right before DSTP with LEN `op_t' words
+   (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
+   operations on `op_t's.  */
+
+#ifndef WORDCOPY_BWD_ALIGNED
+# define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned
+#endif
+
+void
+WORDCOPY_BWD_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1;
+
+  switch (len % 8)
+    {
+    case 2:
+      srcp -= 2 * OPSIZ;
+      dstp -= 1 * OPSIZ;
+      a0 = ((op_t *) srcp)[1];
+      len += 6;
+      goto do1;
+    case 3:
+      srcp -= 3 * OPSIZ;
+      dstp -= 2 * OPSIZ;
+      a1 = ((op_t *) srcp)[2];
+      len += 5;
+      goto do2;
+    case 4:
+      srcp -= 4 * OPSIZ;
+      dstp -= 3 * OPSIZ;
+      a0 = ((op_t *) srcp)[3];
+      len += 4;
+      goto do3;
+    case 5:
+      srcp -= 5 * OPSIZ;
+      dstp -= 4 * OPSIZ;
+      a1 = ((op_t *) srcp)[4];
+      len += 3;
+      goto do4;
+    case 6:
+      srcp -= 6 * OPSIZ;
+      dstp -= 5 * OPSIZ;
+      a0 = ((op_t *) srcp)[5];
+      len += 2;
+      goto do5;
+    case 7:
+      srcp -= 7 * OPSIZ;
+      dstp -= 6 * OPSIZ;
+      a1 = ((op_t *) srcp)[6];
+      len += 1;
+      goto do6;
+
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	return;
+      srcp -= 8 * OPSIZ;
+      dstp -= 7 * OPSIZ;
+      a0 = ((op_t *) srcp)[7];
+      goto do7;
+    case 1:
+      srcp -= 9 * OPSIZ;
+      dstp -= 8 * OPSIZ;
+      a1 = ((op_t *) srcp)[8];
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	goto do0;
+      goto do8;			/* No-op.  */
+    }
+
+  do
+    {
+    do8:
+      a0 = ((op_t *) srcp)[7];
+      ((op_t *) dstp)[7] = a1;
+    do7:
+      a1 = ((op_t *) srcp)[6];
+      ((op_t *) dstp)[6] = a0;
+    do6:
+      a0 = ((op_t *) srcp)[5];
+      ((op_t *) dstp)[5] = a1;
+    do5:
+      a1 = ((op_t *) srcp)[4];
+      ((op_t *) dstp)[4] = a0;
+    do4:
+      a0 = ((op_t *) srcp)[3];
+      ((op_t *) dstp)[3] = a1;
+    do3:
+      a1 = ((op_t *) srcp)[2];
+      ((op_t *) dstp)[2] = a0;
+    do2:
+      a0 = ((op_t *) srcp)[1];
+      ((op_t *) dstp)[1] = a1;
+    do1:
+      a1 = ((op_t *) srcp)[0];
+      ((op_t *) dstp)[0] = a0;
+
+      srcp -= 8 * OPSIZ;
+      dstp -= 8 * OPSIZ;
+      len -= 8;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  ((op_t *) dstp)[7] = a1;
+}
+
+/* _wordcopy_bwd_dest_aligned -- Copy block finishing right
+   before SRCP to block finishing right before DSTP with LEN `op_t'
+   words (not LEN bytes!).  DSTP should be aligned for memory
+   operations on `op_t', but SRCP must *not* be aligned.  */
+
+#ifndef WORDCOPY_BWD_DEST_ALIGNED
+# define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned
+#endif
+
+void
+WORDCOPY_BWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1, a2, a3;
+  int sh_1, sh_2;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp to make it aligned for copy.  */
+
+  sh_1 = 8 * (srcp % OPSIZ);
+  sh_2 = 8 * OPSIZ - sh_1;
+
+  /* Make srcp aligned by rounding it down to the beginning of the op_t
+     it points in the middle of.  */
+  srcp &= -OPSIZ;
+  srcp += OPSIZ;
+
+  switch (len % 4)
+    {
+    case 2:
+      srcp -= 3 * OPSIZ;
+      dstp -= 1 * OPSIZ;
+      a2 = ((op_t *) srcp)[2];
+      a1 = ((op_t *) srcp)[1];
+      len += 2;
+      goto do1;
+    case 3:
+      srcp -= 4 * OPSIZ;
+      dstp -= 2 * OPSIZ;
+      a3 = ((op_t *) srcp)[3];
+      a2 = ((op_t *) srcp)[2];
+      len += 1;
+      goto do2;
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	return;
+      srcp -= 5 * OPSIZ;
+      dstp -= 3 * OPSIZ;
+      a0 = ((op_t *) srcp)[4];
+      a3 = ((op_t *) srcp)[3];
+      goto do3;
+    case 1:
+      srcp -= 6 * OPSIZ;
+      dstp -= 4 * OPSIZ;
+      a1 = ((op_t *) srcp)[5];
+      a0 = ((op_t *) srcp)[4];
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+	goto do0;
+      goto do4;			/* No-op.  */
+    }
+
+  do
+    {
+    do4:
+      a3 = ((op_t *) srcp)[3];
+      ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
+    do3:
+      a2 = ((op_t *) srcp)[2];
+      ((op_t *) dstp)[2] = MERGE (a3, sh_1, a0, sh_2);
+    do2:
+      a1 = ((op_t *) srcp)[1];
+      ((op_t *) dstp)[1] = MERGE (a2, sh_1, a3, sh_2);
+    do1:
+      a0 = ((op_t *) srcp)[0];
+      ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
+
+      srcp -= 4 * OPSIZ;
+      dstp -= 4 * OPSIZ;
+      len -= 4;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
+}
diff --git a/REORG.TODO/string/xpg-strerror.c b/REORG.TODO/string/xpg-strerror.c
new file mode 100644
index 0000000000..4a5e59d5ab
--- /dev/null
+++ b/REORG.TODO/string/xpg-strerror.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+
+
+/* Fill buf with a string describing the errno code in ERRNUM.  */
+int
+__xpg_strerror_r (int errnum, char *buf, size_t buflen)
+{
+  const char *estr = __strerror_r (errnum, buf, buflen);
+
+  /* We know that __strerror_r returns buf (with a dynamically computed
+     string) if errnum is invalid, otherwise it returns a string whose
+     storage has indefinite extent.  */
+  if (estr == buf)
+    {
+      assert (errnum < 0 || errnum >= _sys_nerr_internal
+	      || _sys_errlist_internal[errnum] == NULL);
+      return EINVAL;
+    }
+  else
+    {
+      assert (errnum >= 0 && errnum < _sys_nerr_internal
+	      && _sys_errlist_internal[errnum] != NULL);
+
+      size_t estrlen = strlen (estr);
+
+      /* Terminate the string in any case.  */
+      if (buflen > 0)
+	*((char *) __mempcpy (buf, estr, MIN (buflen - 1, estrlen))) = '\0';
+
+      return buflen <= estrlen ? ERANGE : 0;
+    }
+}