summary refs log tree commit diff
path: root/stdlib
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-02-18 01:27:10 +0000
committerRoland McGrath <roland@gnu.org>1995-02-18 01:27:10 +0000
commit28f540f45bbacd939bfd07f213bcad2bf730b1bf (patch)
tree15f07c4c43d635959c6afee96bde71fb1b3614ee /stdlib
downloadglibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.tar.gz
glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.tar.xz
glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.zip
initial import
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/Makefile43
-rw-r--r--stdlib/abs.c30
-rw-r--r--stdlib/alloca.h44
-rw-r--r--stdlib/atexit.c65
-rw-r--r--stdlib/atof.c30
-rw-r--r--stdlib/atoi.c30
-rw-r--r--stdlib/atol.c30
-rw-r--r--stdlib/bsearch.c51
-rw-r--r--stdlib/div.c92
-rw-r--r--stdlib/exit.c70
-rw-r--r--stdlib/exit.h44
-rw-r--r--stdlib/labs.c31
-rw-r--r--stdlib/ldiv.c92
-rw-r--r--stdlib/mblen.c31
-rw-r--r--stdlib/mbstowcs.c78
-rw-r--r--stdlib/mbtowc.c84
-rw-r--r--stdlib/msort.c103
-rw-r--r--stdlib/on_exit.c37
-rw-r--r--stdlib/qsort.c243
-rw-r--r--stdlib/rand.c30
-rw-r--r--stdlib/random.c357
-rw-r--r--stdlib/stdlib.h289
-rw-r--r--stdlib/strtod.c1027
-rw-r--r--stdlib/strtof.c12
-rw-r--r--stdlib/strtol.c189
-rw-r--r--stdlib/strtold.c12
-rw-r--r--stdlib/strtoq.c22
-rw-r--r--stdlib/strtoul.c21
-rw-r--r--stdlib/strtouq.c22
-rw-r--r--stdlib/testdiv.c33
-rw-r--r--stdlib/testdiv.input2
-rw-r--r--stdlib/testmb.c69
-rw-r--r--stdlib/testrand.c51
-rw-r--r--stdlib/testsort.c38
-rw-r--r--stdlib/tst-strtod.c94
-rw-r--r--stdlib/tst-strtol.c127
-rw-r--r--stdlib/wcstombs.c77
-rw-r--r--stdlib/wctomb.c72
38 files changed, 3772 insertions, 0 deletions
diff --git a/stdlib/Makefile b/stdlib/Makefile
new file mode 100644
index 0000000000..1a1498c662
--- /dev/null
+++ b/stdlib/Makefile
@@ -0,0 +1,43 @@
+# Copyright (C) 1991, 1992, 1993, 1994, 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.
+
+#
+#	Makefile for stdlib routines
+#
+subdir	:= stdlib
+
+headers	:= stdlib.h alloca.h
+
+routines	:=							      \
+	atof atoi atol							      \
+	abort								      \
+	bsearch qsort msort						      \
+	getenv putenv setenv						      \
+	exit on_exit atexit						      \
+	abs labs							      \
+	div ldiv							      \
+	mblen mbstowcs mbtowc wcstombs wctomb				      \
+	random rand 							      \
+	strtol strtoul strtoq strtouq					      \
+	strtof strtod strtold						      \
+	system
+
+distribute	:= exit.h
+tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv
+
+include ../Rules
diff --git a/stdlib/abs.c b/stdlib/abs.c
new file mode 100644
index 0000000000..b8db100b41
--- /dev/null
+++ b/stdlib/abs.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <stdlib.h>
+
+#undef	abs
+
+/* Return the absolute value of I.  */
+__CONSTVALUE
+int
+DEFUN(abs, (i), int i)
+{
+  return(i < 0 ? -i : i);
+}
diff --git a/stdlib/alloca.h b/stdlib/alloca.h
new file mode 100644
index 0000000000..4e9de464a3
--- /dev/null
+++ b/stdlib/alloca.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 1992 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	_ALLOCA_H
+#define	_ALLOCA_H	1
+#include <features.h>
+
+#define	__need_size_t
+#include <stddef.h>
+
+__BEGIN_DECLS
+
+/* Remove any previous definitions.  */
+#undef	__alloca
+#undef	alloca
+
+/* Allocate a block that will be freed when the calling function exits.  */
+extern __ptr_t __alloca __P ((size_t __size));
+extern __ptr_t alloca __P ((size_t __size));
+
+#ifdef	__GNUC__
+#define	__alloca(size)	__builtin_alloca(size)
+#endif /* GCC.  */
+
+#define	alloca(size)	__alloca(size)
+
+__END_DECLS
+
+#endif /* alloca.h */
diff --git a/stdlib/atexit.c b/stdlib/atexit.c
new file mode 100644
index 0000000000..a2ab453576
--- /dev/null
+++ b/stdlib/atexit.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <stdlib.h>
+#include "exit.h"
+
+
+/* Register FUNC to be executed by `exit'.  */
+int
+DEFUN(atexit, (func), void EXFUN((*func), (NOARGS)))
+{
+  struct exit_function *new = __new_exitfn();
+
+  if (new == NULL)
+    return -1;
+
+  new->flavor = ef_at;
+  new->func.at = func;
+  return 0;
+}
+
+
+static struct exit_function_list fnlist = { NULL, 0, };
+struct exit_function_list *__exit_funcs = &fnlist;
+
+struct exit_function *
+DEFUN_VOID(__new_exitfn)
+{
+  register struct exit_function_list *l;
+
+  for (l = __exit_funcs; l != NULL; l = l->next)
+    {
+      register size_t i;
+      for (i = 0; i < l->idx; ++i)
+	if (l->fns[i].flavor == ef_free)
+	  return &l->fns[i];
+      if (l->idx < sizeof(l->fns) / sizeof(l->fns[0]))
+	return &l->fns[l->idx++];
+    }
+
+  l = (struct exit_function_list *) malloc(sizeof(struct exit_function_list));
+  if (l == NULL)
+    return NULL;
+  l->next = __exit_funcs;
+  __exit_funcs = l;
+
+  l->idx = 1;
+  return &l->fns[0];
+}
diff --git a/stdlib/atof.c b/stdlib/atof.c
new file mode 100644
index 0000000000..79585464d1
--- /dev/null
+++ b/stdlib/atof.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <stdlib.h>
+
+#undef	atof
+
+
+/* Convert a string to a double.  */
+double
+DEFUN(atof, (nptr), CONST char *nptr)
+{
+  return(strtod(nptr, (char **) NULL));
+}
diff --git a/stdlib/atoi.c b/stdlib/atoi.c
new file mode 100644
index 0000000000..9fe280cc3e
--- /dev/null
+++ b/stdlib/atoi.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <stdlib.h>
+
+#undef	atoi
+
+
+/* Convert a string to an int.  */
+int
+DEFUN(atoi, (nptr), CONST char *nptr)
+{
+  return((int) strtol(nptr, (char **) NULL, 10));
+}
diff --git a/stdlib/atol.c b/stdlib/atol.c
new file mode 100644
index 0000000000..75f599c107
--- /dev/null
+++ b/stdlib/atol.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <stdlib.h>
+
+#undef	atol
+
+
+/* Convert a string to a long int.  */
+long int
+DEFUN(atol, (nptr), CONST char *nptr)
+{
+  return(strtol(nptr, (char **) NULL, 10));
+}
diff --git a/stdlib/bsearch.c b/stdlib/bsearch.c
new file mode 100644
index 0000000000..d798eabd2b
--- /dev/null
+++ b/stdlib/bsearch.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1991, 1992 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 <ansidecl.h>
+#include <stdlib.h>
+
+
+/* Perform a binary search for KEY in BASE which has NMEMB elements
+   of SIZE bytes each.  The comparisons are done by (*COMPAR)().  */
+PTR
+DEFUN(bsearch, (key, base, nmemb, size, compar),
+      register CONST PTR key AND register CONST PTR base AND
+      size_t nmemb AND register size_t size AND
+      register int EXFUN((*compar), (CONST PTR, CONST PTR)))
+{
+  register size_t l, u, idx;
+  register CONST PTR p;
+  register int comparison;
+
+  l = 0;
+  u = nmemb;
+  while (l < u)
+    {
+      idx = (l + u) / 2;
+      p = (PTR) (((CONST char *) base) + (idx * size));
+      comparison = (*compar)(key, p);
+      if (comparison < 0)
+	u = idx;
+      else if (comparison > 0)
+	l = idx + 1;
+      else
+	return (PTR) p;
+    }
+
+  return NULL;
+}
diff --git a/stdlib/div.c b/stdlib/div.c
new file mode 100644
index 0000000000..5a0ee7da38
--- /dev/null
+++ b/stdlib/div.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 1992 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.  */
+
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ansidecl.h>
+#include <stdlib.h>
+
+
+/* Return the `div_t' representation of NUMER over DENOM.  */
+__CONSTVALUE
+div_t
+DEFUN(div, (numer, denom), int numer AND int denom)
+{
+  div_t result;
+
+  result.quot = numer / denom;
+  result.rem = numer % denom;
+
+  /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where
+     NUMER / DENOM is to be computed in infinite precision.  In
+     other words, we should always truncate the quotient towards
+     zero, never -infinity.  Machine division and remainer may
+     work either way when one or both of NUMER or DENOM is
+     negative.  If only one is negative and QUOT has been
+     truncated towards -infinity, REM will have the same sign as
+     DENOM and the opposite sign of NUMER; if both are negative
+     and QUOT has been truncated towards -infinity, REM will be
+     positive (will have the opposite sign of NUMER).  These are
+     considered `wrong'.  If both are NUM and DENOM are positive,
+     RESULT will always be positive.  This all boils down to: if
+     NUMER >= 0, but REM < 0, we got the wrong answer.  In that
+     case, to get the right answer, add 1 to QUOT and subtract
+     DENOM from REM.  */
+
+  if (numer >= 0 && result.rem < 0)
+    {
+      ++result.quot;
+      result.rem -= denom;
+    }
+
+  return result;
+}
diff --git a/stdlib/exit.c b/stdlib/exit.c
new file mode 100644
index 0000000000..4f33a25cc4
--- /dev/null
+++ b/stdlib/exit.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 1991, 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 <ansidecl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "exit.h"
+
+#ifdef HAVE_GNU_LD
+#include "set-hooks.h"
+DEFINE_HOOK (__libc_atexit, (void))
+#endif
+
+
+/* Call all functions registered with `atexit' and `on_exit',
+   in the reverse of the order in which they were registered
+   perform stdio cleanup, and terminate program execution with STATUS.  */
+void
+DEFUN(exit, (status), int status)
+{
+  register CONST struct exit_function_list *l;
+
+  for (l = __exit_funcs; l != NULL; l = l->next)
+    {
+      register size_t i = l->idx;
+      while (i-- > 0)
+	{
+	  CONST struct exit_function *CONST f = &l->fns[i];
+	  switch (f->flavor)
+	    {
+	    case ef_free:
+	      break;
+	    case ef_on:
+	      (*f->func.on.fn)(status, f->func.on.arg);
+	      break;
+	    case ef_at:
+	      (*f->func.at)();
+	      break;
+	    }
+	}
+    }
+
+#ifdef	HAVE_GNU_LD
+  RUN_HOOK (__libc_atexit, ());
+#else
+  {
+    extern void EXFUN(_cleanup, (NOARGS));
+    _cleanup();
+  }
+#endif
+
+  _exit(status);
+}
+
diff --git a/stdlib/exit.h b/stdlib/exit.h
new file mode 100644
index 0000000000..214217853e
--- /dev/null
+++ b/stdlib/exit.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991 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	_EXIT_H
+
+struct exit_function
+  {
+    enum { ef_free, ef_on, ef_at } flavor;	/* `ef_free' MUST be zero!  */
+    union
+      {
+	void EXFUN((*at), (NOARGS));
+	struct
+	  {
+	    void EXFUN((*fn), (int status, PTR arg));
+	    PTR arg;
+	  } on;
+      } func;
+  };
+struct exit_function_list
+  {
+    struct exit_function_list *next;
+    size_t idx;
+    struct exit_function fns[32];
+  };
+extern struct exit_function_list *__exit_funcs;
+
+extern struct exit_function *EXFUN(__new_exitfn, (NOARGS));
+
+#endif	/* exit.h  */
diff --git a/stdlib/labs.c b/stdlib/labs.c
new file mode 100644
index 0000000000..c54339f02b
--- /dev/null
+++ b/stdlib/labs.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <stdlib.h>
+
+#undef	labs
+
+
+/* Return the absolute value of I.  */
+__CONSTVALUE
+long int
+DEFUN(labs, (i), long int i)
+{
+  return(i < 0 ? -i : i);
+}
diff --git a/stdlib/ldiv.c b/stdlib/ldiv.c
new file mode 100644
index 0000000000..661f1bdbcd
--- /dev/null
+++ b/stdlib/ldiv.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 1992 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.  */
+
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ansidecl.h>
+#include <stdlib.h>
+
+
+/* Return the `ldiv_t' representation of NUMER over DENOM.  */
+__CONSTVALUE
+ldiv_t
+DEFUN(ldiv, (numer, denom), long int numer AND long int denom)
+{
+  ldiv_t result;
+
+  result.quot = numer / denom;
+  result.rem = numer % denom;
+
+  /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where
+     NUMER / DENOM is to be computed in infinite precision.  In
+     other words, we should always truncate the quotient towards
+     zero, never -infinity.  Machine division and remainer may
+     work either way when one or both of NUMER or DENOM is
+     negative.  If only one is negative and QUOT has been
+     truncated towards -infinity, REM will have the same sign as
+     DENOM and the opposite sign of NUMER; if both are negative
+     and QUOT has been truncated towards -infinity, REM will be
+     positive (will have the opposite sign of NUMER).  These are
+     considered `wrong'.  If both are NUM and DENOM are positive,
+     RESULT will always be positive.  This all boils down to: if
+     NUMER >= 0, but REM < 0, we got the wrong answer.  In that
+     case, to get the right answer, add 1 to QUOT and subtract
+     DENOM from REM.  */
+
+  if (numer >= 0 && result.rem < 0)
+    {
+      ++result.quot;
+      result.rem -= denom;
+    }
+
+  return result;
+}
diff --git a/stdlib/mblen.c b/stdlib/mblen.c
new file mode 100644
index 0000000000..5393ce433c
--- /dev/null
+++ b/stdlib/mblen.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <stdlib.h>
+
+#undef	mblen
+
+
+/* Return the length of the multibyte character (if there is one)
+   at S which is no longer than N characters.  */
+int
+DEFUN(mblen, (s, n), CONST char *s AND size_t n)
+{
+  return(mbtowc((wchar_t *) NULL, s, n));
+}
diff --git a/stdlib/mbstowcs.c b/stdlib/mbstowcs.c
new file mode 100644
index 0000000000..38c710279a
--- /dev/null
+++ b/stdlib/mbstowcs.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 1991, 1992 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 <ansidecl.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+
+extern int _mb_shift;	/* Defined in mbtowc.c.  */
+
+/* Convert the string of multibyte characters in S to `wchar_t's in
+   PWCS, writing no more than N.  Return the number written,
+   or (size_t) -1 if an invalid multibyte character is encountered.  */
+size_t
+DEFUN(mbstowcs, (pwcs, s, n),
+      register wchar_t *pwcs AND register CONST char *s AND register size_t n)
+{
+  int save_shift;
+  register size_t written = 0;
+
+  /* Save the shift state.  */
+  save_shift = _mb_shift;
+  /* Reset the shift state.  */
+  _mb_shift = 0;
+
+  while (*s != '\0')
+    {
+      int len;
+      if (isascii (*s))
+	{
+	  *pwcs = (wchar_t) *s;
+	  len = 1;
+	}
+      else
+	len = mbtowc (pwcs, s, n);
+
+      if (len < 1)
+	{
+	  /* Return an error.  */
+	  written = (size_t) -1;
+	  break;
+	}
+      else
+	{
+	  /* Multibyte character converted.  */
+	  ++pwcs;
+	  ++written;
+	  s += len;
+	  n -= len;
+	}
+    }
+
+  /* Terminate the string if it has space.  */
+  if (n > 0)
+    *pwcs = (wchar_t) 0;
+
+  /* Restore the old shift state.  */
+  _mb_shift = save_shift;
+
+  /* Return how many we wrote (or maybe an error).  */
+  return written;
+}
diff --git a/stdlib/mbtowc.c b/stdlib/mbtowc.c
new file mode 100644
index 0000000000..62103407c0
--- /dev/null
+++ b/stdlib/mbtowc.c
@@ -0,0 +1,84 @@
+/* Copyright (C) 1991, 1992, 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 <ansidecl.h>
+#include <localeinfo.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+long int _mb_shift = 0;
+
+/* Convert the multibyte character at S, which is no longer
+   than N characters, to its `wchar_t' representation, placing
+   this n *PWC and returning its length.  */
+int
+DEFUN(mbtowc, (pwc, s, n), wchar_t *pwc AND CONST char *s AND size_t n)
+{
+  register CONST mb_char *mb;
+  register wchar_t i;
+
+  if (s == NULL)
+    return _mb_shift != 0;
+
+  if (*s == '\0')
+    /* ANSI 4.10.7.2, line 19.  */
+    return 0;
+
+  if (isascii (*s))
+    {
+      /* A normal ASCII character translates to itself.  */
+      if (pwc != NULL)
+	*pwc = (wchar_t) *s;
+      return 1;
+    }
+
+  if (_ctype_info->mbchar == NULL ||
+      _ctype_info->mbchar->mb_chars == NULL)
+    return -1;
+
+  if (n > MB_CUR_MAX)
+    n = MB_CUR_MAX;
+
+  for (i = 0; i < WCHAR_MAX; ++i)
+    {
+      mb = &_ctype_info->mbchar->mb_chars[i];
+      /* EOF and NUL aren't MB chars.  */
+      if (i == (wchar_t) EOF || i == (wchar_t) '\0')
+	continue;
+      /* Normal ASCII values can't start MB chars.  */
+      else if (isascii(i))
+	continue;
+      else if (mb->string == NULL || mb->len == 0)
+	continue;
+      else if (mb->len > n)
+	continue;
+      else if (!strncmp(mb->string, s, mb->len))
+	{
+	  _mb_shift += mb->shift;
+	  if (pwc != NULL)
+	    *pwc = i;
+	  return mb->len;
+	}
+    }
+
+  return -1;
+}
diff --git a/stdlib/msort.c b/stdlib/msort.c
new file mode 100644
index 0000000000..92ba5182ed
--- /dev/null
+++ b/stdlib/msort.c
@@ -0,0 +1,103 @@
+/* msort -- an alternative to qsort, with an identical interface.
+   Copyright (C) 1992 Free Software Foundation, Inc.
+   Written by Mike Haertel, September 1988.
+
+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 <ansidecl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MEMCPY(dst, src, s)			\
+  ((s) == sizeof (int)				\
+   ? (*(int *) (dst) = *(int *) (src), (dst))	\
+   : memcpy (dst, src, s))
+
+static void
+DEFUN(msort_with_tmp, (b, n, s, cmp, t),
+      PTR b AND size_t n AND size_t s AND __compar_fn_t cmp AND char *t)
+{
+  char *tmp;
+  char *b1, *b2;
+  size_t n1, n2;
+
+  if (n <= 1)
+    return;
+
+  n1 = n / 2;
+  n2 = n - n1;
+  b1 = b;
+  b2 = (char *) b + (n1 * s);
+
+  msort_with_tmp (b1, n1, s, cmp, t);
+  msort_with_tmp (b2, n2, s, cmp, t);
+
+  tmp = t;
+
+  while (n1 > 0 && n2 > 0)
+    {
+      if ((*cmp) (b1, b2) <= 0)
+	{
+	  MEMCPY (tmp, b1, s);
+	  b1 += s;
+	  --n1;
+	}
+      else
+	{
+	  MEMCPY (tmp, b2, s);
+	  b2 += s;
+	  --n2;
+	}
+      tmp += s;
+    }
+  if (n1 > 0)
+    memcpy (tmp, b1, n1 * s);
+  memcpy (b, t, (n - n2) * s);
+}
+
+void
+DEFUN(qsort, (b, n, s, cmp),
+      PTR b AND size_t n AND size_t s AND __compar_fn_t cmp)
+{
+  CONST size_t size = n * s;
+
+  if (size < 1024)
+    /* The temporary array is small, so put it on the stack.  */
+    msort_with_tmp (b, n, s, cmp, __alloca (size));
+  else
+    {
+      /* It's somewhat large, so malloc it.  */
+      int save = errno;
+      char *tmp = malloc (size);
+      if (tmp == NULL)
+	{
+	  /* Couldn't get space, so use the slower algorithm
+	     that doesn't need a temporary array.  */
+	  extern void EXFUN(_quicksort, (PTR __base,
+					 size_t __nmemb, size_t __size,
+					 __compar_fn_t __compar));
+	  _quicksort (b, n, s, cmp);
+	}
+      else
+	{
+	  msort_with_tmp (b, n, s, cmp, tmp);
+	  free (tmp);
+	}
+      errno = save;
+    }
+}
diff --git a/stdlib/on_exit.c b/stdlib/on_exit.c
new file mode 100644
index 0000000000..bd100be895
--- /dev/null
+++ b/stdlib/on_exit.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <stdlib.h>
+#include "exit.h"
+
+/* Register a function to be called by exit.  */
+int
+DEFUN(on_exit, (func, arg),
+      void EXFUN((*func), (int status, PTR arg)) AND PTR arg)
+{
+  struct exit_function *new = __new_exitfn();
+
+  if (new == NULL)
+    return -1;
+
+  new->flavor = ef_on;
+  new->func.on.fn = func;
+  new->func.on.arg = arg;
+  return 0;
+}
diff --git a/stdlib/qsort.c b/stdlib/qsort.c
new file mode 100644
index 0000000000..bc8d171b79
--- /dev/null
+++ b/stdlib/qsort.c
@@ -0,0 +1,243 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
+
+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 <ansidecl.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Byte-wise swap two items of size SIZE. */
+#define SWAP(a, b, size)						      \
+  do									      \
+    {									      \
+      register size_t __size = (size);					      \
+      register char *__a = (a), *__b = (b);				      \
+      do								      \
+	{								      \
+	  char __tmp = *__a;						      \
+	  *__a++ = *__b;						      \
+	  *__b++ = __tmp;						      \
+	} while (--__size > 0);						      \
+    } while (0)
+
+/* Discontinue quicksort algorithm when partition gets below this size.
+   This particular magic number was chosen to work best on a Sun 4/260. */
+#define MAX_THRESH 4
+
+/* Stack node declarations used to store unfulfilled partition obligations. */
+typedef struct 
+  {
+    char *lo;
+    char *hi;
+  } stack_node;
+
+/* The next 4 #defines implement a very fast in-line stack abstraction. */
+#define STACK_SIZE	(8 * sizeof(unsigned long int))
+#define PUSH(low, high)	((void) ((top->lo = (low)), (top->hi = (high)), ++top))
+#define	POP(low, high)	((void) (--top, (low = top->lo), (high = top->hi)))
+#define	STACK_NOT_EMPTY	(stack < top)                
+
+
+/* Order size using quicksort.  This implementation incorporates
+   four optimizations discussed in Sedgewick:
+
+   1. Non-recursive, using an explicit stack of pointer that store the 
+      next array partition to sort.  To save time, this maximum amount 
+      of space required to store an array of MAX_INT is allocated on the 
+      stack.  Assuming a 32-bit integer, this needs only 32 * 
+      sizeof(stack_node) == 136 bits.  Pretty cheap, actually.
+
+   2. Chose the pivot element using a median-of-three decision tree.
+      This reduces the probability of selecting a bad pivot value and 
+      eliminates certain extraneous comparisons.
+
+   3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
+      insertion sort to order the MAX_THRESH items within each partition.  
+      This is a big win, since insertion sort is faster for small, mostly
+      sorted array segements.
+
+   4. The larger of the two sub-partitions is always pushed onto the
+      stack first, with the algorithm then concentrating on the
+      smaller partition.  This *guarantees* no more than log (n)
+      stack size is needed (actually O(1) in this case)!  */
+
+void
+DEFUN(_quicksort, (pbase, total_elems, size, cmp),
+      PTR CONST pbase AND size_t total_elems AND size_t size AND
+      int EXFUN((*cmp), (CONST PTR, CONST PTR)))
+{
+  register char *base_ptr = (char *) pbase;
+
+  /* Allocating SIZE bytes for a pivot buffer facilitates a better
+     algorithm below since we can do comparisons directly on the pivot. */
+  char *pivot_buffer = (char *) __alloca (size);
+  CONST size_t max_thresh = MAX_THRESH * size;
+
+  if (total_elems == 0)
+    /* Avoid lossage with unsigned arithmetic below.  */
+    return;
+
+  if (total_elems > MAX_THRESH)
+    {
+      char *lo = base_ptr;
+      char *hi = &lo[size * (total_elems - 1)];
+      /* Largest size needed for 32-bit int!!! */
+      stack_node stack[STACK_SIZE];
+      stack_node *top = stack + 1;
+
+      while (STACK_NOT_EMPTY)
+        {
+          char *left_ptr;
+          char *right_ptr;
+
+	  char *pivot = pivot_buffer;
+
+	  /* Select median value from among LO, MID, and HI. Rearrange
+	     LO and HI so the three values are sorted. This lowers the 
+	     probability of picking a pathological pivot value and 
+	     skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
+
+	  char *mid = lo + size * ((hi - lo) / size >> 1);
+
+	  if ((*cmp)((PTR) mid, (PTR) lo) < 0)
+	    SWAP(mid, lo, size);
+	  if ((*cmp)((PTR) hi, (PTR) mid) < 0)
+	    SWAP(mid, hi, size);
+	  else 
+	    goto jump_over;
+	  if ((*cmp)((PTR) mid, (PTR) lo) < 0)
+	    SWAP(mid, lo, size);
+	jump_over:;
+	  memcpy(pivot, mid, size);
+	  pivot = pivot_buffer;
+
+	  left_ptr  = lo + size;
+	  right_ptr = hi - size; 
+
+	  /* Here's the famous ``collapse the walls'' section of quicksort.  
+	     Gotta like those tight inner loops!  They are the main reason 
+	     that this algorithm runs much faster than others. */
+	  do 
+	    {
+	      while ((*cmp)((PTR) left_ptr, (PTR) pivot) < 0)
+		left_ptr += size;
+
+	      while ((*cmp)((PTR) pivot, (PTR) right_ptr) < 0)
+		right_ptr -= size;
+
+	      if (left_ptr < right_ptr) 
+		{
+		  SWAP(left_ptr, right_ptr, size);
+		  left_ptr += size;
+		  right_ptr -= size;
+		}
+	      else if (left_ptr == right_ptr) 
+		{
+		  left_ptr += size;
+		  right_ptr -= size;
+		  break;
+		}
+	    } 
+	  while (left_ptr <= right_ptr);
+
+          /* Set up pointers for next iteration.  First determine whether
+             left and right partitions are below the threshold size.  If so, 
+             ignore one or both.  Otherwise, push the larger partition's
+             bounds on the stack and continue sorting the smaller one. */
+
+          if ((size_t) (right_ptr - lo) <= max_thresh)
+            {
+              if ((size_t) (hi - left_ptr) <= max_thresh)
+		/* Ignore both small partitions. */
+                POP(lo, hi); 
+              else
+		/* Ignore small left partition. */  
+                lo = left_ptr;
+            }
+          else if ((size_t) (hi - left_ptr) <= max_thresh)
+	    /* Ignore small right partition. */
+            hi = right_ptr;
+          else if ((right_ptr - lo) > (hi - left_ptr))
+            {                   
+	      /* Push larger left partition indices. */
+              PUSH(lo, right_ptr);
+              lo = left_ptr;
+            }
+          else
+            {                   
+	      /* Push larger right partition indices. */
+              PUSH(left_ptr, hi);
+              hi = right_ptr;
+            }
+        }
+    }
+
+  /* Once the BASE_PTR array is partially sorted by quicksort the rest
+     is completely sorted using insertion sort, since this is efficient 
+     for partitions below MAX_THRESH size. BASE_PTR points to the beginning 
+     of the array to sort, and END_PTR points at the very last element in
+     the array (*not* one beyond it!). */
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+
+  {
+    char *CONST end_ptr = &base_ptr[size * (total_elems - 1)];
+    char *tmp_ptr = base_ptr;
+    char *thresh = min(end_ptr, base_ptr + max_thresh);
+    register char *run_ptr;
+
+    /* Find smallest element in first threshold and place it at the
+       array's beginning.  This is the smallest array element,
+       and the operation speeds up insertion sort's inner loop. */
+
+    for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
+      if ((*cmp)((PTR) run_ptr, (PTR) tmp_ptr) < 0)
+        tmp_ptr = run_ptr;
+
+    if (tmp_ptr != base_ptr)
+      SWAP(tmp_ptr, base_ptr, size);
+
+    /* Insertion sort, running from left-hand-side up to right-hand-side.  */
+
+    run_ptr = base_ptr + size;
+    while ((run_ptr += size) <= end_ptr)
+      {
+	tmp_ptr = run_ptr - size;
+	while ((*cmp)((PTR) run_ptr, (PTR) tmp_ptr) < 0)
+	  tmp_ptr -= size;
+
+	tmp_ptr += size;
+        if (tmp_ptr != run_ptr)
+          {
+            char *trav;
+
+	    trav = run_ptr + size;
+	    while (--trav >= run_ptr)
+              {
+                char c = *trav;
+                char *hi, *lo;
+
+                for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)
+                  *hi = *lo;
+                *hi = c;
+              }
+          }
+      }
+  }
+}
+
diff --git a/stdlib/rand.c b/stdlib/rand.c
new file mode 100644
index 0000000000..1353432850
--- /dev/null
+++ b/stdlib/rand.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <stdlib.h>
+
+#undef	rand
+
+
+/* Return a random integer between 0 and RAND_MAX.  */
+int
+DEFUN_VOID(rand)
+{
+  return (int) __random();
+}
diff --git a/stdlib/random.c b/stdlib/random.c
new file mode 100644
index 0000000000..fb32b36b87
--- /dev/null
+++ b/stdlib/random.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This is derived from the Berkeley source:
+ *	@(#)random.c	5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+
+/* An improved random number generation package.  In addition to the standard
+   rand()/srand() like interface, this package also has a special state info
+   interface.  The initstate() routine is called with a seed, an array of
+   bytes, and a count of how many bytes are being passed in; this array is
+   then initialized to contain information for random number generation with
+   that much state information.  Good sizes for the amount of state
+   information are 32, 64, 128, and 256 bytes.  The state can be switched by
+   calling the setstate() function with the same array as was initiallized
+   with initstate().  By default, the package runs with 128 bytes of state
+   information and generates far better random numbers than a linear
+   congruential generator.  If the amount of state information is less than
+   32 bytes, a simple linear congruential R.N.G. is used.  Internally, the
+   state information is treated as an array of longs; the zeroeth element of
+   the array is the type of R.N.G. being used (small integer); the remainder
+   of the array is the state information for the R.N.G.  Thus, 32 bytes of
+   state information will give 7 longs worth of state information, which will
+   allow a degree seven polynomial.  (Note: The zeroeth word of state
+   information also has some other information stored in it; see setstate
+   for details).  The random number generation technique is a linear feedback
+   shift register approach, employing trinomials (since there are fewer terms
+   to sum up that way).  In this approach, the least significant bit of all
+   the numbers in the state table will act as a linear feedback shift register,
+   and will have period 2^deg - 1 (where deg is the degree of the polynomial
+   being used, assuming that the polynomial is irreducible and primitive).
+   The higher order bits will have longer periods, since their values are
+   also influenced by pseudo-random carries out of the lower bits.  The
+   total period of the generator is approximately deg*(2**deg - 1); thus
+   doubling the amount of state information has a vast influence on the
+   period of the generator.  Note: The deg*(2**deg - 1) is an approximation
+   only good for large deg, when the period of the shift register is the
+   dominant factor.  With deg equal to seven, the period is actually much
+   longer than the 7*(2**7 - 1) predicted by this formula.  */
+
+
+
+/* For each of the currently supported random number generators, we have a
+   break value on the amount of state information (you need at least thi
+   bytes of state info to support this random number generator), a degree for
+   the polynomial (actually a trinomial) that the R.N.G. is based on, and
+   separation between the two lower order coefficients of the trinomial.  */
+
+/* Linear congruential.  */
+#define	TYPE_0		0
+#define	BREAK_0		8
+#define	DEG_0		0
+#define	SEP_0		0
+
+/* x**7 + x**3 + 1.  */
+#define	TYPE_1		1
+#define	BREAK_1		32
+#define	DEG_1		7
+#define	SEP_1		3
+
+/* x**15 + x + 1.  */
+#define	TYPE_2		2
+#define	BREAK_2		64
+#define	DEG_2		15
+#define	SEP_2		1
+
+/* x**31 + x**3 + 1.  */
+#define	TYPE_3		3
+#define	BREAK_3		128
+#define	DEG_3		31
+#define	SEP_3		3
+
+/* x**63 + x + 1.  */
+#define	TYPE_4		4
+#define	BREAK_4		256
+#define	DEG_4		63
+#define	SEP_4		1
+
+
+/* Array versions of the above information to make code run faster.
+   Relies on fact that TYPE_i == i.  */
+
+#define	MAX_TYPES	5	/* Max number of types above.  */
+
+static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
+static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
+
+
+
+/* Initially, everything is set up as if from:
+	initstate(1, randtbl, 128);
+   Note that this initialization takes advantage of the fact that srandom
+   advances the front and rear pointers 10*rand_deg times, and hence the
+   rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+   element of the state information, which contains info about the current
+   position of the rear pointer is just
+	(MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3.  */
+
+static long int randtbl[DEG_3 + 1] =
+  {
+    TYPE_3,
+    -851904987, -43806228, -2029755270, 1390239686, -1912102820,
+    -485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
+    -1714531963, 1800685987, -2015299881, 654595283, -1149023258,
+    -1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
+    -607508183, -205999574, -1696891592, 1492211999, -1528267240,
+    -952028296, -189082757, 362343714, 1424981831, 2039449641,
+  };
+
+/* FPTR and RPTR are two pointers into the state info, a front and a rear
+   pointer.  These two pointers are always rand_sep places aparts, as they
+   cycle through the state information.  (Yes, this does mean we could get
+   away with just one pointer, but the code for random is more efficient
+   this way).  The pointers are left positioned as they would be from the call:
+	initstate(1, randtbl, 128);
+   (The position of the rear pointer, rptr, is really 0 (as explained above
+   in the initialization of randtbl) because the state table pointer is set
+   to point to randtbl[1] (as explained below).)  */
+
+static long int *fptr = &randtbl[SEP_3 + 1];
+static long int *rptr = &randtbl[1];
+
+
+
+/* The following things are the pointer to the state information table,
+   the type of the current generator, the degree of the current polynomial
+   being used, and the separation between the two pointers.
+   Note that for efficiency of random, we remember the first location of
+   the state information, not the zeroeth.  Hence it is valid to access
+   state[-1], which is used to store the type of the R.N.G.
+   Also, we remember the last location, since this is more efficient than
+   indexing every time to find the address of the last element to see if
+   the front and rear pointers have wrapped.  */
+
+static long int *state = &randtbl[1];
+
+static int rand_type = TYPE_3;
+static int rand_deg = DEG_3;
+static int rand_sep = SEP_3;
+
+static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
+
+/* Initialize the random number generator based on the given seed.  If the
+   type is the trivial no-state-information type, just remember the seed.
+   Otherwise, initializes state[] based on the given "seed" via a linear
+   congruential generator.  Then, the pointers are set to known locations
+   that are exactly rand_sep places apart.  Lastly, it cycles the state
+   information a given number of times to get rid of any initial dependencies
+   introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
+   for default usage relies on values produced by this routine.  */
+void
+DEFUN(__srandom, (x), unsigned int x)
+{
+  state[0] = x;
+  if (rand_type != TYPE_0)
+    {
+      register long int i;
+      for (i = 1; i < rand_deg; ++i)
+	state[i] = (1103515145 * state[i - 1]) + 12345;
+      fptr = &state[rand_sep];
+      rptr = &state[0];
+      for (i = 0; i < 10 * rand_deg; ++i)
+	(void) __random();
+    }
+}
+
+weak_alias (__srandom, srandom)
+weak_alias (__srandom, srand)
+
+/* Initialize the state information in the given array of N bytes for
+   future random number generation.  Based on the number of bytes we
+   are given, and the break values for the different R.N.G.'s, we choose
+   the best (largest) one we can and set things up for it.  srandom is
+   then called to initialize the state information.  Note that on return
+   from srandom, we set state[-1] to be the type multiplexed with the current
+   value of the rear pointer; this is so successive calls to initstate won't
+   lose this information and will be able to restart with setstate.
+   Note: The first thing we do is save the current state, if any, just like
+   setstate so that it doesn't matter when initstate is called.
+   Returns a pointer to the old state.  */
+PTR
+DEFUN(__initstate, (seed, arg_state, n),
+      unsigned int seed AND PTR arg_state AND size_t n)
+{
+  PTR ostate = (PTR) &state[-1];
+
+  if (rand_type == TYPE_0)
+    state[-1] = rand_type;
+  else
+    state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+  if (n < BREAK_1)
+    {
+      if (n < BREAK_0)
+	{
+	  errno = EINVAL;
+	  return NULL;
+	}
+      rand_type = TYPE_0;
+      rand_deg = DEG_0;
+      rand_sep = SEP_0;
+    }
+  else if (n < BREAK_2)
+    {
+      rand_type = TYPE_1;
+      rand_deg = DEG_1;
+      rand_sep = SEP_1;
+    }
+  else if (n < BREAK_3)
+    {
+      rand_type = TYPE_2;
+      rand_deg = DEG_2;
+      rand_sep = SEP_2;
+    }
+  else if (n < BREAK_4)
+    {
+      rand_type = TYPE_3;
+      rand_deg = DEG_3;
+      rand_sep = SEP_3;
+    }
+  else
+    {
+      rand_type = TYPE_4;
+      rand_deg = DEG_4;
+      rand_sep = SEP_4;
+    }
+
+  state = &((long int *) arg_state)[1];	/* First location.  */
+  /* Must set END_PTR before srandom.  */
+  end_ptr = &state[rand_deg];
+  __srandom(seed);
+  if (rand_type == TYPE_0)
+    state[-1] = rand_type;
+  else
+    state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+
+  return ostate;
+}
+
+weak_alias (__initstate, initstate)
+
+/* Restore the state from the given state array.
+   Note: It is important that we also remember the locations of the pointers
+   in the current state information, and restore the locations of the pointers
+   from the old state information.  This is done by multiplexing the pointer
+   location into the zeroeth word of the state information. Note that due
+   to the order in which things are done, it is OK to call setstate with the
+   same state as the current state
+   Returns a pointer to the old state information.  */
+PTR
+DEFUN(__setstate, (arg_state), PTR arg_state)
+{
+  register long int *new_state = (long int *) arg_state;
+  register int type = new_state[0] % MAX_TYPES;
+  register int rear = new_state[0] / MAX_TYPES;
+  PTR ostate = (PTR) &state[-1];
+
+  if (rand_type == TYPE_0)
+    state[-1] = rand_type;
+  else
+    state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+
+  switch (type)
+    {
+    case TYPE_0:
+    case TYPE_1:
+    case TYPE_2:
+    case TYPE_3:
+    case TYPE_4:
+      rand_type = type;
+      rand_deg = degrees[type];
+      rand_sep = seps[type];
+      break;
+    default:
+      /* State info munged.  */
+      errno = EINVAL;
+      return NULL;
+    }
+
+  state = &new_state[1];
+  if (rand_type != TYPE_0)
+    {
+      rptr = &state[rear];
+      fptr = &state[(rear + rand_sep) % rand_deg];
+    }
+  /* Set end_ptr too.  */
+  end_ptr = &state[rand_deg];
+
+  return ostate;
+}
+
+weak_alias (__setstate, setstate)
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+   congruential bit.  Otherwise, we do our fancy trinomial stuff, which is the
+   same in all ther other cases due to all the global variables that have been
+   set up.  The basic operation is to add the number at the rear pointer into
+   the one at the front pointer.  Then both pointers are advanced to the next
+   location cyclically in the table.  The value returned is the sum generated,
+   reduced to 31 bits by throwing away the "least random" low bit.
+   Note: The code takes advantage of the fact that both the front and
+   rear pointers can't wrap on the same call by not testing the rear
+   pointer if the front one has wrapped.  Returns a 31-bit random number.  */
+
+long int
+DEFUN_VOID(__random)
+{
+  if (rand_type == TYPE_0)
+    {
+      state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
+      return state[0];
+    }
+  else
+    {
+      long int i;
+      *fptr += *rptr;
+      /* Chucking least random bit.  */
+      i = (*fptr >> 1) & LONG_MAX;
+      ++fptr;
+      if (fptr >= end_ptr)
+	{
+	  fptr = state;
+	  ++rptr;
+	}
+      else
+	{
+	  ++rptr;
+	  if (rptr >= end_ptr)
+	    rptr = state;
+	}
+      return i;
+    }
+}
+
+weak_alias (__random, random)
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
new file mode 100644
index 0000000000..d64a2ffb7c
--- /dev/null
+++ b/stdlib/stdlib.h
@@ -0,0 +1,289 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 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.  */
+
+/*
+ *	ANSI Standard: 4.10 GENERAL UTILITIES	<stdlib.h>
+ */
+
+#ifndef	_STDLIB_H
+
+#define	_STDLIB_H	1
+#include <features.h>
+
+/* Get size_t, wchar_t and NULL from <stddef.h>.  */
+#define	__need_size_t
+#define	__need_wchar_t
+#define	__need_NULL
+#include <stddef.h>
+
+#define	__need_Emath
+#include <errno.h>
+
+__BEGIN_DECLS
+
+/* Returned by `div'.  */
+typedef struct
+  {
+    int quot;			/* Quotient.  */
+    int rem;			/* Remainder.  */
+  } div_t;
+
+/* Returned by `ldiv'.  */
+typedef struct
+  {
+    long int quot;		/* Quotient.  */
+    long int rem;		/* Remainder.  */
+  } ldiv_t;
+
+
+/* The largest number rand will return (same as INT_MAX).  */
+#define	RAND_MAX	2147483647
+
+
+/* We define these the same for all machines.
+   Changes from this to the outside world should be done in `_exit'.  */
+#define	EXIT_FAILURE	1	/* Failing exit status.  */
+#define	EXIT_SUCCESS	0	/* Successful exit status.  */
+
+
+/* Maximum length of a multibyte character in the current locale.
+   This is just one until the fancy locale support is finished.  */
+#define	MB_CUR_MAX	1
+
+
+/* Convert a string to a floating-point number.  */
+extern double atof __P ((__const char *__nptr));
+/* Convert a string to an integer.  */
+extern int atoi __P ((__const char *__nptr));
+/* Convert a string to a long integer.  */
+extern long int atol __P ((__const char *__nptr));
+
+/* Convert a string to a floating-point number.  */
+extern double strtod __P ((__const char *__nptr, char **__endptr));
+
+#ifdef	__USE_GNU
+/* Likewise for `float' and `long double' sizes of floating-point numbers.  */
+extern float __strtof __P ((__const char *__nptr, char **__endptr));
+extern float strtof __P ((__const char *__nptr, char **__endptr));
+extern __long_double_t __strtold __P ((__const char *__nptr, char **__endptr));
+extern __long_double_t strtold __P ((__const char *__nptr, char **__endptr));
+#endif
+
+/* Convert a string to a long integer.  */
+extern long int strtol __P ((__const char *__nptr, char **__endptr,
+			     int __base));
+/* Convert a string to an unsigned long integer.  */
+extern unsigned long int strtoul __P ((__const char *__nptr,
+				       char **__endptr, int __base));
+
+#if defined (__GNUC__) && defined (__USE_BSD)
+/* Convert a string to a quadword integer.  */
+extern long long int strtoq __P ((__const char *__nptr, char **__endptr,
+				  int __base));
+/* Convert a string to an unsigned quadword integer.  */
+extern unsigned long long int strtouq __P ((__const char *__nptr,
+					    char **__endptr, int __base));
+#endif /* GCC and use BSD.  */
+
+#if defined (__OPTIMIZE__) && __GNUC__ >= 2
+extern __inline double atof (__const char *__nptr)
+{ return strtod(__nptr, (char **) NULL); }
+extern __inline int atoi (__const char *__nptr)
+{ return (int) strtol (__nptr, (char **) NULL, 10); }
+extern __inline long int atol (__const char *__nptr)
+{ return strtol (__nptr, (char **) NULL, 10); }
+#endif /* Optimizing GCC >=2.  */
+
+
+/* Return a random integer between 0 and RAND_MAX inclusive.  */
+extern int rand __P ((void));
+/* Seed the random number generator with the given number.  */
+extern void srand __P ((unsigned int __seed));
+
+/* These are the functions that actually do things.  The `random', `srandom',
+   `initstate' and `setstate' functions are those from BSD Unices.
+   The `rand' and `srand' functions are required by the ANSI standard.
+   We provide both interfaces to the same random number generator.  */
+/* Return a random long integer between 0 and RAND_MAX inclusive.  */
+extern long int __random __P ((void));
+/* Seed the random number generator with the given number.  */
+extern void __srandom __P ((unsigned int __seed));
+
+/* Initialize the random number generator to use state buffer STATEBUF,
+   of length STATELEN, and seed it with SEED.  Optimal lengths are 8, 16,
+   32, 64, 128 and 256, the bigger the better; values less than 8 will
+   cause an error and values greater than 256 will be rounded down.  */
+extern __ptr_t __initstate __P ((unsigned int __seed, __ptr_t __statebuf,
+				 size_t __statelen));
+/* Switch the random number generator to state buffer STATEBUF,
+   which should have been previously initialized by `initstate'.  */
+extern __ptr_t __setstate __P ((__ptr_t __statebuf));
+
+#ifdef	__USE_BSD
+extern long int random __P ((void));
+extern void srandom __P ((unsigned int __seed));
+extern __ptr_t initstate __P ((unsigned int __seed, __ptr_t __statebuf,
+			       size_t __statelen));
+extern __ptr_t setstate __P ((__ptr_t __statebuf));
+
+#if defined (__OPTIMIZE__) && __GNUC__ >= 2
+extern __inline long int random (void)
+{ return __random(); }
+extern __inline void srandom (unsigned int __seed)
+{ __srandom(__seed); }
+extern __inline __ptr_t initstate (unsigned int __seed,
+				   __ptr_t __statebuf, size_t __statelen)
+{ return __initstate (__seed, __statebuf, __statelen); }
+extern __inline __ptr_t setstate (__ptr_t __statebuf)
+{ return __setstate (__statebuf); }
+#endif /* Optimizing GCC >=2.  */
+#endif /* Use BSD.  */
+
+
+/* Allocate SIZE bytes of memory.  */
+extern __ptr_t malloc __P ((size_t __size));
+/* Re-allocate the previously allocated block
+   in __ptr_t, making the new block SIZE bytes long.  */
+extern __ptr_t realloc __P ((__ptr_t __ptr, size_t __size));
+/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0.  */
+extern __ptr_t calloc __P ((size_t __nmemb, size_t __size));
+/* Free a block allocated by `malloc', `realloc' or `calloc'.  */
+extern void free __P ((__ptr_t __ptr));
+
+#ifdef	__USE_MISC
+/* Free a block.  An alias for `free'.	(Sun Unices).  */
+extern void cfree __P ((__ptr_t __ptr));
+#endif /* Use misc.  */
+
+#if defined(__USE_GNU) || defined(__USE_BSD) || defined(__USE_MISC)
+#include <alloca.h>
+#endif /* Use GNU, BSD, or misc.  */
+
+#ifdef	__USE_BSD
+/* Allocate SIZE bytes on a page boundary.  The storage cannot be freed.  */
+extern __ptr_t valloc __P ((size_t __size));
+#endif
+
+
+/* Abort execution and generate a core-dump.  */
+extern void abort __P ((void)) __attribute__ ((__noreturn__));
+
+
+/* Register a function to be called when `exit' is called.  */
+extern int atexit __P ((void (*__func) (void)));
+
+#ifdef	__USE_MISC
+/* Register a function to be called with the status
+   given to `exit' and the given argument.  */
+extern int on_exit __P ((void (*__func) (int __status, __ptr_t __arg),
+			 __ptr_t __arg));
+#endif
+
+/* Call all functions registered with `atexit' and `on_exit',
+   in the reverse of the order in which they were registered
+   perform stdio cleanup, and terminate program execution with STATUS.  */
+extern void exit __P ((int __status)) __attribute__ ((__noreturn__));
+
+
+/* Return the value of envariable NAME, or NULL if it doesn't exist.  */
+extern char *getenv __P ((__const char *__name));
+
+#ifdef	__USE_SVID
+/* The SVID says this is in <stdio.h>, but this seems a better place.	*/
+/* Put STRING, which is of the form "NAME=VALUE", in the environment.
+   If there is no `=', remove NAME from the environment.  */
+extern int putenv __P ((__const char *__string));
+#endif
+
+#ifdef	__USE_BSD
+/* Set NAME to VALUE in the environment.
+   If REPLACE is nonzero, overwrite an existing value.  */
+extern int setenv __P ((__const char *__name, __const char *__value,
+			int __replace));
+#endif
+
+/* Execute the given line as a shell command.  */
+extern int system __P ((__const char *__command));
+
+
+/* Shorthand for type of comparison functions.  */
+typedef int (*__compar_fn_t) __P ((__const __ptr_t, __const __ptr_t));
+
+#ifdef	__USE_GNU
+typedef __compar_fn_t comparison_fn_t;
+#endif
+
+/* Do a binary search for KEY in BASE, which consists of NMEMB elements
+   of SIZE bytes each, using COMPAR to perform the comparisons.  */
+extern __ptr_t bsearch __P ((__const __ptr_t __key, __const __ptr_t __base,
+			     size_t __nmemb, size_t __size,
+			     __compar_fn_t __compar));
+
+/* Sort NMEMB elements of BASE, of SIZE bytes each,
+   using COMPAR to perform the comparisons.  */
+extern void qsort __P ((__ptr_t __base, size_t __nmemb, size_t __size,
+			__compar_fn_t __compar));
+
+
+#ifndef	__CONSTVALUE
+#ifdef	__GNUC__
+/* The `const' keyword tells GCC that a function's return value is
+   based solely on its arguments, and there are no side-effects.  */
+#define	__CONSTVALUE	__const
+#else
+#define	__CONSTVALUE
+#endif /* GCC.  */
+#endif /* __CONSTVALUE not defined.  */
+
+/* Return the absolute value of X.  */
+extern __CONSTVALUE int abs __P ((int __x));
+extern __CONSTVALUE long int labs __P ((long int __x));
+
+
+/* Return the `div_t' or `ldiv_t' representation
+   of the value of NUMER over DENOM. */
+/* GCC may have built-ins for these someday.  */
+extern __CONSTVALUE div_t div __P ((int __numer, int __denom));
+extern __CONSTVALUE ldiv_t ldiv __P ((long int __numer, long int __denom));
+
+
+/* Return the length of the multibyte character
+   in S, which is no longer than N.  */
+extern int mblen __P ((__const char *__s, size_t __n));
+/* Return the length of the given multibyte character,
+   putting its `wchar_t' representation in *PWC.  */
+extern int mbtowc __P ((wchar_t * __pwc, __const char *__s, size_t __n));
+/* Put the multibyte character represented
+   by WCHAR in S, returning its length.  */
+extern int wctomb __P ((char *__s, wchar_t __wchar));
+
+#if defined (__OPTIMIZE__) && __GNUC__ >= 2
+extern __inline int mblen (__const char *__s, size_t __n)
+{ return mbtowc ((wchar_t *) NULL, __s, __n); }
+#endif /* Optimizing GCC >=2.  */
+
+
+/* Convert a multibyte string to a wide char string.  */
+extern size_t mbstowcs __P ((wchar_t * __pwcs, __const char *__s, size_t __n));
+/* Convert a wide char string to multibyte string.  */
+extern size_t wcstombs __P ((char *__s, __const wchar_t * __pwcs, size_t __n));
+
+
+__END_DECLS
+
+#endif /* stdlib.h  */
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
new file mode 100644
index 0000000000..d647753e79
--- /dev/null
+++ b/stdlib/strtod.c
@@ -0,0 +1,1027 @@
+/* Read decimal floating point numbers.
+Copyright (C) 1995 Free Software Foundation, Inc.
+Contributed by Ulrich Drepper.
+
+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.  */
+
+/* Configuration part.  These macros are defined by `strtold.c' and `strtof.c'
+   to produce the `long double' and `float' versions of the reader.  */
+#ifndef FLOAT
+#define	FLOAT		double
+#define	FLT		DBL
+#define	STRTOF		strtod
+#define	MPN2FLOAT	__mpn_construct_double
+#define	FLOAT_HUGE_VAL	HUGE_VAL
+#endif
+/* End of configuration part.  */
+
+#include <ctype.h>
+#include <errno.h>
+#include <float.h>
+#include <localeinfo.h>
+#include <math.h>
+#include <stdlib.h>
+#include "../stdio/gmp.h"
+#include "../stdio/gmp-impl.h"
+#include <gmp-mparam.h>
+#include "../stdio/longlong.h"
+#include "../stdio/fpioconst.h"
+
+/* #define NDEBUG 1 */
+#include <assert.h>
+
+
+/* Constants we need from float.h; select the set for the FLOAT precision.  */
+#define MANT_DIG	FLT##_MANT_DIG
+#define	MAX_EXP		FLT##_MAX_EXP
+#define	MIN_EXP		FLT##_MIN_EXP
+#define MAX_10_EXP	FLT##_MAX_10_EXP
+#define MIN_10_EXP	FLT##_MIN_10_EXP
+#define	MAX_10_EXP_LOG	FLT##_MAX_10_EXP_LOG
+
+
+/* Function to construct a floating point number from an MP integer
+   containing the fraction bits, a base 2 exponent, and a sign flag.  */
+extern FLOAT MPN2FLOAT (mp_srcptr mpn, int exponent, int negative);
+
+/* Definitions according to limb size used.  */
+#if	BITS_PER_MP_LIMB == 32
+#  define MAX_DIG_PER_LIMB	9
+#  define MAX_FAC_PER_LIMB	1000000000L
+#elif	BITS_PER_MP_LIMB == 64
+#  define MAX_DIG_PER_LIMB	19
+#  define MAX_FAC_PER_LIMB	10000000000000000000L
+#else
+#  error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"	
+#endif
+
+
+/* Local data structure.  */
+static const mp_limb _tens_in_limb[MAX_DIG_PER_LIMB] =
+{    0,                  10,                100,
+     1000,               10000,             100000,
+     1000000,            10000000,          100000000
+#if BITS_PER_MP_LIMB > 32
+   , 1000000000,         10000000000,       100000000000,
+     1000000000000,      10000000000000,    100000000000000,
+     1000000000000000,   10000000000000000, 100000000000000000,
+     1000000000000000000
+#endif
+#if BITS_PER_MP_LIMB > 64
+  #error "Need to expand tens_in_limb table to" MAX_DIG_PER_LIMB
+#endif
+};
+
+#ifndef	howmany
+#define	howmany(x,y)		(((x)+((y)-1))/(y))
+#endif
+#define SWAP(x, y)		({ typeof(x) _tmp = x; x = y; y = _tmp; })
+
+#define NDIG			(MAX_10_EXP - MIN_10_EXP + 2 * MANT_DIG)
+#define	RETURN_LIMB_SIZE		howmany (MANT_DIG, BITS_PER_MP_LIMB)
+
+#define RETURN(val,end) \
+	do { if (endptr != 0) *endptr = (char *) end; return val; } while (0)
+
+/* Maximum size necessary for mpn integers to hold floating point numbers.  */ 
+#define	MPNSIZE		(howmany (MAX_EXP + MANT_DIG, BITS_PER_MP_LIMB) + 1)
+/* Declare an mpn integer variable that big.  */
+#define	MPN_VAR(name)	mp_limb name[MPNSIZE]; mp_size_t name##size
+/* Copy an mpn integer value.  */
+#define MPN_ASSIGN(dst, src) \
+	memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb))
+
+
+/* Return a floating point number of the needed type according to the given
+   multi-precision number after possible rounding.  */
+static inline FLOAT
+round_and_return (mp_limb *retval, int exponent, int negative,
+		  mp_limb round_limb, mp_size_t round_bit, int more_bits)
+{
+  if (exponent < MIN_EXP)
+    {
+      mp_size_t shift = MIN_EXP - 1 - exponent;
+
+      if (shift >= MANT_DIG)
+	{
+	  errno = EDOM;
+	  return 0.0;
+	}
+
+      more_bits |= (round_limb & ((1 << round_bit) - 1)) != 0;
+      if (shift >= BITS_PER_MP_LIMB)
+	{
+	  round_limb = retval[(shift - 1) / BITS_PER_MP_LIMB];
+	  round_bit = (shift - 1) % BITS_PER_MP_LIMB;
+#if RETURN_LIMB_SIZE <= 2
+	  assert (RETURN_LIMB_SIZE == 2);
+	  more_bits |= retval[0] != 0;
+	  retval[0] = retval[1];
+	  retval[1] = 0;
+#else
+	  int disp = shift / BITS_PER_MP_LIMB;
+	  int i = 0;
+	  while (retval[i] == 0 && i < disp)
+	    ++i;
+	  more_bits |= i < disp;
+	  for (i = disp; i < RETURN_LIMB_SIZE; ++i)
+	    retval[i - disp] = retval[i];
+	  MPN_ZERO (&retval[RETURN_LIMB_SIZE - disp], disp);
+#endif
+	  shift %= BITS_PER_MP_LIMB;
+	}
+      else
+	{
+          round_limb = retval[0];
+          round_bit = shift - 1;
+	}
+      (void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, shift);
+      exponent = MIN_EXP - 2;
+    }
+
+  if ((round_limb & (1 << round_bit)) != 0 &&
+      (more_bits || (retval[0] & 1) != 0 ||
+       (round_limb & ((1 << round_bit) - 1)) != 0))
+    {
+      mp_limb cy = __mpn_add_1 (retval, retval, RETURN_LIMB_SIZE, 1);
+      if (cy || (retval[RETURN_LIMB_SIZE - 1]
+		 & (1 << (MANT_DIG % BITS_PER_MP_LIMB))) != 0)
+	{
+	  ++exponent;
+	  (void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, 1);
+	  retval[RETURN_LIMB_SIZE - 1] |= 1 << (MANT_DIG % BITS_PER_MP_LIMB);
+	}
+    }
+
+  if (exponent > MAX_EXP)
+    return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
+
+  return MPN2FLOAT (retval, exponent, negative);
+}
+
+
+/* Read a multi-precision integer starting at STR with exactly DIGCNT digits
+   into N.  Return the size of the number limbs in NSIZE at the first
+   character od the string that is not part of the integer as the function
+   value.  If the EXPONENT is small enough to be taken as an additional
+   factor for the resulting number (see code) multiply by it.  */
+static inline const char *
+str_to_mpn (const char *str, int digcnt, mp_limb *n, mp_size_t *nsize,
+	    int *exponent)
+{
+  /* Number of digits for actual limb.  */
+  int cnt = 0;
+  mp_limb low = 0;
+  mp_limb base;
+
+  *nsize = 0;
+  assert (digcnt > 0);
+  do
+    {
+      if (cnt == MAX_DIG_PER_LIMB)
+	{
+	  if (*nsize == 0)
+	    n[0] = low;
+	  else
+	    {
+	      mp_limb cy;
+	      cy = __mpn_mul_1 (n, n, *nsize, MAX_FAC_PER_LIMB);
+	      cy += __mpn_add_1 (n, n, *nsize, low);
+	      if (cy != 0)
+		n[*nsize] = cy;
+	    }
+	  ++(*nsize);
+	  cnt = 0;
+	  low = 0;
+	}
+
+      /* There might be thousands separators or radix characters in the string.
+	 But these all can be ignored because we know the format of the number
+	 is correct and we have an exact number of characters to read.  */
+      while (!isdigit (*str))
+	++str;
+      low = low * 10 + *str++ - '0';
+      ++cnt;
+    }
+  while (--digcnt > 0);
+
+  if (*exponent > 0 && cnt + *exponent <= MAX_DIG_PER_LIMB)
+    {
+      low *= _tens_in_limb[*exponent];
+      base = _tens_in_limb[cnt + *exponent];
+      *exponent = 0;
+    }
+  else
+    base = _tens_in_limb[cnt];
+
+  if (*nsize == 0)
+    {
+      n[0] = low;
+      *nsize = 1;
+    }
+  else
+    {
+      mp_limb cy;
+      cy = __mpn_mul_1 (n, n, *nsize, base);
+      cy += __mpn_add_1 (n, n, *nsize, low);
+      if (cy != 0)
+	n[(*nsize)++] = cy;
+    }
+  return str;
+}
+
+
+/* Shift {PTR, SIZE} COUNT bits to the left, and fill the vacated bits
+   with the COUNT most significant bits of LIMB.
+
+   Tege doesn't like this function so I have to write it here myself. :)
+   --drepper */
+static inline void
+__mpn_lshift_1 (mp_limb *ptr, mp_size_t size, unsigned int count, mp_limb limb)
+{
+  if (count == BITS_PER_MP_LIMB)
+    {
+      /* Optimize the case of shifting by exactly a word:
+	 just copy words, with no actual bit-shifting.  */
+      mp_size_t i;
+      for (i = size - 1; i > 0; --i)
+	ptr[i] = ptr[i - 1];
+      ptr[0] = limb;
+    }
+  else
+    {
+      (void) __mpn_lshift (ptr, ptr, size, count);
+      ptr[0] |= limb >> (BITS_PER_MP_LIMB - count);
+    }
+}
+
+
+/* Return a floating point number with the value of the given string NPTR.
+   Set *ENDPTR to the character after the last used one.  If the number is
+   smaller than the smallest representable number, set `errno' to ERANGE and
+   return 0.0.  If the number is too big to be represented, set `errno' to
+   ERANGE and return HUGE_VAL with the approriate sign.  */
+FLOAT
+STRTOF (nptr, endptr)
+    const char *nptr;
+    char **endptr;
+{
+  int negative;			/* The sign of the number.  */
+  MPN_VAR (num);		/* MP representation of the number.  */
+  int exponent;			/* Exponent of the number.  */
+
+  /* When we have to compute fractional digits we form a fraction with a
+     second multi-precision number (and we sometimes need a second for
+     temporary results).  */
+  MPN_VAR (den);
+
+  /* Representation for the return value.  */
+  mp_limb retval[RETURN_LIMB_SIZE];
+  /* Number of bits currently in result value.  */
+  int bits;
+
+  /* Running pointer after the last character processed in the string.  */
+  const char *cp;
+  /* Start of significant part of the number.  */
+  const char *startp;
+  /* Points at the character following the integer and fractional digits.  */
+  const char *expp;
+  /* Total number of digit and number of digits in integer part.  */
+  int dig_no, int_no;
+  /* Contains the last character read.  */
+  char c;
+
+  /* The radix character of the current locale.  */
+  wchar_t decimal;
+#ifdef	USE_GROUPING
+  /* The thousands character of the current locale.  */
+  wchar_t thousands;
+  /* The numeric grouping specification of the current locale,
+     in the format described in <locale.h>.  */
+  const char *grouping;
+
+  /* Check the grouping of the integer part at [BEGIN,END).
+     Return zero iff a separator is found out of place.  */
+  int grouping_ok (const char *begin, const char *end)
+    {
+      if (grouping)
+	while (end > begin)
+	  {
+	    const char *p = end;
+	    do
+	      --p;
+	    while (*p != thousands && p > begin);
+	    if (end - 1 - p != *grouping++)
+	      return 0;		/* Wrong number of digits in this group.  */
+	    end = p;		/* Correct group; trim it off the end.  */
+
+	    if (*grouping == 0)
+	      --grouping;	/* Same grouping repeats in next iteration.  */
+	    else if (*grouping == CHAR_MAX || *grouping < 0)
+	      {
+		/* No further grouping allowed.  */
+		while (end > begin)
+		  if (*--end == thousands)
+		    return 0;
+	      }
+	  }
+      return 1;
+    }
+  /* Return with no conversion if the grouping of [STARTP,CP) is bad.  */
+#define	CHECK_GROUPING if (! grouping_ok (startp, cp)) RETURN (0.0, nptr); else
+
+  grouping = _numeric_info->grouping; /* Cache the grouping info array.  */
+  if (*grouping <= 0 || *grouping == CHAR_MAX)
+    grouping = NULL;
+  else
+    {
+      /* Figure out the thousands seperator character.  */
+      if (mbtowc (&thousands_sep, _numeric_info->thousands_sep,
+		  strlen (_numeric_info->thousands_sep)) <= 0)
+	thousands = (wchar_t) *_numeric_info->thousands_sep;
+      if (thousands == L'\0')
+	grouping = NULL;
+    }
+#else
+#define	grouping	NULL
+#define	thousands	L'\0'
+#define	CHECK_GROUPING	((void) 0)
+#endif
+
+  /* Find the locale's decimal point character.  */
+  if (mbtowc (&decimal, _numeric_info->decimal_point,
+	      strlen (_numeric_info->decimal_point)) <= 0)
+    decimal = (wchar_t) *_numeric_info->decimal_point;
+
+
+  /* Prepare number representation.  */
+  exponent = 0;
+  negative = 0;
+  bits = 0;
+
+  /* Parse string to get maximal legal prefix.  We need the number of
+     characters of the interger part, the fractional part and the exponent.  */
+  cp = nptr - 1;
+  /* Ignore leading white space.  */
+  do
+    c = *++cp;
+  while (isspace (c));
+
+  /* Get sign of the result.  */
+  if (c == '-')
+    {
+      negative = 1;
+      c = *++cp;
+    }
+  else if (c == '+')
+    c = *++cp;
+
+  /* Return 0.0 if no legal string is found.
+     No character is used even if a sign was found.  */
+  if (!isdigit (c))
+    RETURN (0.0, nptr);
+
+  /* Record the start of the digits, in case we will check their grouping.  */
+  startp = cp;
+
+  /* Ignore leading zeroes.  This helps us to avoid useless computations.  */
+  while (c == '0' || (thousands != L'\0' && c == thousands))
+    c = *++cp;
+
+  CHECK_GROUPING;
+
+  /* If no other digit but a '0' is found the result is 0.0.
+     Return current read pointer.  */
+  if (!isdigit (c) && c != decimal)
+    RETURN (0.0, cp);
+
+  /* Remember first significant digit and read following characters until the
+     decimal point, exponent character or any non-FP number character.  */
+  startp = cp;
+  dig_no = 0;
+  while (dig_no < NDIG ||
+	 /* If parsing grouping info, keep going past useful digits
+	    so we can check all the grouping separators.  */
+	 grouping)
+    {
+      if (isdigit (c))
+	++dig_no;
+      else if (thousands == L'\0' || c != thousands)
+	/* Not a digit or separator: end of the integer part.  */
+	break;
+      c = *++cp;
+    }
+
+  CHECK_GROUPING;
+
+  if (dig_no >= NDIG)
+    /* Too many digits to be representable.  Assigning this to EXPONENT
+       allows us to read the full number but return HUGE_VAL after parsing.  */
+    exponent = MAX_10_EXP;
+
+  /* We have the number digits in the integer part.  Whether these are all or
+     any is really a fractional digit will be decided later.  */
+  int_no = dig_no;
+
+  /* Read the fractional digits.  */
+  if (c == decimal)
+    {
+      if (isdigit (cp[1]))
+	{
+	  ++cp;
+	  do
+	    {
+	      ++dig_no;
+	      c = *++cp;
+	    }
+	  while (isdigit (c));
+	}
+    }
+
+  /* Remember start of exponent (if any).  */
+  expp = cp;
+
+  /* Read exponent.  */
+  if (tolower (c) == 'e')
+    {
+      int exp_negative = 0;
+
+      c = *++cp;
+      if (c == '-')
+	{
+	  exp_negative = 1;
+	  c = *++cp;
+	}
+      else if (c == '+')
+	c = *++cp;
+
+      if (isdigit (c))
+	{
+	  do
+	    {
+	      if ((!exp_negative && exponent * 10 + int_no > MAX_10_EXP)
+		  || (exp_negative
+		      && exponent * 10 + int_no > -MIN_10_EXP + MANT_DIG))
+		/* The exponent is too large/small to represent a valid
+		   number.  */
+		{
+	 	  FLOAT retval;
+
+		  /* Overflow or underflow.  */
+		  errno = ERANGE;
+		  retval = (exp_negative ? 0.0 :
+			    negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL);
+
+		  /* Accept all following digits as part of the exponent.  */
+		  do
+		    ++cp;
+		  while (isdigit (*cp));
+
+		  RETURN (retval, cp);
+		  /* NOTREACHED */
+		}
+
+	      exponent *= 10;
+	      exponent += c - '0';
+	      c = *++cp;
+	    }
+	  while (isdigit (c));
+	}
+      else
+	cp = expp;
+
+      if (exp_negative)
+	exponent = -exponent;
+    }
+
+  /* We don't want to have to work with trailing zeroes after the radix.  */
+  if (dig_no > int_no)
+    {
+      while (expp[-1] == '0')
+	{
+	  --expp;
+	  --dig_no;
+	}
+      assert (dig_no >= int_no);
+    }
+
+  /* The whole string is parsed.  Store the address of the next character.  */
+  if (endptr)
+    *endptr = (char *) cp;
+
+  if (dig_no == 0)
+    return 0.0;
+
+  /* Now we have the number of digits in total and the integer digits as well
+     as the exponent and its sign.  We can decide whether the read digits are
+     really integer digits or belong to the fractional part; i.e. we normalize
+     123e-2 to 1.23.  */
+  {
+    register int incr = exponent < 0 ? MAX (-int_no, exponent)
+				     : MIN (dig_no - int_no, exponent);
+    int_no += incr;
+    exponent -= incr;
+  }
+
+  if (int_no + exponent > MAX_10_EXP)
+    {
+      errno = ERANGE;
+      return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
+    }
+
+  if (int_no - dig_no + exponent < MIN_10_EXP - MANT_DIG)
+    {
+      errno = ERANGE;
+      return 0.0;
+    }	
+
+  if (int_no > 0)
+    {
+      /* Read the integer part as a multi-precision number to NUM.  */
+      startp = str_to_mpn (startp, int_no, num, &numsize, &exponent);
+
+      if (exponent > 0)
+	{
+	  /* We now multiply the gained number by the given power of ten.  */
+	  mp_limb *psrc = num;
+	  mp_limb *pdest = den;
+	  int expbit = 1;
+	  const struct mp_power *ttab = &_fpioconst_pow10[0];
+
+	  assert (exponent < (1 << (MAX_10_EXP_LOG + 1)));
+	  do
+	    {
+	      if ((exponent & expbit) != 0)
+		{
+		  mp_limb cy;
+		  exponent ^= expbit;
+
+		  /* FIXME: not the whole multiplication has to be done.
+		     If we have the needed number of bits we only need the
+		     information whether more non-zero bits follow.  */
+		  if (numsize >= ttab->arraysize - 2)
+		    cy = __mpn_mul (pdest, psrc, numsize,
+				    &ttab->array[2], ttab->arraysize - 2);
+		  else
+		    cy = __mpn_mul (pdest, &ttab->array[2],
+				    ttab->arraysize - 2,
+				    psrc, numsize);
+		  numsize += ttab->arraysize - 2;
+		  if (cy == 0)
+		    --numsize;
+		  SWAP (psrc, pdest);
+		}
+	      expbit <<= 1;
+	      ++ttab;
+	    }
+	  while (exponent != 0);
+
+	  if (psrc == den)
+	    memcpy (num, den, numsize * sizeof (mp_limb));
+	}
+
+      /* Determine how many bits of the result we already have.  */
+      count_leading_zeros (bits, num[numsize - 1]);
+      bits = numsize * BITS_PER_MP_LIMB - bits;
+
+      /* We have already the first BITS bits of the result.  Together with
+	 the information whether more non-zero bits follow this is enough
+	 to determine the result.  */
+      if (bits > MANT_DIG)
+	{
+	  const mp_size_t least_idx = (bits - MANT_DIG) / BITS_PER_MP_LIMB;
+	  const mp_size_t least_bit = (bits - MANT_DIG) % BITS_PER_MP_LIMB;
+	  const mp_size_t round_idx = least_bit == 0 ? least_idx - 1
+						     : least_idx;
+	  const mp_size_t round_bit = least_bit == 0 ? BITS_PER_MP_LIMB - 1
+						     : least_idx - 1;
+	  int i;
+
+	  if (least_bit == 0)
+	    memcpy (retval, &num[least_idx],
+		    RETURN_LIMB_SIZE * sizeof (mp_limb));
+	  else
+	    (void) __mpn_rshift (retval, &num[least_idx],
+				 numsize - least_idx + 1, least_bit);
+
+	  /* Check whether any limb beside the ones in RETVAL are non-zero.  */
+	  for (i = 0; num[i] == 0; ++i)
+	    ;
+
+	  return round_and_return (retval, bits - 1, negative,
+				   num[round_idx], round_bit,
+				   int_no < dig_no || i < round_idx);
+	  /* NOTREACHED */
+	}
+      else if (dig_no == int_no)
+	{
+	  const mp_size_t target_bit = (MANT_DIG - 1) % BITS_PER_MP_LIMB;
+	  const mp_size_t is_bit = (bits - 1) % BITS_PER_MP_LIMB;
+
+	  if (target_bit == is_bit)
+	    {
+	      memcpy (&retval[RETURN_LIMB_SIZE - numsize], num,
+		      numsize * sizeof (mp_limb));
+	      /* FIXME: the following loop can be avoided if we assume a
+		 maximal MANT_DIG value.  */
+	      MPN_ZERO (retval, RETURN_LIMB_SIZE - numsize);
+	    }
+	  else if (target_bit > is_bit)
+	    {
+	      (void) __mpn_lshift (&retval[RETURN_LIMB_SIZE - numsize],
+				   num, numsize, target_bit - is_bit);
+	      /* FIXME: the following loop can be avoided if we assume a
+		 maximal MANT_DIG value.  */
+	      MPN_ZERO (retval, RETURN_LIMB_SIZE - numsize);
+	    }
+	  else
+	    {
+	      mp_limb cy;
+	      assert (numsize < RETURN_LIMB_SIZE);
+
+	      cy = __mpn_rshift (&retval[RETURN_LIMB_SIZE - numsize],
+				 num, numsize, is_bit - target_bit);
+	      retval[RETURN_LIMB_SIZE - numsize - 1] = cy;
+	      /* FIXME: the following loop can be avoided if we assume a
+		 maximal MANT_DIG value.  */
+	      MPN_ZERO (retval, RETURN_LIMB_SIZE - numsize - 1);
+	    }
+
+	  return round_and_return (retval, bits - 1, negative, 0, 0, 0);
+	  /* NOTREACHED */
+	}
+
+      /* Store the bits we already have.  */
+      memcpy (retval, num, numsize * sizeof (mp_limb));
+#if RETURN_LIMB_SIZE > 1
+      if (numsize < RETURN_LIMB_SIZE)
+        retval[numsize] = 0;
+#endif
+    }
+
+  /* We have to compute at least some of the fractional digits.  */
+  {
+    /* We construct a fraction and the result of the division gives us
+       the needed digits.  The denominator is 1.0 multiplied by the
+       exponent of the lowest digit; i.e. 0.123 gives 123 / 1000 and
+       123e6 gives 123 / 1000000.  */
+
+    int expbit;
+    int cnt;
+    mp_limb cy;
+    mp_limb *psrc = den;
+    mp_limb *pdest = num;
+    int neg_exp = dig_no - int_no - exponent;
+    const struct mp_power *ttab = &_fpioconst_pow10[0];
+
+    assert (dig_no > int_no && exponent <= 0);
+
+    /* Construct the denominator.  */
+    densize = 0;
+    expbit = 1;
+    do
+      {
+	if ((neg_exp & expbit) != 0)
+	  {
+	    mp_limb cy;
+	    neg_exp ^= expbit;
+
+	    if (densize == 0)
+	      memcpy (psrc, &ttab->array[2],
+		      (densize = ttab->arraysize - 2) * sizeof (mp_limb));
+	    else
+	      {
+		cy = __mpn_mul (pdest, &ttab->array[2], ttab->arraysize - 2,
+				psrc, densize);
+		densize += ttab->arraysize - 2;
+		if (cy == 0)
+		  --densize;
+		SWAP (psrc, pdest);
+	      }
+	  }
+	expbit <<= 1;
+	++ttab;
+      }
+    while (neg_exp != 0);
+
+    if (psrc == num)
+      memcpy (den, num, densize * sizeof (mp_limb));
+
+    /* Read the fractional digits from the string.  */ 
+    (void) str_to_mpn (startp, dig_no - int_no, num, &numsize, &exponent);
+
+
+    /* We now have to shift both numbers so that the highest bit in the
+       denominator is set.  In the same process we copy the numerator to
+       a high place in the array so that the division constructs the wanted
+       digits.  This is done by a "quasi fix point" number representation.
+
+       num:   ddddddddddd . 0000000000000000000000
+              |--- m ---|
+       den:                            ddddddddddd      n >= m
+                                       |--- n ---|
+     */
+
+    count_leading_zeros (cnt, den[densize - 1]);
+
+    (void) __mpn_lshift (den, den, densize, cnt);
+    cy = __mpn_lshift (num, num, numsize, cnt);
+    if (cy != 0)
+      num[numsize++] = cy;
+
+    /* Now we are ready for the division.  But it is not necessary to
+       do a full multi-precision division because we only need a small
+       number of bits for the result.  So we do not use __mpn_divmod
+       here but instead do the division here by hand and stop whenever
+       the needed number of bits is reached.  The code itself comes
+       from the GNU MP Library by Torbj\"orn Granlund.  */
+
+    exponent = bits;
+
+    switch (densize)
+      {
+      case 1:
+	{
+	  mp_limb d, n, quot;
+	  int used = 0;
+
+	  n = num[0];
+	  d = den[0];
+	  assert (numsize == 1 && n < d);
+
+	  do
+	    {
+	      udiv_qrnnd (quot, n, n, 0, d);
+
+#define got_limb							      \
+	      if (bits == 0)						      \
+		{							      \
+		  register int cnt;					      \
+		  if (quot == 0)					      \
+		    cnt = BITS_PER_MP_LIMB;				      \
+		  else							      \
+		    count_leading_zeros (cnt, quot);			      \
+		  exponent -= cnt;					      \
+		  if (BITS_PER_MP_LIMB - cnt > MANT_DIG)		      \
+		    {							      \
+		      used = cnt + MANT_DIG;				      \
+		      retval[0] = quot >> (BITS_PER_MP_LIMB - used);	      \
+		      bits -= BITS_PER_MP_LIMB - used;			      \
+		    }							      \
+		  else							      \
+		    {							      \
+		      /* Note that we only clear the second element.  */      \
+		      retval[1] = 0;					      \
+		      retval[0] = quot;					      \
+		      bits -= cnt;					      \
+		    }							      \
+		}							      \
+	      else if (bits + BITS_PER_MP_LIMB <= MANT_DIG)		      \
+		__mpn_lshift_1 (retval, RETURN_LIMB_SIZE, BITS_PER_MP_LIMB,    \
+				quot);					      \
+	      else							      \
+		{							      \
+		  used = MANT_DIG - bits;				      \
+		  if (used > 0)						      \
+		    __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, quot);     \
+		}							      \
+	      bits += BITS_PER_MP_LIMB
+
+              got_limb;
+	    }
+	  while (bits <= MANT_DIG);
+
+	  return round_and_return (retval, exponent - 1, negative,
+				   quot, BITS_PER_MP_LIMB - 1 - used,
+				   n != 0);
+	}
+      case 2:
+	{
+	  mp_limb d0, d1, n0, n1;
+	  mp_limb quot = 0;
+	  int used = 0;
+
+	  d0 = den[0];
+	  d1 = den[1];
+
+	  if (numsize < densize)
+	    {
+	      if (bits <= 0)
+		exponent -= BITS_PER_MP_LIMB;
+	      else
+		{
+		  if (bits + BITS_PER_MP_LIMB <= MANT_DIG)
+		    __mpn_lshift_1 (retval, RETURN_LIMB_SIZE,
+				    BITS_PER_MP_LIMB, 0);
+		  else
+		    {
+		      used = MANT_DIG - bits;
+		      if (used > 0)
+			__mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0);
+		    }
+		  bits += BITS_PER_MP_LIMB;
+		}
+	      n1 = num[0];
+	      n0 = 0;
+	    }
+	  else
+	    {
+	      n1 = num[1];
+	      n0 = num[0];
+	    }
+
+	  while (bits <= MANT_DIG)
+	    {
+	      mp_limb r;
+
+	      if (n1 == d1)
+		{
+		  /* QUOT should be either 111..111 or 111..110.  We need
+		     special treatment of this rare case as normal division
+		     would give overflow.  */
+		  quot = ~(mp_limb) 0;
+
+		  r = n0 + d1;
+		  if (r < d1)	/* Carry in the addition?  */
+		    {
+		      add_ssaaaa (n1, n0, r - d0, 0, 0, d0);
+		      goto have_quot;
+		    }
+		  n1 = d0 - (d0 != 0);
+		  n0 = -d0;
+		}
+	      else
+		{
+		  udiv_qrnnd (quot, r, n1, n0, d1);
+		  umul_ppmm (n1, n0, d0, quot);
+		}
+
+	    q_test:
+	      if (n1 > r || (n1 == r && n0 > 0))
+		{
+		  /* The estimated QUOT was too large.  */
+		  --quot;
+
+		  sub_ddmmss (n1, n0, n1, n0, 0, d0);
+		  r += d1;
+		  if (r >= d1)	/* If not carry, test QUOT again.  */
+		    goto q_test;
+		}
+	      sub_ddmmss (n1, n0, r, 0, n1, n0);
+
+	    have_quot:
+	      got_limb;
+	    }
+	    
+	  return round_and_return (retval, exponent - 1, negative,
+				   quot, BITS_PER_MP_LIMB - 1 - used,
+				   n1 != 0 || n0 != 0);
+	}
+      default:
+	{
+	  int i;
+	  mp_limb cy, dX, d1, n0, n1;
+	  mp_limb quot = 0;
+	  int used = 0;
+
+	  dX = den[densize - 1];
+	  d1 = den[densize - 2];
+
+	  /* The division does not work if the upper limb of the two-limb
+	     numerator is greater than the denominator.  */
+	  if (num[numsize - 1] > dX)
+	    num[numsize++] = 0;
+
+	  if (numsize < densize)
+	    {
+	      mp_size_t empty = densize - numsize;
+
+	      if (bits <= 0)
+		{
+		  register int i;
+		  for (i = numsize; i > 0; --i)
+		    num[i + empty] = num[i - 1];
+		  MPN_ZERO (num, empty + 1);
+		  exponent -= empty * BITS_PER_MP_LIMB;
+		}
+	      else
+		{
+		  if (bits + empty * BITS_PER_MP_LIMB <= MANT_DIG)
+		    {
+		      /* We make a difference here because the compiler
+			 cannot optimize the `else' case that good and
+			 this reflects all currently used FLOAT types
+			 and GMP implementations.  */
+		      register int i;
+#if RETURN_LIMB_SIZE <= 2
+		      assert (empty == 1);
+		      __mpn_lshift_1 (retval, RETURN_LIMB_SIZE,
+				      BITS_PER_MP_LIMB, 0);
+#else
+		      for (i = RETURN_LIMB_SIZE; i > empty; --i)
+			retval[i] = retval[i - empty];
+#endif
+		      retval[1] = 0;
+		      for (i = numsize; i > 0; --i)
+			num[i + empty] = num[i - 1];
+		      MPN_ZERO (num, empty + 1);
+		    }
+		  else
+		    {
+		      used = MANT_DIG - bits;
+		      if (used >= BITS_PER_MP_LIMB)
+			{
+			  register int i;
+			  (void) __mpn_lshift (&retval[used
+						       / BITS_PER_MP_LIMB],
+					       retval, RETURN_LIMB_SIZE,
+					       used % BITS_PER_MP_LIMB);
+			  for (i = used / BITS_PER_MP_LIMB; i >= 0; --i)
+			    retval[i] = 0;
+			}
+		      else if (used > 0)
+			__mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0);
+		    }
+		  bits += empty * BITS_PER_MP_LIMB;
+		}
+	    }
+	  else
+	    {
+	      int i;
+	      assert (numsize == densize);
+	      for (i = numsize; i > 0; --i)
+		num[i] = num[i - 1];
+	    }
+
+	  den[densize] = 0;
+	  n0 = num[densize];
+
+	  while (bits <= MANT_DIG)
+	    {
+	      if (n0 == dX)
+		/* This might over-estimate QUOT, but it's probably not
+		   worth the extra code here to find out.  */
+		quot = ~(mp_limb) 0;
+	      else
+		{
+		  mp_limb r;
+
+		  udiv_qrnnd (quot, r, n0, num[densize - 1], dX);
+		  umul_ppmm (n1, n0, d1, quot);
+
+		  while (n1 > r || (n1 == r && n0 > num[densize - 2]))
+		    {
+		      --quot;
+		      r += dX;
+		      if (r < dX) /* I.e. "carry in previous addition?" */
+			break;
+		      n1 -= n0 < d1;
+		      n0 -= d1;
+		    }
+		}
+
+	      /* Possible optimization: We already have (q * n0) and (1 * n1)
+		 after the calculation of QUOT.  Taking advantage of this, we
+		 could make this loop make two iterations less.  */
+
+	      cy = __mpn_submul_1 (num, den, densize + 1, quot);
+
+	      if (num[densize] != cy)
+		{
+		  cy = __mpn_add_n (num, num, den, densize);
+		  assert (cy != 0);
+		  --quot;
+		}
+	      n0 = num[densize] = num[densize - 1];
+	      for (i = densize - 1; i > 0; --i)
+		num[i] = num[i - 1];
+
+	      got_limb;
+	    }
+
+	  for (i = densize - 1; num[i] != 0 && i >= 0; --i)
+	    ;
+	  return round_and_return (retval, exponent - 1, negative,
+				   quot, BITS_PER_MP_LIMB - 1 - used,
+				   i >= 0);
+	}
+      }
+  }
+
+  /* NOTREACHED */
+}
diff --git a/stdlib/strtof.c b/stdlib/strtof.c
new file mode 100644
index 0000000000..bf1349b108
--- /dev/null
+++ b/stdlib/strtof.c
@@ -0,0 +1,12 @@
+/* The actual implementation for all floating point sizes is in strtod.c.
+   These macros tell it to produce the `float' version, `strtof'.  */
+
+#define	FLOAT		float
+#define	FLT		FLT
+#define	STRTOF		__strtof
+#define	MPN2FLOAT	__mpn_construct_float
+#define	FLOAT_HUGE_VAL	HUGE_VALf
+
+#include "strtod.c"
+
+weak_alias (__strtof, strtof)
diff --git a/stdlib/strtol.c b/stdlib/strtol.c
new file mode 100644
index 0000000000..888a94e4d7
--- /dev/null
+++ b/stdlib/strtol.c
@@ -0,0 +1,189 @@
+/* Copyright (C) 1991, 1992, 1994, 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 <ctype.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/* Nonzero if we are defining `strtoul' or `strtouq', operating on unsigned
+   integers.  */
+#ifndef	UNSIGNED
+#define	UNSIGNED	0
+#endif
+
+/* If QUAD is defined, we are defining `strtoq' or `strtouq',
+   operating on `long long int's.  */
+#ifdef QUAD
+#if UNSIGNED
+#define strtoul		strtouq
+#else
+#define strtol		strtoq
+#endif
+#define	LONG		long long
+#undef	LONG_MIN
+#define	LONG_MIN	LONG_LONG_MIN
+#undef	LONG_MAX
+#define LONG_MAX	LONG_LONG_MAX
+#undef	ULONG_MAX
+#define ULONG_MAX	ULONG_LONG_MAX
+#if __GNUC__ == 2 && __GNUC_MINOR__ < 7
+/* Work around gcc bug with using this constant.  */
+static const unsigned long long int maxquad = ULONG_LONG_MAX;
+#undef	ULONG_MAX
+#define ULONG_MAX	maxquad
+#endif
+#else
+#define	LONG	long
+#endif
+
+/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
+   If BASE is 0 the base is determined by the presence of a leading
+   zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
+   If BASE is < 2 or > 36, it is reset to 10.
+   If ENDPTR is not NULL, a pointer to the character after the last
+   one converted is stored in *ENDPTR.  */
+#if	UNSIGNED
+unsigned LONG int
+#define	strtol	strtoul
+#else
+LONG int
+#endif
+strtol (nptr, endptr, base)
+     const char *nptr;
+     char **endptr;
+     int base;
+{
+  int negative;
+  register unsigned LONG int cutoff;
+  register unsigned int cutlim;
+  register unsigned LONG int i;
+  register const char *s;
+  register unsigned char c;
+  const char *save;
+  int overflow;
+
+  if (base < 0 || base == 1 || base > 36)
+    base = 10;
+
+  s = nptr;
+
+  /* Skip white space.  */
+  while (isspace (*s))
+    ++s;
+  if (*s == '\0')
+    goto noconv;
+
+  /* Check for a sign.  */
+  if (*s == '-')
+    {
+      negative = 1;
+      ++s;
+    }
+  else if (*s == '+')
+    {
+      negative = 0;
+      ++s;
+    }
+  else
+    negative = 0;
+
+  if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
+    s += 2;
+
+  /* If BASE is zero, figure it out ourselves.  */
+  if (base == 0)
+    if (*s == '0')
+      {
+	if (toupper (s[1]) == 'X')
+	  {
+	    s += 2;
+	    base = 16;
+	  }
+	else
+	  base = 8;
+      }
+    else
+      base = 10;
+
+  /* Save the pointer so we can check later if anything happened.  */
+  save = s;
+
+  cutoff = ULONG_MAX / (unsigned LONG int) base;
+  cutlim = ULONG_MAX % (unsigned LONG int) base;
+
+  overflow = 0;
+  i = 0;
+  for (c = *s; c != '\0'; c = *++s)
+    {
+      if (isdigit (c))
+	c -= '0';
+      else if (isalpha (c))
+	c = toupper (c) - 'A' + 10;
+      else
+	break;
+      if (c >= base)
+	break;
+      /* Check for overflow.  */
+      if (i > cutoff || (i == cutoff && c > cutlim))
+	overflow = 1;
+      else
+	{
+	  i *= (unsigned LONG int) base;
+	  i += c;
+	}
+    }
+
+  /* Check if anything actually happened.  */
+  if (s == save)
+    goto noconv;
+
+  /* Store in ENDPTR the address of one character
+     past the last character we converted.  */
+  if (endptr != NULL)
+    *endptr = (char *) s;
+
+#if	!UNSIGNED
+  /* Check for a value that is within the range of
+     `unsigned LONG int', but outside the range of `LONG int'.  */
+  if (i > (negative ?
+	   -(unsigned LONG int) LONG_MIN : (unsigned LONG int) LONG_MAX))
+    overflow = 1;
+#endif
+
+  if (overflow)
+    {
+      errno = ERANGE;
+#if	UNSIGNED
+      return ULONG_MAX;
+#else
+      return negative ? LONG_MIN : LONG_MAX;
+#endif
+    }
+
+  /* Return the result of the appropriate sign.  */
+  return (negative ? -i : i);
+
+noconv:
+  /* There was no number to convert.  */
+  if (endptr != NULL)
+    *endptr = (char *) nptr;
+  return 0L;
+}
diff --git a/stdlib/strtold.c b/stdlib/strtold.c
new file mode 100644
index 0000000000..2595725add
--- /dev/null
+++ b/stdlib/strtold.c
@@ -0,0 +1,12 @@
+/* The actual implementation for all floating point sizes is in strtod.c.
+   These macros tell it to produce the `long double' version, `strtold'.  */
+
+#define	FLOAT		long double
+#define	FLT		LDBL
+#define	STRTOF		__strtold
+#define	MPN2FLOAT	__mpn_construct_long_double
+#define	FLOAT_HUGE_VAL	HUGE_VALl
+
+#include "strtod.c"
+
+weak_alias (__strtold, strtold)
diff --git a/stdlib/strtoq.c b/stdlib/strtoq.c
new file mode 100644
index 0000000000..be1f723b13
--- /dev/null
+++ b/stdlib/strtoq.c
@@ -0,0 +1,22 @@
+/* strtoq -- Function to parse a `long long int' from text.
+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.  */
+
+#define	QUAD	1
+
+#include <strtol.c>
diff --git a/stdlib/strtoul.c b/stdlib/strtoul.c
new file mode 100644
index 0000000000..386cc7a357
--- /dev/null
+++ b/stdlib/strtoul.c
@@ -0,0 +1,21 @@
+/* Copyright (C) 1991 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.  */
+
+#define	UNSIGNED	1
+
+#include <strtol.c>
diff --git a/stdlib/strtouq.c b/stdlib/strtouq.c
new file mode 100644
index 0000000000..4eea0b22ee
--- /dev/null
+++ b/stdlib/strtouq.c
@@ -0,0 +1,22 @@
+/* strtouq -- Function to parse an `unsigned long long int' from text.
+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.  */
+
+#define	QUAD	1
+
+#include <strtoul.c>
diff --git a/stdlib/testdiv.c b/stdlib/testdiv.c
new file mode 100644
index 0000000000..b86a58d42c
--- /dev/null
+++ b/stdlib/testdiv.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1992 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 <ansidecl.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+DEFUN_VOID(main)
+{
+  int i, j;
+  while (scanf ("%d %d\n", &i, &j) == 2)
+    {
+      div_t d = div (i, j);
+      printf ("%d / %d = %d + %d/%d\n", i, j, d.quot, d.rem, j);
+    }
+  return 0;
+}
diff --git a/stdlib/testdiv.input b/stdlib/testdiv.input
new file mode 100644
index 0000000000..415b7b4f54
--- /dev/null
+++ b/stdlib/testdiv.input
@@ -0,0 +1,2 @@
+10 3
+-10 3
diff --git a/stdlib/testmb.c b/stdlib/testmb.c
new file mode 100644
index 0000000000..c840ce195b
--- /dev/null
+++ b/stdlib/testmb.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+  wchar_t w[10];
+  char c[10];
+  int i;
+  int lose = 0;
+
+  i = mbstowcs (w, "bar", 4);
+  if (!(i == 3 && w[1] == 'a'))
+    {
+      puts ("mbstowcs FAILED!");
+      lose = 1;
+    }
+
+  mbstowcs (w, "blah", 5);
+  i = wcstombs (c, w, 10);
+  if (i != 4)
+    {
+      puts ("wcstombs FAILED!");
+      lose = 1;
+    }
+
+  if (mblen ("foobar", 7) != 1)
+    {
+      puts ("mblen 1 FAILED!");
+      lose = 1;
+    }
+
+  if (mblen ("", 1) != 0)
+    {
+      puts ("mblen 2 FAILED!");
+      lose = 1;
+    }
+
+  {
+    int r;
+    char c = 'x';
+    wchar_t wc;
+    char *mbc;
+
+    mbc = (char *) malloc (MB_CUR_MAX);
+    mbc[0] = c;
+    mbc[1] = '\0';
+
+    if ((r = mbtowc (&wc, &c, MB_CUR_MAX)) <= 0)
+      {
+	printf ("conversion to wide failed, result: %d\n", r);
+	lose = 1;
+      }
+    else
+      {
+	printf ("wide value: 0x%04x\n", (unsigned long) wc);
+	mbc[0] = '\0';
+	if ((r = wctomb (mbc, wc)) <= 0)
+	  {
+	    printf ("conversion to multibyte failed, result: %d\n", r);
+	    lose = 1;
+	  }
+      }
+
+  }
+
+  puts (lose ? "Test FAILED!" : "Test succeeded.");
+  return lose;
+}
diff --git a/stdlib/testrand.c b/stdlib/testrand.c
new file mode 100644
index 0000000000..b66dca9899
--- /dev/null
+++ b/stdlib/testrand.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1992 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 <ansidecl.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+DEFUN_VOID(main)
+{
+  int i1, i2;
+  int j1, j2;
+
+  /* The C standard says that "If rand is called before any calls to
+     srand have been made, the same sequence shall be generated as
+     when srand is first called with a seed value of 1." */
+  i1 = rand();
+  i2 = rand();
+  srand (1);
+  j1 = rand();
+  j2 = rand();
+  if (j1 == i1 && j2 == i2)
+    {
+      puts ("Test succeeded.");
+      return 0;
+    }
+  else
+    {
+      if (j1 != i1)
+	printf ("%d != %d\n", j1, i1);
+      if (j2 != i2)
+	printf ("%d != %d\n", j2, i2);
+      puts ("Test FAILED!");
+      return 1;
+    }
+}
diff --git a/stdlib/testsort.c b/stdlib/testsort.c
new file mode 100644
index 0000000000..a171a62130
--- /dev/null
+++ b/stdlib/testsort.c
@@ -0,0 +1,38 @@
+#include <ansidecl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+int
+DEFUN(compare, (a, b), CONST PTR a AND CONST PTR b)
+{
+  return strcmp (*(char **) a, *(char **) b);
+}
+
+
+int
+DEFUN_VOID(main)
+{
+  char bufs[500][20];
+  char *lines[500];
+  size_t lens[500];
+  size_t i, j;
+
+  srandom (1);
+
+  for (i = 0; i < 500; ++i)
+    {
+      lens[i] = random() % 19;
+      lines[i] = bufs[i];
+      for (j = 0; j < lens[i]; ++j)
+	lines[i][j] = random() % 26 + 'a';
+      lines[i][j] = '\0';
+    }
+
+  qsort (lines, 500, sizeof (char *), compare);
+
+  for (i = 0; i < 500 && lines[i] != NULL; ++i)
+    puts (lines[i]);
+
+  return 0;
+}
diff --git a/stdlib/tst-strtod.c b/stdlib/tst-strtod.c
new file mode 100644
index 0000000000..a38ff4a74b
--- /dev/null
+++ b/stdlib/tst-strtod.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 1991 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 <ansidecl.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+struct ltest
+  {
+    CONST char *str;		/* Convert this.  */
+    double expect;		/* To get this.  */
+    char left;			/* With this left over.  */
+    int err;			/* And this in errno.  */
+  };
+static CONST struct ltest tests[] =
+  {
+    { "12.345", 12.345, '\0', 0 },
+    { "12.345e19", 12.345e19, '\0', 0 },
+    { "-.1e+9", -.1e+9, '\0', 0 },
+    { ".125", .125, '\0', 0 },
+    { "1e20", 1e20, '\0', 0 },
+    { NULL, 0, '\0', 0 }
+  };
+
+static void EXFUN(expand, (char *dst, int c));
+
+int
+DEFUN_VOID(main)
+{
+  register CONST struct ltest *lt;
+  char *ep;
+  int status = 0;
+
+  for (lt = tests; lt->str != NULL; ++lt)
+    {
+      double d;
+
+      errno = 0;
+      d = strtod(lt->str, &ep);
+      printf("strtod(\"%s\") test %u",
+	     lt->str, (unsigned int) (lt - tests));
+      if (d == lt->expect && *ep == lt->left && errno == lt->err)
+	puts("\tOK");
+      else
+	{
+	  puts("\tBAD");
+	  if (d != lt->expect)
+	    printf("  returns %.60g, expected %.60g\n", d, lt->expect);
+	  if (lt->left != *ep)
+	    {
+	      char exp1[5], exp2[5];
+	      expand(exp1, *ep);
+	      expand(exp2, lt->left);
+	      printf("  leaves '%s', expected '%s'\n", exp1, exp2);
+	    }
+	  if (errno != lt->err)
+	    printf("  errno %d (%s)  instead of %d (%s)\n",
+		   errno, strerror(errno), lt->err, strerror(lt->err));
+	  status = 1;
+	}
+    }
+
+  exit(status ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+static void
+DEFUN(expand, (dst, c), register char *dst AND register int c)
+{
+  if (isprint(c))
+    {
+      dst[0] = c;
+      dst[1] = '\0';
+    }
+  else
+    (void) sprintf(dst, "%#.3o", (unsigned int) c);
+}
diff --git a/stdlib/tst-strtol.c b/stdlib/tst-strtol.c
new file mode 100644
index 0000000000..0682da3f09
--- /dev/null
+++ b/stdlib/tst-strtol.c
@@ -0,0 +1,127 @@
+/* My bet is this was written by Chris Torek.
+   I reformatted and ansidecl-ized it, and tweaked it a little.  */
+
+#include <ansidecl.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <strings.h>
+
+struct ltest
+  {
+    CONST char *str;		/* Convert this.  */
+    unsigned long int expect;	/* To get this.  */
+    int base;			/* Use this base.  */
+    char left;			/* With this left over.  */
+    int err;			/* And this in errno.  */
+  };
+static CONST struct ltest tests[] =
+  {
+    /* First, signed numbers.  */
+    { "   -17",		-17,		0,	0,	0 },
+    { " +0x123fg",	0x123f,		0,	'g',	0 },
+    { "2147483647",	2147483647,	0,	0,	0 },
+    { "2147483648",	2147483647,	0,	0,	ERANGE },
+    { "214748364888",	2147483647,	0,	0,	ERANGE },
+    { "2147483650",	2147483647,	0,	0,	ERANGE },
+    { "-2147483649",	-2147483648,	0,	0,	ERANGE },
+    { "-2147483648",	-2147483648,	0,	0,	0 },
+    { "0123",		0123,		0,	0,	0 },
+    { "0x1122334455z",	2147483647,	16,	'z',	ERANGE },
+    { "0x0xc",		0,		0,	'x',	0 },
+    { "yz!",		34*36+35,	36,	'!',	0 },
+    { NULL,		0,		0,	0,	0 },
+
+    /* Then unsigned.  */
+    { "  0",		0,		0,	0,	0 },
+    { "0xffffffffg",	0xffffffff,	0,	'g',	0 },
+    { "0xf1f2f3f4f5",	0xffffffff,	0,	0,	ERANGE },
+    { "-0x123456789",	0xffffffff,	0,	0,	ERANGE },
+    { "-0xfedcba98",	-0xfedcba98,	0,	0,	0 },
+    { NULL,		0,		0,	0,	0 },
+  };
+
+static void EXFUN(expand, (char *dst, int c));
+
+int
+DEFUN_VOID(main)
+{
+  register CONST struct ltest *lt;
+  char *ep;
+  int status = 0;
+
+  for (lt = tests; lt->str != NULL; ++lt)
+    {
+      register long int l;
+
+      errno = 0;
+      l = strtol(lt->str, &ep, lt->base);
+      printf("strtol(\"%s\", , %d) test %u",
+	     lt->str, lt->base, (unsigned int) (lt - tests));
+      if (l == (long int) lt->expect && *ep == lt->left && errno == lt->err)
+	puts("\tOK");
+      else
+	{
+	  puts("\tBAD");
+	  if (l != (long int) lt->expect)
+	    printf("  returns %ld, expected %ld\n",
+		   l, (long int) lt->expect);
+	  if (lt->left != *ep)
+	    {
+	      char exp1[5], exp2[5];
+	      expand(exp1, *ep);
+	      expand(exp2, lt->left);
+	      printf("  leaves '%s', expected '%s'\n", exp1, exp2);
+	    }
+	  if (errno != lt->err)
+	    printf("  errno %d (%s)  instead of %d (%s)\n",
+		   errno, strerror(errno), lt->err, strerror(lt->err));
+	  status = 1;
+	}
+    }
+
+  for (++lt; lt->str != NULL; lt++)
+    {
+      register unsigned long int ul;
+
+      errno = 0;
+      ul = strtoul(lt->str, &ep, lt->base);
+      printf("strtoul(\"%s\", , %d) test %u",
+	     lt->str, lt->base, (unsigned int) (lt - tests));
+      if (ul == lt->expect && *ep == lt->left && errno == lt->err)
+	puts("\tOK");
+      else
+	{
+	  puts("\tBAD");
+	  if (ul != lt->expect)
+	    printf("  returns %lu, expected %lu\n",
+		   ul, lt->expect);
+	  if (lt->left != *ep)
+	    {
+	      char exp1[5], exp2[5];
+	      expand(exp1, *ep);
+	      expand(exp2, lt->left);
+	      printf("  leaves '%s', expected '%s'\n", exp1, exp2);
+	    }
+	  if (errno != lt->err)
+	    printf("  errno %d (%s) instead of %d (%s)\n",
+		   errno, strerror(errno), lt->err, strerror(lt->err));
+	  status = 1;
+	}
+    }
+
+  exit(status ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+static void
+DEFUN(expand, (dst, c), register char *dst AND register int c)
+{
+  if (isprint(c))
+    {
+      dst[0] = c;
+      dst[1] = '\0';
+    }
+  else
+    (void) sprintf(dst, "%#.3o", (unsigned int) c);
+}
diff --git a/stdlib/wcstombs.c b/stdlib/wcstombs.c
new file mode 100644
index 0000000000..acaf15a94e
--- /dev/null
+++ b/stdlib/wcstombs.c
@@ -0,0 +1,77 @@
+/* Copyright (C) 1991, 1992 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 <ansidecl.h>
+#include <localeinfo.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Convert the `wchar_t' string in PWCS to a multibyte character string
+   in S, writing no more than N characters.  Return the number of bytes
+   written, or (size_t) -1 if an invalid `wchar_t' was found.  */
+size_t
+DEFUN(wcstombs, (s, pwcs, n),
+      register char *s AND register CONST wchar_t *pwcs AND register size_t n)
+{
+  register CONST mb_char *mb;
+  register int shift = 0;
+
+  register size_t written = 0;
+  register wchar_t w;
+
+  while ((w = *pwcs++) != (wchar_t) '\0')
+    {
+      if (isascii (w))
+	{
+	  /* A normal character.  */
+	  *s++ = (unsigned char) w;
+	  --n;
+	  ++written;
+	}
+      else
+	{
+	  mb = &_ctype_info->mbchar->mb_chars[w + shift];
+	  if (mb->string == NULL || mb->len == 0)
+	    {
+	      written = (size_t) -1;
+	      break;
+	    }
+	  else if (mb->len > n)
+	    break;
+	  else
+	    {
+	      memcpy ((PTR) s, (CONST PTR) mb->string, mb->len);
+	      s += mb->len;
+	      n -= mb->len;
+	      written += mb->len;
+	      shift += mb->shift;
+	    }
+	}
+    }
+
+  /* Terminate the string if it has space.  */
+  if (n > 0)
+    *s = '\0';
+
+  /* Return the number of characters written (or maybe an error).  */
+  return written;
+}
diff --git a/stdlib/wctomb.c b/stdlib/wctomb.c
new file mode 100644
index 0000000000..53f1cef3fc
--- /dev/null
+++ b/stdlib/wctomb.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 1991, 1992, 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 <ansidecl.h>
+#include <localeinfo.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+
+extern long int _mb_shift;	/* Defined in mbtowc.c.  */
+
+/* Convert WCHAR into its multibyte character representation,
+   putting this in S and returning its length.  */
+int
+DEFUN(wctomb, (s, wchar), register char *s AND wchar_t wchar)
+{
+  register CONST mb_char *mb;
+
+  if (_ctype_info->mbchar == NULL)
+    mb = NULL;
+  else
+    mb = _ctype_info->mbchar->mb_chars;
+
+  /* If S is NULL, just say if we're shifted or not.  */
+  if (s == NULL)
+    return _mb_shift != 0;
+
+  if (wchar == (wchar_t) '\0')
+    {
+      _mb_shift = 0;
+      /* See ANSI 4.4.1.1, line 21.  */
+      if (s != NULL)
+	*s = '\0';
+      return 1;
+    }
+  else if (mb == NULL)
+    {
+      if ((wchar_t) (char) wchar == wchar && isascii ((char) wchar))
+	{
+	  /* A normal ASCII character translates to itself.  */
+	  if (s != NULL)
+	    *s = (char) wchar;
+	  return 1;
+	}
+      return -1;
+    }
+
+  mb += wchar + _mb_shift;
+  if (mb->string == NULL || mb->len == 0)
+    return -1;
+  memcpy((PTR) s, (CONST PTR) mb->string, mb->len + 1);
+  _mb_shift += mb->shift;
+  return mb->len;
+}