about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Makefile2
-rw-r--r--hurd/report-wait.c146
-rw-r--r--posix/getopt.c1
-rw-r--r--wcsmbs/Makefile31
-rw-r--r--wcsmbs/mbsadvance.c38
-rw-r--r--wcsmbs/mbscat.c56
-rw-r--r--wcsmbs/mbschr.c60
-rw-r--r--wcsmbs/mbscmp.c63
-rw-r--r--wcsmbs/mbscpy.c47
-rw-r--r--wcsmbs/mbsdup.c51
-rw-r--r--wcsmbs/mbslen.c45
-rw-r--r--wcsmbs/mbsncat.c61
-rw-r--r--wcsmbs/mbsncmp.c68
-rw-r--r--wcsmbs/mbsncpy.c55
-rw-r--r--wcsmbs/mbsrchr.c61
-rw-r--r--wcsmbs/mbstomb.c42
-rw-r--r--wcsmbs/mbstr.h69
-rw-r--r--wcsmbs/wcscat.c49
-rw-r--r--wcsmbs/wcschr.c35
-rw-r--r--wcsmbs/wcscmp.c42
-rw-r--r--wcsmbs/wcscpy.c44
-rw-r--r--wcsmbs/wcscspn.c38
-rw-r--r--wcsmbs/wcsdup.c38
-rw-r--r--wcsmbs/wcslen.c42
-rw-r--r--wcsmbs/wcsncat.c79
-rw-r--r--wcsmbs/wcsncmp.c70
-rw-r--r--wcsmbs/wcsncpy.c85
-rw-r--r--wcsmbs/wcspbrk.c35
-rw-r--r--wcsmbs/wcsrchr.c38
-rw-r--r--wcsmbs/wcsspn.c45
-rw-r--r--wcsmbs/wcstok.c67
-rw-r--r--wcsmbs/wcstr.h84
-rw-r--r--wcsmbs/wcswcs.c97
34 files changed, 1787 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index e1a5621125..510507f735 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 Wed Feb  7 18:48:30 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
+	* Makefile (subdirs): Added wcsmbs.
+	* wcsmbs: New directory of wide char/multibyte char functions from
+	drepper.
+
 	* hurd/hurdmsg.c (_S_msg_report_wait): Function removed.
 	* hurd/report-wait.c: New file.
 	* hurd/Makefile (routines): Added report-wait.
diff --git a/Makefile b/Makefile
index 260254a87b..0042e78052 100644
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@ endif
 
 # These are the subdirectories containing the library source.
 subdirs = csu assert ctype db locale intl math setjmp signal stdlib	\
-	  stdio-common $(stdio) malloc string time dirent grp pwd	\
+	  stdio-common $(stdio) malloc string wcsmbs time dirent grp pwd\
 	  posix io termios resource misc socket sysvipc gmon gnulib	\
 	  $(wildcard crypt) manual $(sysdep-subdirs) elf
 export subdirs := $(subdirs)	# Benign, useless in GNU make before 3.63.
diff --git a/hurd/report-wait.c b/hurd/report-wait.c
new file mode 100644
index 0000000000..521c5220b9
--- /dev/null
+++ b/hurd/report-wait.c
@@ -0,0 +1,146 @@
+/* Report on what a thread in our task is waiting for.
+Copyright (C) 1996 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/fd.h>
+#include <string.h>
+#include <assert.h>
+#include <hurd/msg_server.h>
+#include "thread_state.h"
+#include "intr-msg.h"
+
+static void
+describe_number (string_t description, const char *flavor, int i)
+{
+  char *p = __stpcpy (description, flavor);
+  p += i / 10 + 1;
+  *p = '\0';
+  do
+    {
+      *--p = '0' + i % 10;
+      i /= 10;
+    } while (i != 0);
+  assert (p[-1] == '#');
+}
+
+static void
+describe_port (string_t description, mach_port_t port)
+{
+  int i;
+
+  if (port == __mach_task_self ())
+    {
+      strcpy (description, "task-self");
+      return;
+    }
+
+  for (i = 0; i < _hurd_nports; ++i)
+    if (port == _hurd_ports[i].port)
+      {
+	describe_number (description, "init#", i);
+	return;
+      }
+
+  if (_hurd_init_dtable)
+    {
+      for (i = 0; i < _hurd_init_dtablesize; ++i)
+	if (port == _hurd_init_dtable[i])
+	  {
+	    describe_number (description, "fd#", i);
+	    return;
+	  }
+    }
+  else if (_hurd_dtable)
+    {
+      for (i = 0; i < _hurd_dtablesize; ++i)
+	if (_hurd_dtable[i] == NULL)
+	  continue;
+	else if (port == _hurd_dtable[i]->port.port)
+	  {
+	    describe_number (description, "fd#", i);
+	    return;
+	  }
+	else if (port == _hurd_dtable[i]->ctty.port)
+	  {
+	    describe_number (description, "bgfd#", i);
+	    return;
+	  }
+    }
+
+  describe_number (description, "port#", port);
+}
+
+
+kern_return_t
+_S_msg_report_wait (mach_port_t msgport, thread_t thread,
+		    string_t description, int *msgid)
+{
+  *msgid = 0;
+
+  if (thread == _hurd_msgport_thread)
+    /* Cute.  */
+    strcpy (description, "msgport");
+  else
+    {
+      /* Make sure this is really one of our threads.  */
+
+      struct hurd_sigstate *ss;
+
+      __mutex_lock (&_hurd_siglock);
+      for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
+	if (ss->thread == thread)
+	  break;
+      __mutex_unlock (&_hurd_siglock);
+      if (ss == NULL)
+	/* To hell with you.  */
+	return EINVAL;
+
+      if (ss->suspended != MACH_PORT_NULL)
+	strcpy (description, "sigsuspend");
+      else
+	{
+	  /* Examine the thread's state to see if it is blocked in an RPC.  */
+
+	  struct machine_thread_state state;
+	  mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT;
+	  error_t err;
+
+	  err = __thread_get_state (thread, MACHINE_THREAD_STATE_FLAVOR,
+				    (integer_t *) &state, &count);
+	  if (err)
+	    return err;
+	  assert (count == MACHINE_THREAD_STATE_COUNT);
+	  if (SYSCALL_EXAMINE (&state, msgid))
+	    {
+	      /* Blocked in a system call.  */
+	      if (*msgid == -25)
+		/* mach_msg system call.  Examine its parameters.  */
+		describe_port (description, MSG_EXAMINE (&state, msgid));
+	      else
+		strcpy (description, "kernel");
+	    }
+	  else
+	    description[0] = '\0';
+	}
+    }
+
+  __mach_port_deallocate (__mach_task_self (), thread);
+  return 0;
+}
diff --git a/posix/getopt.c b/posix/getopt.c
index 0da5965137..4e11744db8 100644
--- a/posix/getopt.c
+++ b/posix/getopt.c
@@ -61,6 +61,7 @@ Cambridge, MA 02139, USA.  */
 /* Don't include stdlib.h for non-GNU C libraries because some of them
    contain conflicting prototypes for getopt.  */
 #include <stdlib.h>
+#include <unistd.h>
 #endif	/* GNU C library.  */
 
 #ifndef _
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
new file mode 100644
index 0000000000..6d75c7b01f
--- /dev/null
+++ b/wcsmbs/Makefile
@@ -0,0 +1,31 @@
+# Copyright (C) 1995, 1996 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 Library General Public License as
+# published by the Free Software Foundation; either version 2 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
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public
+# License along with the GNU C Library; see the file COPYING.LIB.  If
+# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+# Cambridge, MA 02139, USA.
+
+#
+#	Sub-makefile for wcsmbs portion of the library.
+#
+subdir	:= wcsmbs
+
+headers	:= wcstr.h mbstr.h
+
+routines := mbsadvance mbscat mbschr mbscmp mbscpy mbsdup mbslen	\
+	    mbsncat mbsncmp mbsncpy mbsrchr mbstomb wcscat wcschr wcscmp\
+	    wcscpy wcscspn wcsdup wcslen wcsncat wcsncmp wcsncpy wcspbrk\
+	    wcsrchr wcsspn wcstok wcswcs
+
+include ../Rules
diff --git a/wcsmbs/mbsadvance.c b/wcsmbs/mbsadvance.c
new file mode 100644
index 0000000000..b6649935d7
--- /dev/null
+++ b/wcsmbs/mbsadvance.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+
+/* Advance pointer to multibyte string by one character.  */
+char *
+mbsadvance (mbs)
+    const char *mbs;
+{
+  int clen;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  clen = mblen (mbs, MB_CUR_MAX);
+
+  /* FIXME: when current character is illegal return same character.  */
+  return clen <= 0 ? (char *) mbs : (char *) (mbs + clen);
+}
+
diff --git a/wcsmbs/mbscat.c b/wcsmbs/mbscat.c
new file mode 100644
index 0000000000..324cad9cc8
--- /dev/null
+++ b/wcsmbs/mbscat.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+
+/* Append SRC onto DEST.  */
+char *
+mbscat (dest, src)
+    char *dest;
+    const char *src;
+{
+  const char * const d = dest;
+  size_t len = 0;
+  int clen = 0;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  do
+    {
+      dest += clen;
+      clen = mblen (dest, MB_CUR_MAX);
+    }
+  while (clen > 0);
+
+  clen = 0;
+  do
+    {
+      len += clen;
+      clen = mblen (&src[len], MB_CUR_MAX);
+    }
+  while (clen > 0);
+
+  (void) memcpy ((void *) dest, (void *) src, len);
+  dest[len] = '\0';	    /* '\0' is the multibyte representation of L'\0' */
+
+  return (char *) d;
+}
+
diff --git a/wcsmbs/mbschr.c b/wcsmbs/mbschr.c
new file mode 100644
index 0000000000..f8a7d21857
--- /dev/null
+++ b/wcsmbs/mbschr.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+#define __need_wchar_t
+#include <stddef.h>
+
+
+/* Find the first occurence of MBC in MBS.  */
+char *
+mbschr (mbs, mbc)
+    const char *mbs;
+    mbchar_t mbc;
+{
+  int clen;
+  wchar_t wc;
+  wchar_t c;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  clen = mbtowc (&wc, (char *) &mbc, MB_CUR_MAX);
+  if (clen < 0)
+    /* FIXME: search character is illegal.  */
+    return NULL;
+  else if (clen == 0)
+    wc = L'\0';
+
+  clen = 0;
+  do
+    {
+      mbs += clen;
+      clen = mbtowc (&c, mbs, MB_CUR_MAX);
+    }
+  while (clen > 0 && c != wc);
+
+  if (clen < 0 || (clen == 0 && wc != L'\0'))
+    /* FIXME: clen < 0 means illegal character in string.  */
+    return NULL;
+
+  return (char *) mbs;
+}
+
diff --git a/wcsmbs/mbscmp.c b/wcsmbs/mbscmp.c
new file mode 100644
index 0000000000..04f6f473b9
--- /dev/null
+++ b/wcsmbs/mbscmp.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+#define __need_wchar_t
+/* FIXME: should be defined in stddef.h.
+!!! #define __need_uwchar_t  */
+typedef unsigned int uwchar_t;
+#include <stddef.h>
+
+
+/* Compare MBS1 and MBS2.  */
+int
+mbscmp (mbs1, mbs2)
+    const char *mbs1;
+    const char *mbs2;
+{
+  int len1 = 0;
+  int len2 = 0;
+  uwchar_t c1;
+  uwchar_t c2;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  do
+    {
+      len1 = mbtowc ((wchar_t *) &c1, mbs1, MB_CUR_MAX);
+      len2 = mbtowc ((wchar_t *) &c2, mbs2, MB_CUR_MAX);
+
+      if (len1 == 0)
+	return len2 == 0 ? 0 : -1;
+      if (len2 == 0)
+	return 1;
+      if (len1 < 0 || len2 < 0)
+	/* FIXME: an illegal character appears.	 What to do?  */
+	return c1 - c2;
+
+      mbs1 += len1;
+      mbs2 += len2;
+    }
+  while (c1 == c2);
+
+  return c1 - c2;
+}
+
diff --git a/wcsmbs/mbscpy.c b/wcsmbs/mbscpy.c
new file mode 100644
index 0000000000..8f354ceede
--- /dev/null
+++ b/wcsmbs/mbscpy.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+
+/* Copy SRC to DEST.  */
+char *
+mbscpy (dest, src)
+    char *dest;
+    const char *src;
+{
+  size_t len = 0;
+  int clen = 0;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  do
+    {
+      len += clen;
+      clen = mblen (&src[len], MB_CUR_MAX);
+    }
+  while (clen > 0);
+
+  (void) memcpy ((void *) dest, (void *) src, len);
+  dest[len] = '\0';	    /* '\0' is the multibyte representation of L'\0' */
+
+  return dest;
+}
+
diff --git a/wcsmbs/mbsdup.c b/wcsmbs/mbsdup.c
new file mode 100644
index 0000000000..2d196dd06d
--- /dev/null
+++ b/wcsmbs/mbsdup.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+
+/* Duplicate MBS, returning an identical malloc'd string.  */
+char *
+mbsdup (mbs)
+    const char *mbs;
+{
+  size_t len = 0;
+  int clen = 0;
+  char *retval;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  do
+    {
+      len += clen;
+      clen = mblen (&mbs[len], MB_CUR_MAX);
+    }
+  while (clen > 0);
+
+  retval = (char *) malloc (len + 1);
+  if (retval != NULL)
+    {
+      (void) memcpy ((void *) retval, (void *) mbs, len);
+      retval[len] = '\0';   /* '\0' is the multibyte representation of L'\0' */
+    }
+
+  return retval;
+}
+
diff --git a/wcsmbs/mbslen.c b/wcsmbs/mbslen.c
new file mode 100644
index 0000000000..f8077d0fb9
--- /dev/null
+++ b/wcsmbs/mbslen.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+
+/* Return the length of MBS.  */
+size_t
+mbslen (mbs)
+    const char *mbs;
+{
+  size_t len = 0;
+  int clen = 0;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  do
+    {
+      len += clen;
+      clen = mblen (&mbs[len], MB_CUR_MAX);
+    }
+  while (clen > 0);
+
+  /* FIXME: if string contains an illegal character the length upto this
+     character is returned.  */
+  return len;
+}
+
diff --git a/wcsmbs/mbsncat.c b/wcsmbs/mbsncat.c
new file mode 100644
index 0000000000..3dd4df1c70
--- /dev/null
+++ b/wcsmbs/mbsncat.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+
+/* Append no more than N multi-byte characters from SRC onto DEST.  */
+char *
+mbsncat (dest, src, n)
+    char *dest;
+    const char *src;
+    size_t n;
+{
+  const char * const d = dest;
+  const char * const s = src;
+  size_t len = 0;
+  int clen = 0;
+
+  if (n == 0)
+    return (char *) d;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  do
+    {
+      dest += clen;
+      clen = mblen (dest, MB_CUR_MAX);
+    }
+  while (clen > 0);
+
+  clen = 0;
+  do
+    {
+      src += clen;
+      clen = mblen (src, MB_CUR_MAX);
+    }
+  while (clen > 0 && ++len < n);
+
+  (void) memcpy ((void *) dest, (void *) s, src - s);
+  dest[src - s] = '\0';	    /* '\0' is the multibyte representation of L'\0' */
+
+  return (char *) d;
+}
+
diff --git a/wcsmbs/mbsncmp.c b/wcsmbs/mbsncmp.c
new file mode 100644
index 0000000000..43fb527afb
--- /dev/null
+++ b/wcsmbs/mbsncmp.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+#define __need_wchar_t
+/* FIXME: should be defined in stddef.h.
+!!! #define __need_uwchar_t  */
+typedef unsigned int uwchar_t;
+#include <stddef.h>
+
+
+/* Compare N characters of MBS1 and MBS2.  */
+int
+mbsncmp (mbs1, mbs2, n)
+    const char *mbs1;
+    const char *mbs2;
+    size_t n;
+{
+  size_t len = 0;
+  int clen1 = 0;
+  int clen2 = 0;
+  uwchar_t c1;
+  uwchar_t c2;
+
+  if (n == 0)
+    return 0;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  do
+    {
+      clen1 = mbtowc ((wchar_t *) &c1, mbs1, MB_CUR_MAX);
+      clen2 = mbtowc ((wchar_t *) &c2, mbs2, MB_CUR_MAX);
+
+      if (clen1 == 0)
+	return clen2 == 0 ? 0 : -1;
+      if (clen2 == 0)
+	return 1;
+      if (clen1 < 0 || clen2 < 0)
+	/* FIXME: an illegal character appears.	 What to do?  */
+	return c1 - c2;
+
+      mbs1 += clen1;
+      mbs2 += clen2;
+    }
+  while (c1 == c2 && ++len < n);
+
+  return len < n ? c1 - c2 : 0;
+}
+
diff --git a/wcsmbs/mbsncpy.c b/wcsmbs/mbsncpy.c
new file mode 100644
index 0000000000..09aecefd03
--- /dev/null
+++ b/wcsmbs/mbsncpy.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+
+/* Copy no more than N characters of SRC to DEST.  */
+char *
+mbsncpy (dest, src, n)
+    char *dest;
+    const char *src;
+    size_t n;
+{
+  const char * const s = src;
+  size_t len = 0;
+  int clen = 0;
+
+  if (n == 0)
+    {
+      dest[0] = '\0';	    /* '\0' is the multibyte representation of L'\0' */
+      return dest;
+    }
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  do
+    {
+      src += clen;
+      clen = mblen (src, MB_CUR_MAX);
+    }
+  while (clen > 0 && ++len < n);
+
+  (void) memcpy ((void *) dest, (void *) s, src - s);
+  dest[src - s] = '\0';	    /* '\0' is the multibyte representation of L'\0' */
+
+  return dest;
+}
+
diff --git a/wcsmbs/mbsrchr.c b/wcsmbs/mbsrchr.c
new file mode 100644
index 0000000000..62fa219dd2
--- /dev/null
+++ b/wcsmbs/mbsrchr.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+#define __need_wchar_t
+#include <stddef.h>
+
+
+/* Find the last occurence of MBC in MBS.  */
+char *
+mbsrchr (mbs, mbc)
+    const char *mbs;
+    mbchar_t mbc;
+{
+  const char * retval = NULL;
+  int clen;
+  wchar_t wc;
+  wchar_t c;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  clen = mbtowc (&wc, (char *) &mbc, MB_CUR_MAX);
+  if (clen < 0)
+    /* FIXME: search character MBC is illegal.	*/
+    return NULL;
+  else if (clen == 0)
+    wc = L'\0';
+
+  clen = 0;
+  do
+    {
+      mbs += clen;
+      clen = mbtowc (&c, mbs, MB_CUR_MAX);
+    }
+  while (clen > 0 && c != wc);
+
+  if (clen < 0)
+    /* FIXME: clen < 0 means illegal character in string.  */
+    return NULL;
+
+  return (char *) (clen > 0 || (clen == 0 && wc == L'\0') ? mbs : retval);
+}
+
diff --git a/wcsmbs/mbstomb.c b/wcsmbs/mbstomb.c
new file mode 100644
index 0000000000..f593ced3cb
--- /dev/null
+++ b/wcsmbs/mbstomb.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mbstr.h>
+#include <stdlib.h>
+
+
+/* Advance pointer to multibyte string by one character.  */
+mbchar_t
+mbstomb (mbs)
+    const char *mbs;
+{
+  mbchar_t retval = 0;
+  int clen;
+
+  /* Reset multibyte characters to their initial state.	 */
+  (void) mblen ((char *) NULL, 0);
+
+  clen = mblen (mbs, MB_CUR_MAX);
+
+  if (clen > 0)
+    (void) memcpy (&retval, mbs, clen);
+
+  /* FIXME: when current character is illegal return '\0'.  */
+  return retval;
+}
+
diff --git a/wcsmbs/mbstr.h b/wcsmbs/mbstr.h
new file mode 100644
index 0000000000..7cb94bf85b
--- /dev/null
+++ b/wcsmbs/mbstr.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the, Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef _MBSTRING_H
+
+#define _MBSTRING_H 1
+#include <features.h>
+#include <limits.h>
+
+#define __need_size_t
+#include <stddef.h>
+
+__BEGIN_DECLS
+
+/* This data type should be large enough to contain MB_CUR_MAX bytes.  */
+typedef unsigned int mbchar_t;
+
+
+/* Copy SRC to DEST.  */
+extern char *mbscpy __P ((char *__dest, __const char *__src));
+/* Copy no more than N multi-byte characters of SRC to DEST.  */
+extern char *mbsncpy __P ((char *__dest, __const char *__src, size_t __n));
+
+/* Append SRC onto DEST.  */
+extern char *mbscat __P ((char *__dest, __const char *__src));
+/* Append no more than N characters from SRC onto DEST.  */
+extern char *mbsncat __P ((char *__dest, __const char *__src, size_t __n));
+
+/* Compare S1 and S2.  */
+extern int mbscmp __P ((__const char *__s1, __const char *__s2));
+/* Compare N characters of S1 and S2.  */
+extern int mbsncmp __P ((__const char *__s1, __const char *__s2, size_t __n));
+
+/* Duplicate MBS, returning an identical malloc'd string.  */
+extern char *mbsdup __P ((__const char *__s));
+
+/* Find the first occurence of MBC in MBS.  */
+extern char *mbschr __P ((__const char *__mbs, mbchar_t mbc));
+/* Find the last occurence of MBC in MBS.  */
+extern char *mbsrchr __P ((__const char *__mbs, mbchar_t mbc));
+
+/* Return the length of MBS.  */
+extern size_t mbslen __P ((__const char *__mbs));
+
+
+/* Advance pointer to multibyte string by one character.  */
+extern char *mbsadvance __P ((__const char *__mbs));
+
+/* Return first character in MBS.  */
+extern mbchar_t mbstomb __P ((__const char *__mbs));
+
+__END_DECLS
+
+#endif /* mbstring.h */
diff --git a/wcsmbs/wcscat.c b/wcsmbs/wcscat.c
new file mode 100644
index 0000000000..4ff5c861e4
--- /dev/null
+++ b/wcsmbs/wcscat.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Append SRC on the end of DEST.  */
+wchar_t *
+wcscat (dest, src)
+    wchar_t *dest;
+    const wchar_t *src;
+{
+  register wchar_t *s1 = dest;
+  register const wchar_t *s2 = src;
+  wchar_t c;
+
+  /* Find the end of the string.  */
+  do
+    c = *s1++;
+  while (c != L'\0');
+
+  /* Make S1 point before the next character, so we can increment
+     it while memory is read (wins on pipelined cpus).	*/
+  s1 -= 2;
+
+  do
+    {
+      c = *s2++;
+      *++s1 = c;
+    }
+  while (c != L'\0');
+
+  return dest;
+}
diff --git a/wcsmbs/wcschr.c b/wcsmbs/wcschr.c
new file mode 100644
index 0000000000..85a1801839
--- /dev/null
+++ b/wcsmbs/wcschr.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Find the first ocurrence of WC in WCS.  */
+wchar_t *
+wcschr (wcs, wc)
+    register const wchar_t *wcs;
+    register const wchar_t wc;
+{
+  while (*wcs != L'\0')
+    if (*wcs == wc)
+      return (wchar_t *) wcs;
+    else
+      ++wcs;
+
+  return NULL;
+}
diff --git a/wcsmbs/wcscmp.c b/wcsmbs/wcscmp.c
new file mode 100644
index 0000000000..84ecae8553
--- /dev/null
+++ b/wcsmbs/wcscmp.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Compare S1 and S2, returning less than, equal to or
+   greater than zero if S1 is lexiographically less than,
+   equal to or greater than S2.	 */
+int
+wcscmp (s1, s2)
+    const wchar_t *s1;
+    const wchar_t *s2;
+{
+  uwchar_t c1, c2;
+
+  do
+    {
+      c1 = (uwchar_t) *s1++;
+      c2 = (uwchar_t) *s2++;
+      if (c1 == L'\0')
+	return c1 - c2;
+    }
+  while (c1 == c2);
+
+  return c1 - c2;
+}
diff --git a/wcsmbs/wcscpy.c b/wcsmbs/wcscpy.c
new file mode 100644
index 0000000000..a45747edf1
--- /dev/null
+++ b/wcsmbs/wcscpy.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+#define __need_ptrdiff_t
+#include <stddef.h>
+
+
+/* Copy SRC to DEST.  */
+wchar_t *
+wcscpy (dest, src)
+    wchar_t *dest;
+    const wchar_t *src;
+{
+  wchar_t *wcp = (wchar_t *) src;
+  wchar_t c;
+  const ptrdiff_t off = dest - src - 1;
+
+  do
+    {
+      c = *wcp++;
+      wcp[off] = c;
+    }
+  while (c != L'\0');
+
+  return dest;
+}
+
diff --git a/wcsmbs/wcscspn.c b/wcsmbs/wcscspn.c
new file mode 100644
index 0000000000..0dc4d9bc9e
--- /dev/null
+++ b/wcsmbs/wcscspn.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Return the length of the maximum initial segment
+   of WCS which contains only wide-characters not in REJECT.  */
+size_t
+wcscspn (wcs, reject)
+    const wchar_t *wcs;
+    const wchar_t *reject;
+{
+  register size_t count = 0;
+
+  while (*wcs != L'\0')
+    if (wcschr (reject, *wcs++) == NULL)
+      ++count;
+    else
+      return count;
+
+  return count;
+}
diff --git a/wcsmbs/wcsdup.c b/wcsmbs/wcsdup.c
new file mode 100644
index 0000000000..62c64621de
--- /dev/null
+++ b/wcsmbs/wcsdup.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+/* Duplicate S, returning an identical malloc'd string.	 */
+wchar_t *
+wcsdup (s)
+    const wchar_t *s;
+{
+  size_t len = (wcslen (s) + 1) * sizeof (wchar_t);
+  void *new = malloc (len);
+
+  if (new == NULL)
+    return NULL;
+
+  memcpy (new, (void *) s, len);
+
+  return (wchar_t *) new;
+}
diff --git a/wcsmbs/wcslen.c b/wcsmbs/wcslen.c
new file mode 100644
index 0000000000..2907cb3cc4
--- /dev/null
+++ b/wcsmbs/wcslen.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Copy SRC to DEST.  */
+size_t
+wcslen (s)
+    const wchar_t *s;
+{
+  size_t len = 0;
+
+  while (s[len] != L'\0')
+    {
+      if (s[++len] == L'\0')
+	return len;
+      if (s[++len] == L'\0')
+	return len;
+      if (s[++len] == L'\0')
+	return len;
+      ++len;
+    }
+
+  return len;
+}
+
diff --git a/wcsmbs/wcsncat.c b/wcsmbs/wcsncat.c
new file mode 100644
index 0000000000..7851d7048d
--- /dev/null
+++ b/wcsmbs/wcsncat.c
@@ -0,0 +1,79 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Append no more than N wide-character of SRC onto DEST.  */
+wchar_t *
+wcsncat (dest, src, n)
+      wchar_t *dest;
+      const wchar_t *src;
+      size_t n;
+{
+  wchar_t c;
+  wchar_t * const s = dest;
+
+  /* Find the end of DEST.  */
+  do
+    c = *dest++;
+  while (c != L'\0');
+
+  /* Make DEST point before next character, so we can increment
+     it while memory is read (wins on pipelined cpus).	*/
+  dest -= 2;
+
+  if (n >= 4)
+    {
+      size_t n4 = n >> 2;
+      do
+	{
+	  c = *src++;
+	  *++dest = c;
+	  if (c == L'\0')
+	    return s;
+	  c = *src++;
+	  *++dest = c;
+	  if (c == L'\0')
+	    return s;
+	  c = *src++;
+	  *++dest = c;
+	  if (c == L'\0')
+	    return s;
+	  c = *src++;
+	  *++dest = c;
+	  if (c == L'\0')
+	    return s;
+	} while (--n4 > 0);
+      n &= 3;
+    }
+
+  while (n > 0)
+    {
+      c = *src++;
+      *++dest = c;
+      if (c == L'\0')
+	return s;
+      n--;
+    }
+
+  if (c != L'\0')
+    *++dest = L'\0';
+
+  return s;
+}
diff --git a/wcsmbs/wcsncmp.c b/wcsmbs/wcsncmp.c
new file mode 100644
index 0000000000..9f1829bc5d
--- /dev/null
+++ b/wcsmbs/wcsncmp.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Compare no more than N characters of S1 and S2,
+   returning less than, equal to or greater than zero
+   if S1 is lexiographically less than, equal to or
+   greater than S2.  */
+int
+wcsncmp (s1, s2, n)
+      const wchar_t *s1;
+      const wchar_t *s2;
+      size_t n;
+{
+  uwchar_t c1 = L'\0';
+  uwchar_t c2 = L'\0';
+
+  if (n >= 4)
+    {
+      size_t n4 = n >> 2;
+      do
+	{
+	  c1 = (uwchar_t) *s1++;
+	  c2 = (uwchar_t) *s2++;
+	  if (c1 == L'\0' || c1 != c2)
+	    return c1 - c2;
+	  c1 = (uwchar_t) *s1++;
+	  c2 = (uwchar_t) *s2++;
+	  if (c1 == L'\0' || c1 != c2)
+	    return c1 - c2;
+	  c1 = (uwchar_t) *s1++;
+	  c2 = (uwchar_t) *s2++;
+	  if (c1 == L'\0' || c1 != c2)
+	    return c1 - c2;
+	  c1 = (uwchar_t) *s1++;
+	  c2 = (uwchar_t) *s2++;
+	  if (c1 == L'\0' || c1 != c2)
+	    return c1 - c2;
+	} while (--n4 > 0);
+      n &= 3;
+    }
+
+  while (n > 0)
+    {
+      c1 = (uwchar_t) *s1++;
+      c2 = (uwchar_t) *s2++;
+      if (c1 == L'\0' || c1 != c2)
+	return c1 - c2;
+      n--;
+    }
+
+  return c1 - c2;
+}
diff --git a/wcsmbs/wcsncpy.c b/wcsmbs/wcsncpy.c
new file mode 100644
index 0000000000..740c71ecf8
--- /dev/null
+++ b/wcsmbs/wcsncpy.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Copy no more than N wide-characters of SRC to DEST.	*/
+wchar_t *
+wcsncpy (dest, src, n)
+      wchar_t *dest;
+      const wchar_t *src;
+      size_t n;
+{
+  wchar_t c;
+  wchar_t * const s = dest;
+
+  --dest;
+
+  if (n >= 4)
+    {
+      size_t n4 = n >> 2;
+
+      for (;;)
+	{
+	  c = *src++;
+	  *++dest = c;
+	  if (c == L'\0')
+	    break;
+	  c = *src++;
+	  *++dest = c;
+	  if (c == L'\0')
+	    break;
+	  c = *src++;
+	  *++dest = c;
+	  if (c == L'\0')
+	    break;
+	  c = *src++;
+	  *++dest = c;
+	  if (c == L'\0')
+	    break;
+	  if (--n4 == 0)
+	    goto last_chars;
+	}
+      n = n - (dest - s) - 1;
+      if (n == 0)
+	return s;
+      goto zero_fill;
+    }
+
+ last_chars:
+  n &= 3;
+  if (n == 0)
+    return s;
+
+  do
+    {
+      c = *src++;
+      *++dest = c;
+      if (--n == 0)
+	return s;
+    }
+  while (c != L'\0');
+
+ zero_fill:
+  do
+    *++dest = L'\0';
+  while (--n > 0);
+
+  return s;
+}
diff --git a/wcsmbs/wcspbrk.c b/wcsmbs/wcspbrk.c
new file mode 100644
index 0000000000..83892bacb0
--- /dev/null
+++ b/wcsmbs/wcspbrk.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Find the first ocurrence in WCS of any wide-character in ACCEPT.  */
+wchar_t *
+wcspbrk (wcs, accept)
+      register const wchar_t *wcs;
+      register const wchar_t *accept;
+{
+  while (*wcs != L'\0')
+    if (wcschr (accept, *wcs) == NULL)
+      ++wcs;
+    else
+      return (wchar_t *) wcs;
+
+  return NULL;
+}
diff --git a/wcsmbs/wcsrchr.c b/wcsmbs/wcsrchr.c
new file mode 100644
index 0000000000..87823b3709
--- /dev/null
+++ b/wcsmbs/wcsrchr.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Find the last ocurrence of WC in WCS.  */
+wchar_t *
+wcsrchr (wcs, wc)
+    register const wchar_t *wcs;
+    register const wchar_t wc;
+{
+  const wchar_t *retval = NULL;
+
+  while (*wcs != L'\0')
+    {
+      if (*wcs == wc)
+	retval = wcs;
+      ++wcs;
+    }
+
+  return (wchar_t *) retval;
+}
diff --git a/wcsmbs/wcsspn.c b/wcsmbs/wcsspn.c
new file mode 100644
index 0000000000..81a557c7b7
--- /dev/null
+++ b/wcsmbs/wcsspn.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+
+
+/* Return the length of the maximum initial segment
+   of WCS which contains only wide-characters in ACCEPT.  */
+size_t
+wcsspn (wcs, accept)
+    const wchar_t *wcs;
+    const wchar_t *accept;
+{
+  register const wchar_t *p;
+  register const wchar_t *a;
+  register size_t count = 0;
+
+  for (p = wcs; *p != L'\0'; ++p)
+    {
+      for (a = accept; *a != L'\0'; ++a)
+	if (*p == *a)
+	  break;
+      if (*a == L'\0')
+	return count;
+      else
+	++count;
+    }
+
+  return count;
+}
diff --git a/wcsmbs/wcstok.c b/wcsmbs/wcstok.c
new file mode 100644
index 0000000000..191bbd5960
--- /dev/null
+++ b/wcsmbs/wcstok.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <wcstr.h>
+#include <errno.h>
+
+
+static wchar_t *olds = NULL;
+
+/* Parse WCS into tokens separated by characters in DELIM.
+   If WCS is NULL, the last string wcstok() was called with is
+   used.  */
+wchar_t *
+wcstok (wcs, delim)
+    register wchar_t *wcs;
+    register const wchar_t *delim;
+{
+  wchar_t *token;
+
+  if (wcs == NULL)
+    {
+      if (olds == NULL)
+	{
+	  errno = EINVAL;
+	  return NULL;
+	}
+      else
+	wcs = olds;
+    }
+
+  /* Scan leading delimiters.  */
+  wcs += wcsspn (wcs, delim);
+  if (*wcs == L'\0')
+    {
+      olds = NULL;
+      return NULL;
+    }
+
+  /* Find the end of the token.	 */
+  token = wcs;
+  wcs = wcspbrk (token, delim);
+  if (wcs == NULL)
+    /* This token finishes the string.	*/
+    olds = NULL;
+  else
+    {
+      /* Terminate the token and make OLDS point past it.  */
+      *wcs = L'\0';
+      olds = wcs + 1;
+    }
+  return token;
+}
diff --git a/wcsmbs/wcstr.h b/wcsmbs/wcstr.h
new file mode 100644
index 0000000000..e9cc64ddc1
--- /dev/null
+++ b/wcsmbs/wcstr.h
@@ -0,0 +1,84 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef _WCSTRING_H
+
+#define _WCSTRING_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Get size_t, wchar_t, uwchar_t and NULL from <stddef.h>.  */
+#define __need_size_t
+#define __need_wchar_t
+/* #define __need_uwchar_t */
+#define __need_NULL
+#include <stddef.h>
+
+/* FIXME: Should go with this or another name in stddef.h.  */
+typedef unsigned int uwchar_t;
+
+
+/* Copy SRC to DEST.  */
+extern wchar_t *wcscpy __P ((wchar_t *__dest, __const wchar_t *__src));
+/* Copy no more than N wide-characters of SRC to DEST.  */
+extern wchar_t *wcsncpy __P ((wchar_t *__dest, __const wchar_t *__src,
+			      size_t __n));
+
+/* Append SRC onto DEST.  */
+extern wchar_t *wcscat __P ((wchar_t *__dest, __const wchar_t *__src));
+/* Append no more than N wide-characters of SRC onto DEST.  */
+extern wchar_t *wcsncat __P ((wchar_t *__dest, __const wchar_t *__src,
+			      size_t __n));
+
+/* Compare S1 and S2.  */
+extern int wcscmp __P ((__const wchar_t *__s1, __const wchar_t *__s2));
+/* Compare N wide-characters of S1 and S2.  */
+extern int wcsncmp __P ((__const wchar_t *__s1, __const wchar_t *__s2,
+			 size_t __n));
+
+/* Duplicate S, returning an identical malloc'd string.  */
+extern wchar_t *wcsdup __P ((__const wchar_t *__s));
+
+/* Find the first occurence of WC in WCS.  */
+extern wchar_t *wcschr __P ((__const wchar_t *__wcs, wchar_t __wc));
+/* Find the last occurence of WC in WCS.  */
+extern wchar_t *wcsrchr __P ((__const wchar_t *__wcs, wchar_t __wc));
+
+/* Return the length of the initial segmet of WCS which
+   consists entirely of wide-characters not in REJECT.  */
+extern size_t wcscspn __P ((__const wchar_t *__wcs,
+			    __const wchar_t *__reject));
+/* Return the length of the initial segmet of WCS which
+   consists entirely of wide-characters in  ACCEPT.  */
+extern size_t wcsspn __P ((__const wchar_t *__wcs, __const wchar_t *__accept));
+/* Find the first occurence in WCS of any character in ACCEPT.  */
+extern wchar_t *wcspbrk __P ((__const wchar_t *__wcs,
+			      __const wchar_t *__accept));
+/* Find the first occurence of NEEDLE in HAYSTACK.  */
+extern wchar_t *wcswcs __P ((__const wchar_t *__haystack,
+			     __const wchar_t *__needle));
+/* Divide WCS into tokens separated by characters in DELIM.  */
+extern wchar_t *wcstok __P ((wchar_t *__s, __const wchar_t *__delim));
+
+/* Return the number of wide-characters in S.  */
+extern size_t wcslen __P ((__const wchar_t *__s));
+
+__END_DECLS
+
+#endif /* wcstring.h */
diff --git a/wcsmbs/wcswcs.c b/wcsmbs/wcswcs.c
new file mode 100644
index 0000000000..4b1f2ace54
--- /dev/null
+++ b/wcsmbs/wcswcs.c
@@ -0,0 +1,97 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.	 If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/*
+ * The original strstr() file contains the following comment:
+ *
+ * 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 */
+
+#include <wcstr.h>
+
+wchar_t *
+wcswcs (haystack, needle)
+    const wchar_t *haystack;
+    const wchar_t *needle;
+{
+  register wchar_t b, c;
+
+  if ((b = *needle) != L'\0')
+    {
+      haystack--;				/* possible ANSI violation */
+      do
+	if ((c = *++haystack) == L'\0')
+	  goto ret0;
+      while (c != b);
+
+      if (!(c = *++needle))
+	goto foundneedle;
+      ++needle;
+      goto jin;
+
+      for (;;)
+	{ 
+	  register wchar_t a;
+	  register const wchar_t *rhaystack, *rneedle;
+
+	  do
+	    {
+	      if (!(a = *++haystack))
+		goto ret0;
+	      if (a == b)
+		break;
+	      if ((a = *++haystack) == L'\0')
+		goto ret0;
+shloop:	      ;
+	    }
+	  while (a != b);
+
+jin:	  if (!(a = *++haystack))
+	    goto ret0;
+
+	  if (a != c)
+	    goto shloop;
+
+	  if (*(rhaystack = haystack-- + 1) == (a = *(rneedle = needle)))
+	    do
+	      {
+		if (a == L'\0')
+		  goto foundneedle;
+		if (*++rhaystack != (a = *++needle))
+		  break;
+		if (a == L'\0')
+		  goto foundneedle;
+	      }
+	    while (*++rhaystack == (a = *++needle));
+
+	  needle=rneedle;		  /* took the register-poor approach */
+
+	  if (a == L'\0')
+	    break;
+	}
+    }
+foundneedle:
+  return (wchar_t*)haystack;
+ret0:
+  return NULL;
+}