Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/string')
-rw-r--r--newlib/libc/string/Makefile.am66
-rw-r--r--newlib/libc/string/Makefile.in343
-rw-r--r--newlib/libc/string/bcmp.c50
-rw-r--r--newlib/libc/string/bcopy.c38
-rw-r--r--newlib/libc/string/bzero.c42
-rw-r--r--newlib/libc/string/index.c44
-rw-r--r--newlib/libc/string/memchr.c143
-rw-r--r--newlib/libc/string/memcmp.c113
-rw-r--r--newlib/libc/string/memcpy.c111
-rw-r--r--newlib/libc/string/memmove.c143
-rw-r--r--newlib/libc/string/memset.c110
-rw-r--r--newlib/libc/string/rindex.c44
-rw-r--r--newlib/libc/string/strcasecmp.c56
-rw-r--r--newlib/libc/string/strcat.c104
-rw-r--r--newlib/libc/string/strchr.c108
-rw-r--r--newlib/libc/string/strcmp.c106
-rw-r--r--newlib/libc/string/strcoll.c48
-rw-r--r--newlib/libc/string/strcpy.c99
-rw-r--r--newlib/libc/string/strcspn.c54
-rw-r--r--newlib/libc/string/strerror.c650
-rw-r--r--newlib/libc/string/strings.tex133
-rw-r--r--newlib/libc/string/strlen.c88
-rw-r--r--newlib/libc/string/strlwr.c50
-rw-r--r--newlib/libc/string/strncasecmp.c64
-rw-r--r--newlib/libc/string/strncat.c115
-rw-r--r--newlib/libc/string/strncmp.c122
-rw-r--r--newlib/libc/string/strncpy.c125
-rw-r--r--newlib/libc/string/strpbrk.c58
-rw-r--r--newlib/libc/string/strrchr.c61
-rw-r--r--newlib/libc/string/strspn.c59
-rw-r--r--newlib/libc/string/strstr.c73
-rw-r--r--newlib/libc/string/strtok.c76
-rw-r--r--newlib/libc/string/strtok_r.c85
-rw-r--r--newlib/libc/string/strupr.c49
-rw-r--r--newlib/libc/string/strxfrm.c75
-rw-r--r--newlib/libc/string/u_strerr.c8
36 files changed, 3713 insertions, 0 deletions
diff --git a/newlib/libc/string/Makefile.am b/newlib/libc/string/Makefile.am
new file mode 100644
index 000000000..26d4b8952
--- /dev/null
+++ b/newlib/libc/string/Makefile.am
@@ -0,0 +1,66 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
+
+noinst_LIBRARIES = lib.a
+
+lib_a_SOURCES = \
+ bcmp.c \
+ bcopy.c \
+ bzero.c \
+ index.c \
+ memchr.c \
+ memcmp.c \
+ memcpy.c \
+ memmove.c \
+ memset.c \
+ rindex.c \
+ strcat.c \
+ strchr.c \
+ strcmp.c \
+ strcasecmp.c \
+ strcoll.c \
+ strcpy.c \
+ strcspn.c \
+ strerror.c \
+ strlen.c \
+ strlwr.c \
+ strncat.c \
+ strncmp.c \
+ strncasecmp.c \
+ strncpy.c \
+ strpbrk.c \
+ strrchr.c \
+ strspn.c \
+ strtok.c \
+ strtok_r.c \
+ strupr.c \
+ strxfrm.c \
+ strstr.c \
+ u_strerr.c
+
+CHEWOUT_FILES=\
+bcmp.def memcpy.def strcmp.def strncat.def strstr.def \
+bcopy.def memmove.def strcoll.def strncmp.def strtok.def \
+bzero.def memset.def strcpy.def strncpy.def strxfrm.def \
+index.def rindex.def strcspn.def strpbrk.def \
+memchr.def strcat.def strerror.def strrchr.def \
+memcmp.def strchr.def strlen.def strspn.def \
+strcasecmp.def strncasecmp.def strlwr.def strupr.def
+
+SUFFIXES = .def
+
+CHEW = ../../doc/makedoc -f $(srcdir)/../../doc/doc.str
+
+.c.def:
+ $(CHEW) < $< > $*.def 2> $*.ref
+ touch stmp-def
+
+TARGETDOC = ../tmp.texi
+
+doc: $(CHEWOUT_FILES)
+ cat $(srcdir)/strings.tex >> $(TARGETDOC)
+
+CLEANFILES = $(CHEWOUT_FILES) *.ref
diff --git a/newlib/libc/string/Makefile.in b/newlib/libc/string/Makefile.in
new file mode 100644
index 000000000..29a413c0d
--- /dev/null
+++ b/newlib/libc/string/Makefile.in
@@ -0,0 +1,343 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AR = @AR@
+AS = @AS@
+CC = @CC@
+CPP = @CPP@
+CRT0 = @CRT0@
+EXEEXT = @EXEEXT@
+LIBC_MACHINE_LIB = @LIBC_MACHINE_LIB@
+LIBC_POSIX_LIB = @LIBC_POSIX_LIB@
+LIBC_SIGNAL_DEF = @LIBC_SIGNAL_DEF@
+LIBC_SIGNAL_LIB = @LIBC_SIGNAL_LIB@
+LIBC_SYSCALL_LIB = @LIBC_SYSCALL_LIB@
+LIBC_SYS_LIB = @LIBC_SYS_LIB@
+LIBC_UNIX_LIB = @LIBC_UNIX_LIB@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+NEWLIB_CFLAGS = @NEWLIB_CFLAGS@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+machine_dir = @machine_dir@
+newlib_basedir = @newlib_basedir@
+sys_dir = @sys_dir@
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
+
+noinst_LIBRARIES = lib.a
+
+lib_a_SOURCES = \
+ bcmp.c \
+ bcopy.c \
+ bzero.c \
+ index.c \
+ memchr.c \
+ memcmp.c \
+ memcpy.c \
+ memmove.c \
+ memset.c \
+ rindex.c \
+ strcat.c \
+ strchr.c \
+ strcmp.c \
+ strcasecmp.c \
+ strcoll.c \
+ strcpy.c \
+ strcspn.c \
+ strerror.c \
+ strlen.c \
+ strlwr.c \
+ strncat.c \
+ strncmp.c \
+ strncasecmp.c \
+ strncpy.c \
+ strpbrk.c \
+ strrchr.c \
+ strspn.c \
+ strtok.c \
+ strtok_r.c \
+ strupr.c \
+ strxfrm.c \
+ strstr.c \
+ u_strerr.c
+
+
+CHEWOUT_FILES = \
+bcmp.def memcpy.def strcmp.def strncat.def strstr.def \
+bcopy.def memmove.def strcoll.def strncmp.def strtok.def \
+bzero.def memset.def strcpy.def strncpy.def strxfrm.def \
+index.def rindex.def strcspn.def strpbrk.def \
+memchr.def strcat.def strerror.def strrchr.def \
+memcmp.def strchr.def strlen.def strspn.def \
+strcasecmp.def strncasecmp.def strlwr.def strupr.def
+
+
+SUFFIXES = .def
+
+CHEW = ../../doc/makedoc -f $(srcdir)/../../doc/doc.str
+
+TARGETDOC = ../tmp.texi
+
+CLEANFILES = $(CHEWOUT_FILES) *.ref
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+lib_a_LIBADD =
+lib_a_OBJECTS = bcmp.o bcopy.o bzero.o index.o memchr.o memcmp.o \
+memcpy.o memmove.o memset.o rindex.o strcat.o strchr.o strcmp.o \
+strcasecmp.o strcoll.o strcpy.o strcspn.o strerror.o strlen.o strlwr.o \
+strncat.o strncmp.o strncasecmp.o strncpy.o strpbrk.o strrchr.o \
+strspn.o strtok.o strtok_r.o strupr.o strxfrm.o strstr.o u_strerr.o
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(lib_a_SOURCES)
+OBJECTS = $(lib_a_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .def .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus string/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES)
+ -rm -f lib.a
+ $(AR) cru lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD)
+ $(RANLIB) lib.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = string
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am:
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-info-am:
+install-info: install-info-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LIBRARIES)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstLIBRARIES distclean-compile \
+ distclean-tags distclean-generic clean-am
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
+ maintainer-clean-compile maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-info-am install-info \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+.c.def:
+ $(CHEW) < $< > $*.def 2> $*.ref
+ touch stmp-def
+
+doc: $(CHEWOUT_FILES)
+ cat $(srcdir)/strings.tex >> $(TARGETDOC)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/newlib/libc/string/bcmp.c b/newlib/libc/string/bcmp.c
new file mode 100644
index 000000000..b6a4d5298
--- /dev/null
+++ b/newlib/libc/string/bcmp.c
@@ -0,0 +1,50 @@
+/*
+FUNCTION
+ <<bcmp>>---compare two memory areas
+
+INDEX
+ bcmp
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ int bcmp(const char *<[s1]>, const char *<[s2]>, size_t <[n]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ int bcmp(<[s1]>, <[s2]>, <[n]>)
+ char *<[s1]>;
+ char *<[s2]>;
+ size_t <[n]>;
+
+DESCRIPTION
+ This function compares not more than <[n]> characters of the
+ object pointed to by <[s1]> with the object pointed to by <[s2]>.
+
+ This function is identical to <<memcmp>>.
+
+
+
+RETURNS
+ The function returns an integer greater than, equal to or
+ less than zero according to whether the object pointed to by
+ <[s1]> is greater than, equal to or less than the object
+ pointed to by <[s2]>.
+
+PORTABILITY
+<<bcmp>> requires no supporting OS subroutines.
+
+QUICKREF
+ bcmp ansi pure
+*/
+
+#include <string.h>
+
+int
+_DEFUN (bcmp, (m1, m2, n),
+ _CONST char *m1 _AND
+ _CONST char *m2 _AND
+ size_t n)
+
+{
+ return memcmp (m1, m2, n);
+}
diff --git a/newlib/libc/string/bcopy.c b/newlib/libc/string/bcopy.c
new file mode 100644
index 000000000..733840b83
--- /dev/null
+++ b/newlib/libc/string/bcopy.c
@@ -0,0 +1,38 @@
+/*
+FUNCTION
+ <<bcopy>>---copy memory regions
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void bcopy(const char *<[in]>, char *<[out]>, size_t <[n]>);
+
+TRAD_SYNOPSIS
+ void bcopy(<[in]>, <[out]>, <[n]>
+ char *<[in]>;
+ char *<[out]>;
+ size_t <[n]>;
+
+DESCRIPTION
+ This function copies <[n]> bytes from the memory region
+ pointed to by <[in]> to the memory region pointed to by
+ <[out]>.
+
+ This function is implemented in term of <<memmove>>.
+
+PORTABILITY
+<<bcopy>> requires no supporting OS subroutines.
+
+QUICKREF
+ bcopy - pure
+*/
+
+#include <string.h>
+
+void
+_DEFUN (bcopy, (b1, b2, length),
+ _CONST char *b1 _AND
+ char *b2 _AND
+ size_t length)
+{
+ memmove ((_PTR) b2, (_PTR) b1, length);
+}
diff --git a/newlib/libc/string/bzero.c b/newlib/libc/string/bzero.c
new file mode 100644
index 000000000..e9e78c938
--- /dev/null
+++ b/newlib/libc/string/bzero.c
@@ -0,0 +1,42 @@
+/*
+FUNCTION
+<<bzero>>---initialize memory to zero
+
+INDEX
+ bzero
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void bzero(char *<[b]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ void bzero(<[b]>, <[length]>)
+ char *<[b]>;
+ size_t <[length]>;
+
+DESCRIPTION
+<<bzero>> initializes <[length]> bytes of memory, starting at address
+<[b]>, to zero.
+
+RETURNS
+<<bzero>> does not return a result.
+
+PORTABILITY
+<<bzero>> is in the Berkeley Software Distribution.
+Neither ANSI C nor the System V Interface Definition (Issue 2) require
+<<bzero>>.
+
+<<bzero>> requires no supporting OS subroutines.
+*/
+
+#include <string.h>
+
+_VOID
+_DEFUN (bzero, (b, length),
+ char *b _AND
+ size_t length)
+{
+ while (length--)
+ *b++ = 0;
+}
diff --git a/newlib/libc/string/index.c b/newlib/libc/string/index.c
new file mode 100644
index 000000000..6c165f952
--- /dev/null
+++ b/newlib/libc/string/index.c
@@ -0,0 +1,44 @@
+/*
+FUNCTION
+ <<index>>---search for character in string
+
+INDEX
+ index
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char * index(const char *<[string]>, int <[c]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char * index(<[string]>, <[c]>);
+ char *<[string]>;
+ int *<[c]>;
+
+DESCRIPTION
+ This function finds the first occurence of <[c]> (converted to
+ a char) in the string pointed to by <[string]> (including the
+ terminating null character).
+
+ This function is identical to <<strchr>>.
+
+RETURNS
+ Returns a pointer to the located character, or a null pointer
+ if <[c]> does not occur in <[string]>.
+
+PORTABILITY
+<<index>> requires no supporting OS subroutines.
+
+QUICKREF
+ index - pure
+*/
+
+#include <string.h>
+
+char *
+_DEFUN (index, (s, c),
+ _CONST char *s _AND
+ int c)
+{
+ return strchr (s, c);
+}
diff --git a/newlib/libc/string/memchr.c b/newlib/libc/string/memchr.c
new file mode 100644
index 000000000..2fd3c861d
--- /dev/null
+++ b/newlib/libc/string/memchr.c
@@ -0,0 +1,143 @@
+/*
+FUNCTION
+ <<memchr>>---find character in memory
+
+INDEX
+ memchr
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void *memchr(const void *<[src]>, int <[c]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ void *memchr(<[src]>, <[c]>, <[length]>)
+ void *<[src]>;
+ void *<[c]>;
+ size_t <[length]>;
+
+DESCRIPTION
+ This function searches memory starting at <<*<[src]>>> for the
+ character <[c]>. The search only ends with the first
+ occurrence of <[c]>, or after <[length]> characters; in
+ particular, <<NULL>> does not terminate the search.
+
+RETURNS
+ If the character <[c]> is found within <[length]> characters
+ of <<*<[src]>>>, a pointer to the character is returned. If
+ <[c]> is not found, then <<NULL>> is returned.
+
+PORTABILITY
+<<memchr>>> is ANSI C.
+
+<<memchr>> requires no supporting OS subroutines.
+
+QUICKREF
+ memchr ansi pure
+*/
+
+#include <_ansi.h>
+#include <string.h>
+#include <limits.h>
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
+
+/* How many bytes are loaded each iteration of the word copy loop. */
+#define LBLOCKSIZE (sizeof (long))
+
+/* Threshhold for punting to the bytewise iterator. */
+#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
+
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+/* Nonzero if X (a long int) contains a NULL byte. */
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+#ifndef DETECTNULL
+#error long int is not a 32bit or 64bit byte
+#endif
+
+
+_PTR
+_DEFUN (memchr, (src_void, c, length),
+ _CONST _PTR src_void _AND
+ int c _AND
+ size_t length)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ _CONST unsigned char *src = (_CONST unsigned char *) src_void;
+
+ c &= 0xff;
+
+ while (length--)
+ {
+ if (*src == c)
+ return (char *) src;
+ src++;
+ }
+ return NULL;
+#else
+ _CONST unsigned char *src = (_CONST unsigned char *) src_void;
+ unsigned long *asrc;
+ unsigned long buffer;
+ unsigned long mask;
+ int i, j;
+
+ c &= 0xff;
+
+ /* If the size is small, or src is unaligned, then
+ use the bytewise loop. We can hope this is rare. */
+ if (!TOO_SMALL (length) && !UNALIGNED (src))
+ {
+ /* The fast code reads the ASCII one word at a time and only
+ performs the bytewise search on word-sized segments if they
+ contain the search character, which is detected by XORing
+ the word-sized segment with a word-sized block of the search
+ character and then detecting for the presence of NULL in the
+ result. */
+ asrc = (unsigned long*) src;
+ mask = 0;
+ for (i = 0; i < LBLOCKSIZE; i++)
+ mask = (mask << 8) + c;
+
+ while (length >= LBLOCKSIZE)
+ {
+ buffer = *asrc;
+ buffer ^= mask;
+ if (DETECTNULL (buffer))
+ {
+ src = (unsigned char*) asrc;
+ for ( j = 0; j < LBLOCKSIZE; j++ )
+ {
+ if (*src == c)
+ return (char*) src;
+ src++;
+ }
+ }
+ length -= LBLOCKSIZE;
+ asrc++;
+ }
+
+ /* If there are fewer than LBLOCKSIZE characters left,
+ then we resort to the bytewise loop. */
+
+ src = (unsigned char*) asrc;
+ }
+
+ while (length--)
+ {
+ if (*src == c)
+ return (char*) src;
+ src++;
+ }
+
+ return NULL;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/memcmp.c b/newlib/libc/string/memcmp.c
new file mode 100644
index 000000000..ac7a194a6
--- /dev/null
+++ b/newlib/libc/string/memcmp.c
@@ -0,0 +1,113 @@
+/*
+FUNCTION
+ <<memcmp>>---compare two memory areas
+
+INDEX
+ memcmp
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ int memcmp(const void *<[s1]>, const void *<[s2]>, size_t <[n]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ int memcmp(<[s1]>, <[s2]>, <[n]>)
+ void *<[s1]>;
+ void *<[s2]>;
+ size_t <[n]>;
+
+DESCRIPTION
+ This function compares not more than <[n]> characters of the
+ object pointed to by <[s1]> with the object pointed to by <[s2]>.
+
+
+RETURNS
+ The function returns an integer greater than, equal to or
+ less than zero according to whether the object pointed to by
+ <[s1]> is greater than, equal to or less than the object
+ pointed to by <[s2]>.
+
+PORTABILITY
+<<memcmp>> is ANSI C.
+
+<<memcmp>> requires no supporting OS subroutines.
+
+QUICKREF
+ memcmp ansi pure
+*/
+
+#include <string.h>
+
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* How many bytes are copied each iteration of the word copy loop. */
+#define LBLOCKSIZE (sizeof (long))
+
+/* Threshhold for punting to the byte copier. */
+#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
+
+int
+_DEFUN (memcmp, (m1, m2, n),
+ _CONST _PTR m1 _AND
+ _CONST _PTR m2 _AND
+ size_t n)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ unsigned char *s1 = (unsigned char *) m1;
+ unsigned char *s2 = (unsigned char *) m2;
+
+ while (n--)
+ {
+ if (*s1 != *s2)
+ {
+ return *s1 - *s2;
+ }
+ s1++;
+ s2++;
+ }
+ return 0;
+#else
+ unsigned char *s1 = (unsigned char *) m1;
+ unsigned char *s2 = (unsigned char *) m2;
+ unsigned long *a1;
+ unsigned long *a2;
+
+ /* If the size is too small, or either pointer is unaligned,
+ then we punt to the byte compare loop. Hopefully this will
+ not turn up in inner loops. */
+ if (!TOO_SMALL(n) && !UNALIGNED(s1,s2))
+ {
+ /* Otherwise, load and compare the blocks of memory one
+ word at a time. */
+ a1 = (unsigned long*) s1;
+ a2 = (unsigned long*) s2;
+ while (n >= LBLOCKSIZE)
+ {
+ if (*a1 != *a2)
+ break;
+ a1++;
+ a2++;
+ n -= LBLOCKSIZE;
+ }
+
+ /* check m mod LBLOCKSIZE remaining characters */
+
+ s1 = (char*)a1;
+ s2 = (char*)a2;
+ }
+
+ while (n--)
+ {
+ if (*s1 != *s2)
+ return *s1 - *s2;
+ s1++;
+ s2++;
+ }
+
+ return 0;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
+
diff --git a/newlib/libc/string/memcpy.c b/newlib/libc/string/memcpy.c
new file mode 100644
index 000000000..5336f25a9
--- /dev/null
+++ b/newlib/libc/string/memcpy.c
@@ -0,0 +1,111 @@
+/*
+FUNCTION
+ <<memcpy>>---copy memory regions
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
+
+TRAD_SYNOPSIS
+ void *memcpy(<[out]>, <[in]>, <[n]>
+ void *<[out]>;
+ void *<[in]>;
+ size_t <[n]>;
+
+DESCRIPTION
+ This function copies <[n]> bytes from the memory region
+ pointed to by <[in]> to the memory region pointed to by
+ <[out]>.
+
+ If the regions overlap, the behavior is undefined.
+
+RETURNS
+ <<memcpy>> returns a pointer to the first byte of the <[out]>
+ region.
+
+PORTABILITY
+<<memcpy>> is ANSI C.
+
+<<memcpy>> requires no supporting OS subroutines.
+
+QUICKREF
+ memcpy ansi pure
+ */
+
+#include <_ansi.h>
+#include <stddef.h>
+#include <limits.h>
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* How many bytes are copied each iteration of the 4X unrolled loop. */
+#define BIGBLOCKSIZE (sizeof (long) << 2)
+
+/* How many bytes are copied each iteration of the word copy loop. */
+#define LITTLEBLOCKSIZE (sizeof (long))
+
+/* Threshhold for punting to the byte copier. */
+#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
+
+_PTR
+_DEFUN (memcpy, (dst0, src0, len0),
+ _PTR dst0 _AND
+ _CONST _PTR src0 _AND
+ size_t len0)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *dst = (char *) dst0;
+ char *src = (char *) src0;
+
+ _PTR save = dst0;
+
+ while (len0--)
+ {
+ *dst++ = *src++;
+ }
+
+ return save;
+#else
+ char *dst = dst0;
+ _CONST char *src = src0;
+ long *aligned_dst;
+ _CONST long *aligned_src;
+ int len = len0;
+
+ /* If the size is small, or either SRC or DST is unaligned,
+ then punt into the byte copy loop. This should be rare. */
+ if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
+ {
+ aligned_dst = (long*)dst;
+ aligned_src = (long*)src;
+
+ /* Copy 4X long words at a time if possible. */
+ while (len >= BIGBLOCKSIZE)
+ {
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ len -= BIGBLOCKSIZE;
+ }
+
+ /* Copy one long word at a time if possible. */
+ while (len >= LITTLEBLOCKSIZE)
+ {
+ *aligned_dst++ = *aligned_src++;
+ len -= LITTLEBLOCKSIZE;
+ }
+
+ /* Pick up any residual with a byte copier. */
+ dst = (char*)aligned_dst;
+ src = (char*)aligned_src;
+ }
+
+ while (len--)
+ *dst++ = *src++;
+
+ return dst0;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/memmove.c b/newlib/libc/string/memmove.c
new file mode 100644
index 000000000..2528e27d4
--- /dev/null
+++ b/newlib/libc/string/memmove.c
@@ -0,0 +1,143 @@
+/*
+FUNCTION
+ <<memmove>>---move possibly overlapping memory
+
+INDEX
+ memmove
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ void *memmove(<[dst]>, <[src]>, <[length]>)
+ void *<[dst]>;
+ void *<[src]>;
+ size_t <[length]>;
+
+DESCRIPTION
+ This function moves <[length]> characters from the block of
+ memory starting at <<*<[src]>>> to the memory starting at
+ <<*<[dst]>>>. <<memmove>> reproduces the characters correctly
+ at <<*<[dst]>>> even if the two areas overlap.
+
+
+RETURNS
+ The function returns <[dst]> as passed.
+
+PORTABILITY
+<<memmove>> is ANSI C.
+
+<<memmove>> requires no supporting OS subroutines.
+
+QUICKREF
+ memmove ansi pure
+*/
+
+#include <string.h>
+#include <_ansi.h>
+#include <stddef.h>
+#include <limits.h>
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* How many bytes are copied each iteration of the 4X unrolled loop. */
+#define BIGBLOCKSIZE (sizeof (long) << 2)
+
+/* How many bytes are copied each iteration of the word copy loop. */
+#define LITTLEBLOCKSIZE (sizeof (long))
+
+/* Threshhold for punting to the byte copier. */
+#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
+
+/*SUPPRESS 20*/
+_PTR
+_DEFUN (memmove, (dst_void, src_void, length),
+ _PTR dst_void _AND
+ _CONST _PTR src_void _AND
+ size_t length)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *dst = dst_void;
+ _CONST char *src = src_void;
+
+ if (src < dst && dst < src + length)
+ {
+ /* Have to copy backwards */
+ src += length;
+ dst += length;
+ while (length--)
+ {
+ *--dst = *--src;
+ }
+ }
+ else
+ {
+ while (length--)
+ {
+ *dst++ = *src++;
+ }
+ }
+
+ return dst_void;
+#else
+ char *dst = dst_void;
+ _CONST char *src = src_void;
+ long *aligned_dst;
+ _CONST long *aligned_src;
+ int len = length;
+
+ if (src < dst && dst < src + len)
+ {
+ /* Destructive overlap...have to copy backwards */
+ src += len;
+ dst += len;
+ while (len--)
+ {
+ *--dst = *--src;
+ }
+ }
+ else
+ {
+ /* Use optimizing algorithm for a non-destructive copy to closely
+ match memcpy. If the size is small or either SRC or DST is unaligned,
+ then punt into the byte copy loop. This should be rare. */
+ if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
+ {
+ aligned_dst = (long*)dst;
+ aligned_src = (long*)src;
+
+ /* Copy 4X long words at a time if possible. */
+ while (len >= BIGBLOCKSIZE)
+ {
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ len -= BIGBLOCKSIZE;
+ }
+
+ /* Copy one long word at a time if possible. */
+ while (len >= LITTLEBLOCKSIZE)
+ {
+ *aligned_dst++ = *aligned_src++;
+ len -= LITTLEBLOCKSIZE;
+ }
+
+ /* Pick up any residual with a byte copier. */
+ dst = (char*)aligned_dst;
+ src = (char*)aligned_src;
+ }
+
+ while (len--)
+ {
+ *dst++ = *src++;
+ }
+ }
+
+ return dst_void;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/memset.c b/newlib/libc/string/memset.c
new file mode 100644
index 000000000..f6ec46b9a
--- /dev/null
+++ b/newlib/libc/string/memset.c
@@ -0,0 +1,110 @@
+/*
+FUNCTION
+ <<memset>>---set an area of memory
+
+INDEX
+ memset
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ void *memset(<[dst]>, <[c]>, <[length]>)
+ void *<[dst]>;
+ int <[c]>;
+ size_t <[length]>;
+
+DESCRIPTION
+ This function converts the argument <[c]> into an unsigned
+ char and fills the first <[length]> characters of the array
+ pointed to by <[dst]> to the value.
+
+RETURNS
+ <<memset>> returns the value of <[m]>.
+
+PORTABILITY
+<<memset>> is ANSI C.
+
+ <<memset>> requires no supporting OS subroutines.
+
+QUICKREF
+ memset ansi pure
+*/
+
+#include <string.h>
+
+#define LBLOCKSIZE (sizeof(long))
+#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
+#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
+
+_PTR
+_DEFUN (memset, (m, c, n),
+ _PTR m _AND
+ int c _AND
+ size_t n)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *s = (char *) m;
+
+ while (n-- != 0)
+ {
+ *s++ = (char) c;
+ }
+
+ return m;
+#else
+ char *s = (char *) m;
+ int count, i;
+ unsigned long buffer;
+ unsigned long *aligned_addr;
+ unsigned char *unaligned_addr;
+
+ if (!TOO_SMALL (n) && !UNALIGNED (m))
+ {
+ /* If we get this far, we know that n is large and m is word-aligned. */
+
+ aligned_addr = (unsigned long*)m;
+
+ /* Store C into each char sized location in BUFFER so that
+ we can set large blocks quickly. */
+ c &= 0xff;
+ if (LBLOCKSIZE == 4)
+ {
+ buffer = (c << 8) | c;
+ buffer |= (buffer << 16);
+ }
+ else
+ {
+ buffer = 0;
+ for (i = 0; i < LBLOCKSIZE; i++)
+ buffer = (buffer << 8) | c;
+ }
+
+ while (n >= LBLOCKSIZE*4)
+ {
+ *aligned_addr++ = buffer;
+ *aligned_addr++ = buffer;
+ *aligned_addr++ = buffer;
+ *aligned_addr++ = buffer;
+ n -= 4*LBLOCKSIZE;
+ }
+
+ while (n >= LBLOCKSIZE)
+ {
+ *aligned_addr++ = buffer;
+ n -= LBLOCKSIZE;
+ }
+ /* Pick up the remainder with a bytewise loop. */
+ s = (char*)aligned_addr;
+ }
+
+ while (n--)
+ {
+ *s++ = (char)c;
+ }
+
+ return m;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/rindex.c b/newlib/libc/string/rindex.c
new file mode 100644
index 000000000..3c6dff909
--- /dev/null
+++ b/newlib/libc/string/rindex.c
@@ -0,0 +1,44 @@
+/*
+FUNCTION
+ <<rindex>>---reverse search for character in string
+
+INDEX
+ rindex
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char * rindex(const char *<[string]>, int <[c]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char * rindex(<[string]>, <[c]>);
+ char *<[string]>;
+ int *<[c]>;
+
+DESCRIPTION
+ This function finds the last occurence of <[c]> (converted to
+ a char) in the string pointed to by <[string]> (including the
+ terminating null character).
+
+ This function is identical to <<strrchr>>.
+
+RETURNS
+ Returns a pointer to the located character, or a null pointer
+ if <[c]> does not occur in <[string]>.
+
+PORTABILITY
+<<rindex>> requires no supporting OS subroutines.
+
+QUICKREF
+ rindex - pure
+*/
+
+#include <string.h>
+
+char *
+_DEFUN (rindex, (s, c),
+ _CONST char *s _AND
+ int c)
+{
+ return strrchr (s, c);
+}
diff --git a/newlib/libc/string/strcasecmp.c b/newlib/libc/string/strcasecmp.c
new file mode 100644
index 000000000..4dcfc784a
--- /dev/null
+++ b/newlib/libc/string/strcasecmp.c
@@ -0,0 +1,56 @@
+/*
+FUNCTION
+ <<strcasecmp>>---case insensitive character string compare
+
+INDEX
+ strcasecmp
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ int strcasecmp(const char *<[a]>, const char *<[b]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ int strcasecmp(<[a]>, <[b]>)
+ char *<[a]>;
+ char *<[b]>;
+
+DESCRIPTION
+ <<strcasecmp>> compares the string at <[a]> to
+ the string at <[b]> in a case-insensitive manner.
+
+RETURNS
+
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
+ both are converted to upper case), <<strcasecmp>> returns a
+ number greater than zero. If the two strings match,
+ <<strcasecmp>> returns zero. If <<*<[a]>>> sorts
+ lexicographically before <<*<[b]>>>, <<strcasecmp>> returns a
+ number less than zero.
+
+PORTABILITY
+<<strcasecmp>> is in the Berkeley Software Distribution.
+
+<<strcasecmp>> requires no supporting OS subroutines. It uses
+tolower() from elsewhere in this library.
+
+QUICKREF
+ strcasecmp
+*/
+
+#include <string.h>
+#include <ctype.h>
+
+int
+_DEFUN (strcasecmp, (s1, s2),
+ _CONST char *s1 _AND
+ _CONST char *s2)
+{
+ while (*s1 != '\0' && tolower(*s1) == tolower(*s2))
+ {
+ s1++;
+ s2++;
+ }
+
+ return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
+}
diff --git a/newlib/libc/string/strcat.c b/newlib/libc/string/strcat.c
new file mode 100644
index 000000000..411eadb85
--- /dev/null
+++ b/newlib/libc/string/strcat.c
@@ -0,0 +1,104 @@
+/*
+FUNCTION
+ <<strcat>>---concatenate strings
+
+INDEX
+ strcat
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strcat(char *<[dst]>, const char *<[src]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strcat(<[dst]>, <[src]>)
+ char *<[dst]>;
+ char *<[src]>;
+
+DESCRIPTION
+ <<strcat>> appends a copy of the string pointed to by <[src]>
+ (including the terminating null character) to the end of the
+ string pointed to by <[dst]>. The initial character of
+ <[src]> overwrites the null character at the end of <[dst]>.
+
+RETURNS
+ This function returns the initial value of <[dst]>
+
+PORTABILITY
+<<strcat>> is ANSI C.
+
+<<strcat>> requires no supporting OS subroutines.
+
+QUICKREF
+ strcat ansi pure
+*/
+
+#include <string.h>
+#include <limits.h>
+
+/* Nonzero if X is aligned on a "long" boundary. */
+#define ALIGNED(X) \
+ (((long)X & (sizeof (long) - 1)) == 0)
+
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+/* Nonzero if X (a long int) contains a NULL byte. */
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+#ifndef DETECTNULL
+#error long int is not a 32bit or 64bit byte
+#endif
+
+
+/*SUPPRESS 560*/
+/*SUPPRESS 530*/
+
+char *
+_DEFUN (strcat, (s1, s2),
+ char *s1 _AND
+ _CONST char *s2)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *s = s1;
+
+ while (*s1)
+ s1++;
+
+ while (*s1++ = *s2++)
+ ;
+ return s;
+#else
+ char *s = s1;
+
+
+ /* Skip over the data in s1 as quickly as possible. */
+ if (ALIGNED (s1))
+ {
+ unsigned long *aligned_s1 = (unsigned long *)s1;
+ while (!DETECTNULL (*aligned_s1))
+ aligned_s1++;
+
+ s1 = (char *)aligned_s1;
+ }
+
+ while (*s1)
+ s1++;
+
+ /* s1 now points to the its trailing null character, we can
+ just use strcpy to do the work for us now.
+
+ ?!? We might want to just include strcpy here.
+ Also, this will cause many more unaligned string copies because
+ s1 is much less likely to be aligned. I don't know if its worth
+ tweaking strcpy to handle this better. */
+ strcpy (s1, s2);
+
+ return s;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/strchr.c b/newlib/libc/string/strchr.c
new file mode 100644
index 000000000..de4585f75
--- /dev/null
+++ b/newlib/libc/string/strchr.c
@@ -0,0 +1,108 @@
+/*
+FUNCTION
+ <<strchr>>---search for character in string
+
+INDEX
+ strchr
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char * strchr(const char *<[string]>, int <[c]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char * strchr(<[string]>, <[c]>);
+ char *<[string]>;
+ int *<[c]>;
+
+DESCRIPTION
+ This function finds the first occurence of <[c]> (converted to
+ a char) in the string pointed to by <[string]> (including the
+ terminating null character).
+
+RETURNS
+ Returns a pointer to the located character, or a null pointer
+ if <[c]> does not occur in <[string]>.
+
+PORTABILITY
+<<strchr>> is ANSI C.
+
+<<strchr>> requires no supporting OS subroutines.
+
+QUICKREF
+ strchr ansi pure
+*/
+
+#include <string.h>
+#include <limits.h>
+
+/* Nonzero if X is not aligned on a "long" boundary. */
+#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
+
+/* How many bytes are loaded each iteration of the word copy loop. */
+#define LBLOCKSIZE (sizeof (long))
+
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+/* Nonzero if X (a long int) contains a NULL byte. */
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+/* DETECTCHAR returns nonzero if (long)X contains the byte used
+ to fill (long)MASK. */
+#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
+
+char *
+_DEFUN (strchr, (s1, i),
+ _CONST char *s1 _AND
+ int i)
+{
+ _CONST unsigned char *s = (_CONST unsigned char *)s1;
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ unsigned char c = (unsigned int)i;
+
+ while (*s && *s != c)
+ {
+ s++;
+ }
+
+ if (*s != c)
+ {
+ s = NULL;
+ }
+
+ return (char *) s;
+#else
+ unsigned char c = (unsigned char)i;
+ unsigned long mask,j;
+ unsigned long *aligned_addr;
+
+ if (!UNALIGNED (s))
+ {
+ mask = 0;
+ for (j = 0; j < LBLOCKSIZE; j++)
+ mask = (mask << 8) | c;
+
+ aligned_addr = (unsigned long*)s;
+ while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
+ aligned_addr++;
+
+ /* The block of bytes currently pointed to by aligned_addr
+ contains either a null or the target char, or both. We
+ catch it using the bytewise search. */
+
+ s = (unsigned char*)aligned_addr;
+ }
+
+ while (*s && *s != c)
+ s++;
+ if (*s == c)
+ return (char *)s;
+ return NULL;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/strcmp.c b/newlib/libc/string/strcmp.c
new file mode 100644
index 000000000..81d65272e
--- /dev/null
+++ b/newlib/libc/string/strcmp.c
@@ -0,0 +1,106 @@
+/*
+FUNCTION
+ <<strcmp>>---character string compare
+
+INDEX
+ strcmp
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ int strcmp(const char *<[a]>, const char *<[b]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ int strcmp(<[a]>, <[b]>)
+ char *<[a]>;
+ char *<[b]>;
+
+DESCRIPTION
+ <<strcmp>> compares the string at <[a]> to
+ the string at <[b]>.
+
+RETURNS
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
+ <<strcmp>> returns a number greater than zero. If the two
+ strings match, <<strcmp>> returns zero. If <<*<[a]>>>
+ sorts lexicographically before <<*<[b]>>>, <<strcmp>> returns a
+ number less than zero.
+
+PORTABILITY
+<<strcmp>> is ANSI C.
+
+<<strcmp>> requires no supporting OS subroutines.
+
+QUICKREF
+ strcmp ansi pure
+*/
+
+#include <string.h>
+#include <limits.h>
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+#ifndef DETECTNULL
+#error long int is not a 32bit or 64bit byte
+#endif
+
+int
+_DEFUN (strcmp, (s1, s2),
+ _CONST char *s1 _AND
+ _CONST char *s2)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ while (*s1 != '\0' && *s1 == *s2)
+ {
+ s1++;
+ s2++;
+ }
+
+ return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+#else
+ unsigned long *a1;
+ unsigned long *a2;
+
+ /* If s1 or s2 are unaligned, then compare bytes. */
+ if (!UNALIGNED (s1, s2))
+ {
+ /* If s1 and s2 are word-aligned, compare them a word at a time. */
+ a1 = (unsigned long*)s1;
+ a2 = (unsigned long*)s2;
+ while (*a1 == *a2)
+ {
+ /* To get here, *a1 == *a2, thus if we find a null in *a1,
+ then the strings must be equal, so return zero. */
+ if (DETECTNULL (*a1))
+ return 0;
+
+ a1++;
+ a2++;
+ }
+
+ /* A difference was detected in last few bytes of s1, so search bytewise */
+ s1 = (char*)a1;
+ s2 = (char*)a2;
+ }
+
+ while (*s1 != '\0' && *s1 == *s2)
+ {
+ s1++;
+ s2++;
+ }
+ return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/strcoll.c b/newlib/libc/string/strcoll.c
new file mode 100644
index 000000000..8760b2217
--- /dev/null
+++ b/newlib/libc/string/strcoll.c
@@ -0,0 +1,48 @@
+/*
+FUNCTION
+ <<strcoll>>---locale specific character string compare
+
+INDEX
+ strcoll
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ int strcoll(const char *<[stra]>, const char * <[strb]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ int strcoll(<[stra]>, <[strb]>)
+ char *<[stra]>;
+ char *<[strb]>;
+
+DESCRIPTION
+ <<strcoll>> compares the string pointed to by <[stra]> to
+ the string pointed to by <[strb]>, using an interpretation
+ appropriate to the current <<LC_COLLATE>> state.
+
+RETURNS
+ If the first string is greater than the second string,
+ <<strcoll>> returns a number greater than zero. If the two
+ strings are equivalent, <<strcoll>> returns zero. If the first
+ string is less than the second string, <<strcoll>> returns a
+ number less than zero.
+
+PORTABILITY
+<<strcoll>> is ANSI C.
+
+<<strcoll>> requires no supporting OS subroutines.
+
+QUICKREF
+ strcoll ansi pure
+*/
+
+#include <string.h>
+
+int
+_DEFUN (strcoll, (a, b),
+ _CONST char *a _AND
+ _CONST char *b)
+
+{
+ return strcmp (a, b);
+}
diff --git a/newlib/libc/string/strcpy.c b/newlib/libc/string/strcpy.c
new file mode 100644
index 000000000..905b2541c
--- /dev/null
+++ b/newlib/libc/string/strcpy.c
@@ -0,0 +1,99 @@
+/*
+FUNCTION
+ <<strcpy>>---copy string
+
+INDEX
+ strcpy
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strcpy(char *<[dst]>, const char *<[src]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strcpy(<[dst]>, <[src]>)
+ char *<[dst]>;
+ char *<[src]>;
+
+DESCRIPTION
+ <<strcpy>> copies the string pointed to by <[src]>
+ (including the terminating null character) to the array
+ pointed to by <[dst]>.
+
+RETURNS
+ This function returns the initial value of <[dst]>.
+
+PORTABILITY
+<<strcpy>> is ANSI C.
+
+<<strcpy>> requires no supporting OS subroutines.
+
+QUICKREF
+ strcpy ansi pure
+*/
+
+#include <string.h>
+#include <limits.h>
+
+/*SUPPRESS 560*/
+/*SUPPRESS 530*/
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+/* Nonzero if X (a long int) contains a NULL byte. */
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+#ifndef DETECTNULL
+#error long int is not a 32bit or 64bit byte
+#endif
+
+char*
+_DEFUN (strcpy, (dst0, src0),
+ char *dst0 _AND
+ _CONST char *src0)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *s = dst0;
+
+ while (*dst0++ = *src0++)
+ ;
+
+ return s;
+#else
+ char *dst = dst0;
+ _CONST char *src = src0;
+ long *aligned_dst;
+ _CONST long *aligned_src;
+
+ /* If SRC or DEST is unaligned, then copy bytes. */
+ if (!UNALIGNED (src, dst))
+ {
+ aligned_dst = (long*)dst;
+ aligned_src = (long*)src;
+
+ /* SRC and DEST are both "long int" aligned, try to do "long int"
+ sized copies. */
+ while (!DETECTNULL(*aligned_src))
+ {
+ *aligned_dst++ = *aligned_src++;
+ }
+
+ dst = (char*)aligned_dst;
+ src = (char*)aligned_src;
+ }
+
+ while (*dst++ = *src++)
+ ;
+ return dst0;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/strcspn.c b/newlib/libc/string/strcspn.c
new file mode 100644
index 000000000..fe68b8f51
--- /dev/null
+++ b/newlib/libc/string/strcspn.c
@@ -0,0 +1,54 @@
+/*
+FUNCTION
+ <<strcspn>>---count chars not in string
+
+INDEX
+ strcspn
+
+ANSI_SYNOPSIS
+ size_t strcspn(const char *<[s1]>, const char *<[s2]>);
+
+TRAD_SYNOPSIS
+ size_t strcspn(<[s1]>, <[s2]>)
+ char *<[s1]>;
+ char *<[s2]>;
+
+DESCRIPTION
+ This function computes the length of the initial part of
+ the string pointed to by <[s1]> which consists entirely of
+ characters <[NOT]> from the string pointed to by <[s2]>
+ (excluding the terminating null character).
+
+RETURNS
+ <<strcspn>> returns the length of the substring found.
+
+PORTABILITY
+<<strcspn>> is ANSI C.
+
+<<strcspn>> requires no supporting OS subroutines.
+ */
+
+#include <string.h>
+
+size_t
+_DEFUN (strcspn, (s1, s2),
+ _CONST char *s1 _AND
+ _CONST char *s2)
+{
+ _CONST char *s = s1;
+ _CONST char *c;
+
+ while (*s1)
+ {
+ for (c = s2; *c; c++)
+ {
+ if (*s1 == *c)
+ break;
+ }
+ if (*c)
+ break;
+ s1++;
+ }
+
+ return s1 - s;
+}
diff --git a/newlib/libc/string/strerror.c b/newlib/libc/string/strerror.c
new file mode 100644
index 000000000..78336595d
--- /dev/null
+++ b/newlib/libc/string/strerror.c
@@ -0,0 +1,650 @@
+/***
+**** CAUTION!!! KEEP DOC CONSISTENT---if you change text of a message
+**** here, change two places:
+**** 1) the leading doc section (alphabetized by macro)
+**** 2) the real text inside switch(errnum)
+***/
+
+/*
+FUNCTION
+ <<strerror>>---convert error number to string
+
+INDEX
+ strerror
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strerror(int <[errnum]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strerror(<[errnum]>)
+ int <[errnum]>;
+
+DESCRIPTION
+<<strerror>> converts the error number <[errnum]> into a
+string. The value of <[errnum]> is usually a copy of <<errno>>.
+If <<errnum>> is not a known error number, the result points to an
+empty string.
+
+This implementation of <<strerror>> prints out the following strings
+for each of the values defined in `<<errno.h>>':
+
+o+
+o E2BIG
+Arg list too long
+
+o EACCES
+Permission denied
+
+o EADV
+Advertise error
+
+o EAGAIN
+No more processes
+
+o EBADF
+Bad file number
+
+o EBADMSG
+Bad message
+
+o EBUSY
+Device or resource busy
+
+o ECHILD
+No children
+
+o ECOMM
+Communication error
+
+o EDEADLK
+Deadlock
+
+o EEXIST
+File exists
+
+o EDOM
+Math argument
+
+o EFAULT
+Bad address
+
+o EFBIG
+File too large
+
+o EIDRM
+Identifier removed
+
+o EINTR
+Interrupted system call
+
+o EINVAL
+Invalid argument
+
+o EIO
+I/O error
+
+o EISDIR
+Is a directory
+
+o ELIBACC
+Cannot access a needed shared library
+
+o ELIBBAD
+Accessing a corrupted shared library
+
+o ELIBEXEC
+Cannot exec a shared library directly
+
+o ELIBMAX
+Attempting to link in more shared libraries than system limit
+
+o ELIBSCN
+<<.lib>> section in a.out corrupted
+
+o EMFILE
+Too many open files
+
+o EMLINK
+Too many links
+
+o EMULTIHOP
+Multihop attempted
+
+o ENAMETOOLONG
+File or path name too long
+
+o ENFILE
+Too many open files in system
+
+o ENODEV
+No such device
+
+o ENOENT
+No such file or directory
+
+o ENOEXEC
+Exec format error
+
+o ENOLCK
+No lock
+
+o ENOLINK
+Virtual circuit is gone
+
+o ENOMEM
+Not enough space
+
+o ENOMSG
+No message of desired type
+
+o ENONET
+Machine is not on the network
+
+o ENOPKG
+No package
+
+o ENOSPC
+No space left on device
+
+o ENOSR
+No stream resources
+
+o ENOSTR
+Not a stream
+
+o ENOSYS
+Function not implemented
+
+o ENOTBLK
+Block device required
+
+o ENOTDIR
+Not a directory
+
+o ENOTEMPTY
+Directory not empty
+
+o ENOTTY
+Not a character device
+
+o ENXIO
+No such device or address
+
+o EPERM
+Not owner
+
+o EPIPE
+Broken pipe
+
+o EPROTO
+Protocol error
+
+o ERANGE
+Result too large
+
+o EREMOTE
+Resource is remote
+
+o EROFS
+Read-only file system
+
+o ESPIPE
+Illegal seek
+
+o ESRCH
+No such process
+
+o ESRMNT
+Srmount error
+
+o ETIME
+Stream ioctl timeout
+
+o ETXTBSY
+Text file busy
+
+o EXDEV
+Cross-device link
+
+o-
+
+RETURNS
+This function returns a pointer to a string. Your application must
+not modify that string.
+
+PORTABILITY
+ANSI C requires <<strerror>>, but does not specify the strings used
+for each error number.
+
+Although this implementation of <<strerror>> is reentrant, ANSI C
+declares that subsequent calls to <<strerror>> may overwrite the
+result string; therefore portable code cannot depend on the reentrancy
+of this subroutine.
+
+This implementation of <<strerror>> provides for user-defined
+extensibility. <<errno.h>> defines <[__ELASTERROR]>, which can be
+used as a base for user-defined error values. If the user supplies a
+routine named <<_user_strerror>>, and <[errnum]> passed to
+<<strerror>> does not match any of the supported values,
+<<_user_strerror>> is called with <[errnum]> as its argument.
+
+<<_user_strerror>> takes one argument of type <[int]>, and returns a
+character pointer. If <[errnum]> is unknown to <<_user_strerror>>,
+<<_user_strerror>> returns <[NULL]>. The default <<_user_strerror>>
+returns <[NULL]> for all input values.
+
+<<strerror>> requires no supporting OS subroutines.
+
+QUICKREF
+ strerror ansi pure
+*/
+
+#include <errno.h>
+#include <string.h>
+
+char *
+_DEFUN (strerror, (errnum),
+ int errnum)
+{
+ char *error;
+ extern char *_user_strerror _PARAMS ((int));
+
+ switch (errnum)
+ {
+/* go32 defines EPERM as EACCES */
+#if defined (EPERM) && (!defined (EACCES) || (EPERM != EACCES))
+ case EPERM:
+ error = "Not owner";
+ break;
+#endif
+#ifdef ENOENT
+ case ENOENT:
+ error = "No such file or directory";
+ break;
+#endif
+#ifdef ESRCH
+ case ESRCH:
+ error = "No such process";
+ break;
+#endif
+#ifdef EINTR
+ case EINTR:
+ error = "Interrupted system call";
+ break;
+#endif
+#ifdef EIO
+ case EIO:
+ error = "I/O error";
+ break;
+#endif
+/* go32 defines ENXIO as ENODEV */
+#if defined (ENXIO) && (!defined (ENODEV) || (ENXIO != ENODEV))
+ case ENXIO:
+ error = "No such device or address";
+ break;
+#endif
+#ifdef E2BIG
+ case E2BIG:
+ error = "Arg list too long";
+ break;
+#endif
+#ifdef ENOEXEC
+ case ENOEXEC:
+ error = "Exec format error";
+ break;
+#endif
+#ifdef EBADF
+ case EBADF:
+ error = "Bad file number";
+ break;
+#endif
+#ifdef ECHILD
+ case ECHILD:
+ error = "No children";
+ break;
+#endif
+#ifdef EAGAIN
+ case EAGAIN:
+ error = "No more processes";
+ break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM:
+ error = "Not enough space";
+ break;
+#endif
+#ifdef EACCES
+ case EACCES:
+ error = "Permission denied";
+ break;
+#endif
+#ifdef EFAULT
+ case EFAULT:
+ error = "Bad address";
+ break;
+#endif
+#ifdef ENOTBLK
+ case ENOTBLK:
+ error = "Block device required";
+ break;
+#endif
+#ifdef EBUSY
+ case EBUSY:
+ error = "Device or resource busy";
+ break;
+#endif
+#ifdef EEXIST
+ case EEXIST:
+ error = "File exists";
+ break;
+#endif
+#ifdef EXDEV
+ case EXDEV:
+ error = "Cross-device link";
+ break;
+#endif
+#ifdef ENODEV
+ case ENODEV:
+ error = "No such device";
+ break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR:
+ error = "Not a directory";
+ break;
+#endif
+#ifdef EISDIR
+ case EISDIR:
+ error = "Is a directory";
+ break;
+#endif
+#ifdef EINVAL
+ case EINVAL:
+ error = "Invalid argument";
+ break;
+#endif
+#ifdef ENFILE
+ case ENFILE:
+ error = "Too many open files in system";
+ break;
+#endif
+#ifdef EMFILE
+ case EMFILE:
+ error = "Too many open files";
+ break;
+#endif
+#ifdef ENOTTY
+ case ENOTTY:
+ error = "Not a character device";
+ break;
+#endif
+#ifdef ETXTBSY
+ case ETXTBSY:
+ error = "Text file busy";
+ break;
+#endif
+#ifdef EFBIG
+ case EFBIG:
+ error = "File too large";
+ break;
+#endif
+#ifdef ENOSPC
+ case ENOSPC:
+ error = "No space left on device";
+ break;
+#endif
+#ifdef ESPIPE
+ case ESPIPE:
+ error = "Illegal seek";
+ break;
+#endif
+#ifdef EROFS
+ case EROFS:
+ error = "Read-only file system";
+ break;
+#endif
+#ifdef EMLINK
+ case EMLINK:
+ error = "Too many links";
+ break;
+#endif
+#ifdef EPIPE
+ case EPIPE:
+ error = "Broken pipe";
+ break;
+#endif
+#ifdef EDOM
+ case EDOM:
+ error = "Math argument";
+ break;
+#endif
+#ifdef ERANGE
+ case ERANGE:
+ error = "Result too large";
+ break;
+#endif
+#ifdef ENOMSG
+ case ENOMSG:
+ error = "No message of desired type";
+ break;
+#endif
+#ifdef EIDRM
+ case EIDRM:
+ error = "Identifier removed";
+ break;
+#endif
+#ifdef EDEADLK
+ case EDEADLK:
+ error = "Deadlock";
+ break;
+#endif
+#ifdef ENOLCK
+ case ENOLCK:
+ error = "No lock";
+ break;
+#endif
+#ifdef ENOSTR
+ case ENOSTR:
+ error = "Not a stream";
+ break;
+#endif
+#ifdef ETIME
+ case ETIME:
+ error = "Stream ioctl timeout";
+ break;
+#endif
+#ifdef ENOSR
+ case ENOSR:
+ error = "No stream resources";
+ break;
+#endif
+#ifdef ENONET
+ case ENONET:
+ error = "Machine is not on the network";
+ break;
+#endif
+#ifdef ENOPKG
+ case ENOPKG:
+ error = "No package";
+ break;
+#endif
+#ifdef EREMOTE
+ case EREMOTE:
+ error = "Resource is remote";
+ break;
+#endif
+#ifdef ENOLINK
+ case ENOLINK:
+ error = "Virtual circuit is gone";
+ break;
+#endif
+#ifdef EADV
+ case EADV:
+ error = "Advertise error";
+ break;
+#endif
+#ifdef ESRMNT
+ case ESRMNT:
+ error = "Srmount error";
+ break;
+#endif
+#ifdef ECOMM
+ case ECOMM:
+ error = "Communication error";
+ break;
+#endif
+#ifdef EPROTO
+ case EPROTO:
+ error = "Protocol error";
+ break;
+#endif
+#ifdef EMULTIHOP
+ case EMULTIHOP:
+ error = "Multihop attempted";
+ break;
+#endif
+#ifdef EBADMSG
+ case EBADMSG:
+ error = "Bad message";
+ break;
+#endif
+#ifdef ELIBACC
+ case ELIBACC:
+ error = "Cannot access a needed shared library";
+ break;
+#endif
+#ifdef ELIBBAD
+ case ELIBBAD:
+ error = "Accessing a corrupted shared library";
+ break;
+#endif
+#ifdef ELIBSCN
+ case ELIBSCN:
+ error = ".lib section in a.out corrupted";
+ break;
+#endif
+#ifdef ELIBMAX
+ case ELIBMAX:
+ error = "Attempting to link in more shared libraries than system limit";
+ break;
+#endif
+#ifdef ELIBEXEC
+ case ELIBEXEC:
+ error = "Cannot exec a shared library directly";
+ break;
+#endif
+#ifdef ENOSYS
+ case ENOSYS:
+ error = "Function not implemented";
+ break;
+#endif
+#ifdef ENMFILE
+ case ENMFILE:
+ error = "No more files";
+ break;
+#endif
+#ifdef ENOTEMPTY
+ case ENOTEMPTY:
+ error = "Directory not empty";
+ break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG:
+ error = "File or path name too long";
+ break;
+#endif
+#ifdef ELOOP
+ case ELOOP:
+ error = "Too many symbolic links";
+ break;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS:
+ error = "No buffer space available";
+ break;
+#endif
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT:
+ error = "Address family not supported by protocol family";
+ break;
+#endif
+#ifdef EPROTOTYPE
+ case EPROTOTYPE:
+ error = "Protocol wrong type for socket";
+ break;
+#endif
+#ifdef ENOTSOCK
+ case ENOTSOCK:
+ error = "Socket operation on non-socket";
+ break;
+#endif
+#ifdef ENOPROTOOPT
+ case ENOPROTOOPT:
+ error = "Protocol not available";
+ break;
+#endif
+#ifdef ESHUTDOWN
+ case ESHUTDOWN:
+ error = "Can't send after socket shutdown";
+ break;
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED:
+ error = "Connection refused";
+ break;
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE:
+ error = "Address already in use";
+ break;
+#endif
+#ifdef ECONNABORTED
+ case ECONNABORTED:
+ error = "Software caused connection abort";
+ break;
+#endif
+#if (defined(EWOULDBLOCK) && (!defined (EAGAIN) || (EWOULDBLOCK != EAGAIN)))
+ case EWOULDBLOCK:
+ error = "Operation would block";
+ break;
+#endif
+#ifdef ENOTCONN
+ case ENOTCONN:
+ error = "Socket is not connected";
+ break;
+#endif
+#ifdef ESOCKTNOSUPPORT
+ case ESOCKTNOSUPPORT:
+ error = "Socket type not supported";
+ break;
+#endif
+#ifdef EISCONN
+ case EISCONN:
+ error = "Socket is already connected";
+ break;
+#endif
+#ifdef EOPNOTSUPP
+ case EOPNOTSUPP:
+ error = "Operation not supported on socket";
+ break;
+#endif
+#ifdef EMSGSIZE
+ case EMSGSIZE:
+ error = "Message too long";
+ break;
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT:
+ error = "Connection timed out";
+ break;
+#endif
+ default:
+ if ((error = _user_strerror (errnum)) == 0)
+ error = "";
+ break;
+ }
+
+ return error;
+}
diff --git a/newlib/libc/string/strings.tex b/newlib/libc/string/strings.tex
new file mode 100644
index 000000000..2d17d1c6f
--- /dev/null
+++ b/newlib/libc/string/strings.tex
@@ -0,0 +1,133 @@
+@node Strings
+@chapter Strings and Memory (@file{string.h})
+
+This chapter describes string-handling functions and functions for
+managing areas of memory. The corresponding declarations are in
+@file{string.h}.
+
+@menu
+* bcmp:: Compare two memory areas
+* bcopy:: Copy memory regions
+* bzero:: Initialize memory to zero
+* index:: Search for character in string
+* memchr:: Find character in memory
+* memcmp:: Compare two memory areas
+* memcpy:: Copy memory regions
+* memmove:: Move possibly overlapping memory
+* memset:: Set an area of memory
+* rindex:: Reverse search for character in string
+* strcasecmp:: Compare strings ignoring case
+* strcat:: Concatenate strings
+* strchr:: Search for character in string
+* strcmp:: Character string compare
+* strcoll:: Locale specific character string compare
+* strcpy:: Copy string
+* strcspn:: Count chars not in string
+* strerror:: Convert error number to string
+* strlen:: Character string length
+* strlwr:: Convert string to lower case
+* strncasecmp:: Compare strings ignoring case
+* strncat:: Concatenate strings
+* strncmp:: Character string compare
+* strncpy:: Counted copy string
+* strpbrk:: Find chars in string
+* strrchr:: Reverse search for character in string
+* strspn:: Find initial match
+* strstr:: Find string segment
+* strtok:: Get next token from a string
+* strupr:: Convert string to upper case
+* strxfrm:: Transform string
+@end menu
+
+@page
+@include string/bcmp.def
+
+@page
+@include string/bcopy.def
+
+@page
+@include string/bzero.def
+
+@page
+@include string/index.def
+
+@page
+@include string/memchr.def
+
+@page
+@include string/memcmp.def
+
+@page
+@include string/memcpy.def
+
+@page
+@include string/memmove.def
+
+@page
+@include string/memset.def
+
+@page
+@include string/rindex.def
+
+@page
+@include string/strcasecmp.def
+
+@page
+@include string/strcat.def
+
+@page
+@include string/strchr.def
+
+@page
+@include string/strcmp.def
+
+@page
+@include string/strcoll.def
+
+@page
+@include string/strcpy.def
+
+@page
+@include string/strcspn.def
+
+@page
+@include string/strerror.def
+
+@page
+@include string/strlen.def
+
+@page
+@include string/strlwr.def
+
+@page
+@include string/strncasecmp.def
+
+@page
+@include string/strncat.def
+
+@page
+@include string/strncmp.def
+
+@page
+@include string/strncpy.def
+
+@page
+@include string/strpbrk.def
+
+@page
+@include string/strrchr.def
+
+@page
+@include string/strspn.def
+
+@page
+@include string/strstr.def
+
+@page
+@include string/strtok.def
+
+@page
+@include string/strupr.def
+
+@page
+@include string/strxfrm.def
diff --git a/newlib/libc/string/strlen.c b/newlib/libc/string/strlen.c
new file mode 100644
index 000000000..4249e14c7
--- /dev/null
+++ b/newlib/libc/string/strlen.c
@@ -0,0 +1,88 @@
+/*
+FUNCTION
+ <<strlen>>---character string length
+
+INDEX
+ strlen
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ size_t strlen(const char *<[str]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ size_t strlen(<[str]>)
+ char *<[src]>;
+
+DESCRIPTION
+ The <<strlen>> function works out the length of the string
+ starting at <<*<[str]>>> by counting chararacters until it
+ reaches a <<NULL>> character.
+
+RETURNS
+ <<strlen>> returns the character count.
+
+PORTABILITY
+<<strlen>> is ANSI C.
+
+<<strlen>> requires no supporting OS subroutines.
+
+QUICKREF
+ strlen ansi pure
+*/
+
+#include <_ansi.h>
+#include <string.h>
+#include <limits.h>
+
+#define LBLOCKSIZE (sizeof (long))
+#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
+
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+/* Nonzero if X (a long int) contains a NULL byte. */
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+#ifndef DETECTNULL
+#error long int is not a 32bit or 64bit byte
+#endif
+
+size_t
+_DEFUN (strlen, (str),
+ _CONST char *str)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ _CONST char *start = str;
+
+ while (*str)
+ str++;
+
+ return str - start;
+#else
+ _CONST char *start = str;
+ unsigned long *aligned_addr;
+
+ if (!UNALIGNED (str))
+ {
+ /* If the string is word-aligned, we can check for the presence of
+ a null in each word-sized block. */
+ aligned_addr = (unsigned long*)str;
+ while (!DETECTNULL (*aligned_addr))
+ aligned_addr++;
+
+ /* Once a null is detected, we check each byte in that block for a
+ precise position of the null. */
+ str = (char*)aligned_addr;
+ }
+
+ while (*str)
+ str++;
+ return str - start;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/strlwr.c b/newlib/libc/string/strlwr.c
new file mode 100644
index 000000000..cf0d45f71
--- /dev/null
+++ b/newlib/libc/string/strlwr.c
@@ -0,0 +1,50 @@
+/*
+FUNCTION
+ <<strlwr>>---force string to lower case
+
+INDEX
+ strlwr
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strlwr(char *<[a]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strlwr(<[a]>)
+ char *<[a]>;
+
+DESCRIPTION
+ <<strlwr>> converts each characters in the string at <[a]> to
+ lower case.
+
+RETURNS
+ <<strlwr>> returns its argument, <[a]>.
+
+PORTABILITY
+<<strlwr>> is not widely portable.
+
+<<strlwr>> requires no supporting OS subroutines.
+
+QUICKREF
+ strlwr
+*/
+
+#include <string.h>
+#include <ctype.h>
+
+char *
+strlwr (a)
+ char *a;
+{
+ char *ret = a;
+
+ while (*a != '\0')
+ {
+ if (isupper (*a))
+ *a = tolower (*a);
+ ++a;
+ }
+
+ return ret;
+}
diff --git a/newlib/libc/string/strncasecmp.c b/newlib/libc/string/strncasecmp.c
new file mode 100644
index 000000000..28c6cc44f
--- /dev/null
+++ b/newlib/libc/string/strncasecmp.c
@@ -0,0 +1,64 @@
+/*
+FUNCTION
+ <<strncasecmp>>---case insensitive character string compare
+
+INDEX
+ strncasecmp
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ int strncasecmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ int strncasecmp(<[a]>, <[b]>, <[length]>)
+ char *<[a]>;
+ char *<[b]>;
+ size_t <[length]>
+
+DESCRIPTION
+ <<strncasecmp>> compares up to <[length]> characters
+ from the string at <[a]> to the string at <[b]> in a
+ case-insensitive manner.
+
+RETURNS
+
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
+ both are converted to upper case), <<strncasecmp>> returns a
+ number greater than zero. If the two strings are equivalent,
+ <<strncasecmp>> returns zero. If <<*<[a]>>> sorts
+ lexicographically before <<*<[b]>>>, <<strncasecmp>> returns a
+ number less than zero.
+
+PORTABILITY
+<<strncasecmp>> is in the Berkeley Software Distribution.
+
+<<strncasecmp>> requires no supporting OS subroutines. It uses
+tolower() from elsewhere in this library.
+
+QUICKREF
+ strncasecmp
+*/
+
+#include <string.h>
+#include <ctype.h>
+
+int
+_DEFUN (strncasecmp, (s1, s2, n),
+ _CONST char *s1 _AND
+ _CONST char *s2 _AND
+ size_t n)
+{
+ if (n == 0)
+ return 0;
+
+ while (n-- != 0 && tolower(*s1) == tolower(*s2))
+ {
+ if (n == 0 || *s1 == '\0' || *s2 == '\0')
+ break;
+ s1++;
+ s2++;
+ }
+
+ return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
+}
diff --git a/newlib/libc/string/strncat.c b/newlib/libc/string/strncat.c
new file mode 100644
index 000000000..57ca068eb
--- /dev/null
+++ b/newlib/libc/string/strncat.c
@@ -0,0 +1,115 @@
+/*
+FUNCTION
+ <<strncat>>---concatenate strings
+
+INDEX
+ strncat
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strncat(char *<[dst]>, const char *<[src]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strncat(<[dst]>, <[src]>, <[length]>)
+ char *<[dst]>;
+ char *<[src]>;
+ size_t <[length]>;
+
+DESCRIPTION
+ <<strncat>> appends not more than <[length]> characters from
+ the string pointed to by <[src]> (including the terminating
+ null character) to the end of the string pointed to by
+ <[dst]>. The initial character of <[src]> overwrites the null
+ character at the end of <[dst]>. A terminating null character
+ is always appended to the result
+
+WARNINGS
+ Note that a null is always appended, so that if the copy is
+ limited by the <[length]> argument, the number of characters
+ appended to <[dst]> is <<n + 1>>.
+
+
+RETURNS
+ This function returns the initial value of <[dst]>
+
+PORTABILITY
+<<strncat>> is ANSI C.
+
+<<strncat>> requires no supporting OS subroutines.
+
+QUICKREF
+ strncat ansi pure
+*/
+
+#include <string.h>
+#include <limits.h>
+
+/* Nonzero if X is aligned on a "long" boundary. */
+#define ALIGNED(X) \
+ (((long)X & (sizeof (long) - 1)) == 0)
+
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+/* Nonzero if X (a long int) contains a NULL byte. */
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+#ifndef DETECTNULL
+#error long int is not a 32bit or 64bit byte
+#endif
+
+char *
+_DEFUN (strncat, (s1, s2, n),
+ char *s1 _AND
+ _CONST char *s2 _AND
+ size_t n)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *s = s1;
+
+ while (*s1)
+ s1++;
+ while (n-- != 0 && (*s1++ = *s2++))
+ {
+ if (n == 0)
+ *s1 = '\0';
+ }
+
+ return s;
+#else
+ char *s = s1;
+
+ /* Skip over the data in s1 as quickly as possible. */
+ if (ALIGNED (s1))
+ {
+ unsigned long *aligned_s1 = (unsigned long *)s1;
+ while (!DETECTNULL (*aligned_s1))
+ aligned_s1++;
+
+ s1 = (char *)aligned_s1;
+ }
+
+ while (*s1)
+ s1++;
+
+ /* s1 now points to the its trailing null character, now copy
+ up to N bytes from S2 into S1 stopping if a NULL is encountered
+ in S2.
+
+ It is not safe to use strncpy here since it copies EXACTLY N
+ characters, NULL padding if necessary. */
+ while (n-- != 0 && (*s1++ = *s2++))
+ {
+ if (n == 0)
+ *s1 = '\0';
+ }
+
+ return s;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/strncmp.c b/newlib/libc/string/strncmp.c
new file mode 100644
index 000000000..9801b7d92
--- /dev/null
+++ b/newlib/libc/string/strncmp.c
@@ -0,0 +1,122 @@
+/*
+FUNCTION
+ <<strncmp>>---character string compare
+
+INDEX
+ strncmp
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ int strncmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ int strncmp(<[a]>, <[b]>, <[length]>)
+ char *<[a]>;
+ char *<[b]>;
+ size_t <[length]>
+
+DESCRIPTION
+ <<strncmp>> compares up to <[length]> characters
+ from the string at <[a]> to the string at <[b]>.
+
+RETURNS
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
+ <<strncmp>> returns a number greater than zero. If the two
+ strings are equivalent, <<strncmp>> returns zero. If <<*<[a]>>>
+ sorts lexicographically before <<*<[b]>>>, <<strncmp>> returns a
+ number less than zero.
+
+PORTABILITY
+<<strncmp>> is ANSI C.
+
+<<strncmp>> requires no supporting OS subroutines.
+
+QUICKREF
+ strncmp ansi pure
+*/
+
+#include <string.h>
+#include <limits.h>
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+#ifndef DETECTNULL
+#error long int is not a 32bit or 64bit byte
+#endif
+
+int
+_DEFUN (strncmp, (s1, s2, n),
+ _CONST char *s1 _AND
+ _CONST char *s2 _AND
+ size_t n)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ if (n == 0)
+ return 0;
+
+ while (n-- != 0 && *s1 == *s2)
+ {
+ if (n == 0 || *s1 == '\0')
+ break;
+ s1++;
+ s2++;
+ }
+
+ return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+#else
+ unsigned long *a1;
+ unsigned long *a2;
+
+ if (n == 0)
+ return 0;
+
+ /* If s1 or s2 are unaligned, then compare bytes. */
+ if (!UNALIGNED (s1, s2))
+ {
+ /* If s1 and s2 are word-aligned, compare them a word at a time. */
+ a1 = (unsigned long*)s1;
+ a2 = (unsigned long*)s2;
+ while (n >= sizeof (long) && *a1 == *a2)
+ {
+ n -= sizeof (long);
+
+ /* If we've run out of bytes or hit a null, return zero
+ since we already know *a1 == *a2. */
+ if (n == 0 || DETECTNULL (*a1))
+ return 0;
+
+ a1++;
+ a2++;
+ }
+
+ /* A difference was detected in last few bytes of s1, so search bytewise */
+ s1 = (char*)a1;
+ s2 = (char*)a2;
+ }
+
+ while (n-- > 0 && *s1 == *s2)
+ {
+ /* If we've run out of bytes or hit a null, return zero
+ since we already know *s1 == *s2. */
+ if (n == 0 || *s1 == '\0')
+ return 0;
+ s1++;
+ s2++;
+ }
+ return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/strncpy.c b/newlib/libc/string/strncpy.c
new file mode 100644
index 000000000..7c1973ba6
--- /dev/null
+++ b/newlib/libc/string/strncpy.c
@@ -0,0 +1,125 @@
+/*
+FUNCTION
+ <<strncpy>>---counted copy string
+
+INDEX
+ strncpy
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strncpy(char *<[dst]>, const char *<[src]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strncpy(<[dst]>, <[src]>, <[length]>)
+ char *<[dst]>;
+ char *<[src]>;
+ size_t <[length]>;
+
+DESCRIPTION
+ <<strncpy>> copies not more than <[length]> characters from the
+ the string pointed to by <[src]> (including the terminating
+ null character) to the array pointed to by <[dst]>. If the
+ string pointed to by <[src]> is shorter than <[length]>
+ characters, null characters are appended to the destination
+ array until a total of <[length]> characters have been
+ written.
+
+RETURNS
+ This function returns the initial value of <[dst]>.
+
+PORTABILITY
+<<strncpy>> is ANSI C.
+
+<<strncpy>> requires no supporting OS subroutines.
+
+QUICKREF
+ strncpy ansi pure
+*/
+
+#include <string.h>
+#include <limits.h>
+
+/*SUPPRESS 560*/
+/*SUPPRESS 530*/
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+/* Nonzero if X (a long int) contains a NULL byte. */
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+#ifndef DETECTNULL
+#error long int is not a 32bit or 64bit byte
+#endif
+
+#define TOO_SMALL(LEN) ((LEN) < sizeof (long))
+
+char *
+_DEFUN (strncpy, (dst0, src0),
+ char *dst0 _AND
+ _CONST char *src0 _AND
+ size_t count)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *dscan;
+ _CONST char *sscan;
+
+ dscan = dst0;
+ sscan = src0;
+ while (count > 0)
+ {
+ --count;
+ if ((*dscan++ = *sscan++) == '\0')
+ break;
+ }
+ while (count-- > 0)
+ *dscan++ = '\0';
+
+ return dst0;
+#else
+ char *dst = dst0;
+ _CONST char *src = src0;
+ long *aligned_dst;
+ _CONST long *aligned_src;
+
+ /* If SRC and DEST is aligned and count large enough, then copy words. */
+ if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
+ {
+ aligned_dst = (long*)dst;
+ aligned_src = (long*)src;
+
+ /* SRC and DEST are both "long int" aligned, try to do "long int"
+ sized copies. */
+ while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
+ {
+ count -= sizeof (long int);
+ *aligned_dst++ = *aligned_src++;
+ }
+
+ dst = (char*)aligned_dst;
+ src = (char*)aligned_src;
+ }
+
+ while (count > 0)
+ {
+ --count;
+ if ((*dst++ = *src++) == '\0')
+ break;
+ }
+
+ while (count-- > 0)
+ *dst++ = '\0';
+
+ return dst0;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/strpbrk.c b/newlib/libc/string/strpbrk.c
new file mode 100644
index 000000000..e7f2dd2b6
--- /dev/null
+++ b/newlib/libc/string/strpbrk.c
@@ -0,0 +1,58 @@
+/*
+FUNCTION
+ <<strpbrk>>---find chars in string
+
+INDEX
+ strpbrk
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strpbrk(const char *<[s1]>, const char *<[s2]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strpbrk(<[s1]>, <[s2]>)
+ char *<[s1]>;
+ char *<[s2]>;
+
+DESCRIPTION
+ This function locates the first occurence in the string
+ pointed to by <[s1]> of any character in string pointed to by
+ <[s2]> (excluding the terminating null character).
+
+RETURNS
+ <<strpbrk>> returns a pointer to the character found in <[s1]>, or a
+ null pointer if no character from <[s2]> occurs in <[s1]>.
+
+PORTABILITY
+<<strpbrk>> requires no supporting OS subroutines.
+*/
+
+#include <string.h>
+
+char *
+_DEFUN (strpbrk, (s1, s2),
+ _CONST char *s1 _AND
+ _CONST char *s2)
+{
+ _CONST char *c = s2;
+ if (!*s1)
+ return (char *) NULL;
+
+ while (*s1)
+ {
+ for (c = s2; *c; c++)
+ {
+ if (*s1 == *c)
+ break;
+ }
+ if (*c)
+ break;
+ s1++;
+ }
+
+ if (*c == '\0')
+ s1 = NULL;
+
+ return (char *) s1;
+}
diff --git a/newlib/libc/string/strrchr.c b/newlib/libc/string/strrchr.c
new file mode 100644
index 000000000..65160f55e
--- /dev/null
+++ b/newlib/libc/string/strrchr.c
@@ -0,0 +1,61 @@
+/*
+FUNCTION
+ <<strrchr>>---reverse search for character in string
+
+INDEX
+ strrchr
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char * strrchr(const char *<[string]>, int <[c]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char * strrchr(<[string]>, <[c]>);
+ char *<[string]>;
+ int *<[c]>;
+
+DESCRIPTION
+ This function finds the last occurence of <[c]> (converted to
+ a char) in the string pointed to by <[string]> (including the
+ terminating null character).
+
+RETURNS
+ Returns a pointer to the located character, or a null pointer
+ if <[c]> does not occur in <[string]>.
+
+PORTABILITY
+<<strrchr>> is ANSI C.
+
+<<strrchr>> requires no supporting OS subroutines.
+
+QUICKREF
+ strrchr ansi pure
+*/
+
+#include <string.h>
+
+char *
+_DEFUN (strrchr, (s, i),
+ _CONST char *s _AND
+ int i)
+{
+ _CONST char *last = NULL;
+ char c = i;
+
+ while (*s)
+ {
+ if (*s == c)
+ {
+ last = s;
+ }
+ s++;
+ }
+
+ if (*s == c)
+ {
+ last = s;
+ }
+
+ return (char *) last;
+}
diff --git a/newlib/libc/string/strspn.c b/newlib/libc/string/strspn.c
new file mode 100644
index 000000000..32b921b10
--- /dev/null
+++ b/newlib/libc/string/strspn.c
@@ -0,0 +1,59 @@
+/*
+FUNCTION
+ <<strspn>>---find initial match
+
+INDEX
+ strspn
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ size_t strspn(const char *<[s1]>, const char *<[s2]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ size_t strspn(<[s1]>, <[s2]>)
+ char *<[s1]>;
+ char *<[s2]>;
+
+DESCRIPTION
+ This function computes the length of the initial segment of
+ the string pointed to by <[s1]> which consists entirely of
+ characters from the string pointed to by <[s2]> (excluding the
+ terminating null character).
+
+RETURNS
+ <<strspn>> returns the length of the segment found.
+
+PORTABILITY
+<<strspn>> is ANSI C.
+
+<<strspn>> requires no supporting OS subroutines.
+
+QUICKREF
+ strspn ansi pure
+*/
+
+#include <string.h>
+
+size_t
+_DEFUN (strspn, (s1, s2),
+ _CONST char *s1 _AND
+ _CONST char *s2)
+{
+ _CONST char *s = s1;
+ _CONST char *c;
+
+ while (*s1)
+ {
+ for (c = s2; *c; c++)
+ {
+ if (*s1 == *c)
+ break;
+ }
+ if (*c == '\0')
+ break;
+ s1++;
+ }
+
+ return s1 - s;
+}
diff --git a/newlib/libc/string/strstr.c b/newlib/libc/string/strstr.c
new file mode 100644
index 000000000..dddced3b2
--- /dev/null
+++ b/newlib/libc/string/strstr.c
@@ -0,0 +1,73 @@
+/*
+FUNCTION
+ <<strstr>>---find string segment
+
+INDEX
+ strstr
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strstr(const char *<[s1]>, const char *<[s2]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strstr(<[s1]>, <[s2]>)
+ char *<[s1]>;
+ char *<[s2]>;
+
+DESCRIPTION
+ Locates the first occurence in the string pointed to by <[s1]> of
+ the sequence of characters in the string pointed to by <[s2]>
+ (excluding the terminating null character).
+
+RETURNS
+ Returns a pointer to the located string segment, or a null
+ pointer if the string <[s2]> is not found. If <[s2]> points to
+ a string with zero length, the <[s1]> is returned.
+
+PORTABILITY
+<<strstr>> is ANSI C.
+
+<<strstr>> requires no supporting OS subroutines.
+
+QUICKREF
+ strstr ansi pure
+*/
+
+#include <string.h>
+
+char *
+_DEFUN (strstr, (searchee, lookfor),
+ _CONST char *searchee _AND
+ _CONST char *lookfor)
+{
+ if (*searchee == 0)
+ {
+ if (*lookfor)
+ return (char *) NULL;
+ return (char *) searchee;
+ }
+
+ while (*searchee)
+ {
+ size_t i;
+ i = 0;
+
+ while (1)
+ {
+ if (lookfor[i] == 0)
+ {
+ return (char *) searchee;
+ }
+
+ if (lookfor[i] != searchee[i])
+ {
+ break;
+ }
+ i++;
+ }
+ searchee++;
+ }
+
+ return (char *) NULL;
+}
diff --git a/newlib/libc/string/strtok.c b/newlib/libc/string/strtok.c
new file mode 100644
index 000000000..bc11f0df7
--- /dev/null
+++ b/newlib/libc/string/strtok.c
@@ -0,0 +1,76 @@
+/*
+FUNCTION
+ <<strtok>>---get next token from a string
+
+INDEX
+ strtok
+
+INDEX
+ strtok_r
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strtok(char *<[source]>, const char *<[delimiters]>)
+ char *strtok_r(char *<[source]>, const char *<[delimiters]>,
+ char **<[lasts]>)
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strtok(<[source]>, <[delimiters]>)
+ char *<[source]>;
+ char *<[delimiters]>;
+
+ char *strtok_r(<[source]>, <[delimiters]>, <[lasts]>)
+ char *<[source]>;
+ char *<[delimiters]>;
+ char **<[lasts]>;
+
+DESCRIPTION
+ The <<strtok>> function is used to isolate sequential tokens in a
+ null-terminated string, <<*<[source]>>>. These tokens are delimited
+ in the string by at least one of the characters in <<*<[delimiters]>>>.
+ The first time that <<strtok>> is called, <<*<[source]>>> should be
+ specified; subsequent calls, wishing to obtain further tokens from
+ the same string, should pass a null pointer instead. The separator
+ string, <<*<[delimiters]>>>, must be supplied each time, and may
+ change between calls.
+
+ The <<strtok>> function returns a pointer to the beginning of each
+ subsequent token in the string, after replacing the separator
+ character itself with a NUL character. When no more tokens remain,
+ a null pointer is returned.
+
+ The <<strtok_r>> function has the same behavior as <<strtok>>, except
+ a pointer to placeholder <<*[lasts]>> must be supplied by the caller.
+
+RETURNS
+ <<strtok>> returns a pointer to the next token, or <<NULL>> if
+ no more tokens can be found.
+
+NOTES
+ <<strtok>> is unsafe for multi-thread applications. <<strtok_r>>
+ is MT-Safe and should be used instead.
+
+PORTABILITY
+<<strtok>> is ANSI C.
+
+<<strtok>> requires no supporting OS subroutines.
+
+QUICKREF
+ strtok ansi impure
+*/
+
+#include <string.h>
+#include <_ansi.h>
+#include <reent.h>
+
+#ifndef _REENT_ONLY
+
+char *
+_DEFUN (strtok, (s, delim),
+ register char *s _AND
+ register const char *delim)
+{
+ return strtok_r (s, delim, &(_REENT->_new._reent._strtok_last));
+}
+#endif
diff --git a/newlib/libc/string/strtok_r.c b/newlib/libc/string/strtok_r.c
new file mode 100644
index 000000000..ed323369e
--- /dev/null
+++ b/newlib/libc/string/strtok_r.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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 <string.h>
+
+char *
+_DEFUN (strtok_r, (s, delim, lasts),
+ register char *s _AND
+ register const char *delim _AND
+ char **lasts)
+{
+ register char *spanp;
+ register int c, sc;
+ char *tok;
+
+
+ if (s == NULL && (s = *lasts) == NULL)
+ return (NULL);
+
+ /*
+ * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+ */
+cont:
+ c = *s++;
+ for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+ if (c == sc)
+ goto cont;
+ }
+
+ if (c == 0) { /* no non-delimiter characters */
+ *lasts = NULL;
+ return (NULL);
+ }
+ tok = s - 1;
+
+ /*
+ * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+ * Note that delim must have one NUL; we stop if we see that, too.
+ */
+ for (;;) {
+ c = *s++;
+ spanp = (char *)delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *lasts = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
diff --git a/newlib/libc/string/strupr.c b/newlib/libc/string/strupr.c
new file mode 100644
index 000000000..d7f7c129d
--- /dev/null
+++ b/newlib/libc/string/strupr.c
@@ -0,0 +1,49 @@
+/*
+FUNCTION
+ <<strupr>>---force string to uppercase
+
+INDEX
+ strupr
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ char *strupr(char *<[a]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ char *strupr(<[a]>)
+ char *<[a]>;
+
+DESCRIPTION
+ <<strupr>> converts each characters in the string at <[a]> to
+ upper case.
+
+RETURNS
+ <<strupr>> returns its argument, <[a]>.
+
+PORTABILITY
+<<strupr>> is not widely portable.
+
+<<strupr>> requires no supporting OS subroutines.
+
+QUICKREF
+ strupr */
+
+#include <string.h>
+#include <ctype.h>
+
+char *
+strupr (a)
+ char *a;
+{
+ char *ret = a;
+
+ while (*a != '\0')
+ {
+ if (islower (*a))
+ *a = toupper (*a);
+ ++a;
+ }
+
+ return ret;
+}
diff --git a/newlib/libc/string/strxfrm.c b/newlib/libc/string/strxfrm.c
new file mode 100644
index 000000000..65ed4f1b1
--- /dev/null
+++ b/newlib/libc/string/strxfrm.c
@@ -0,0 +1,75 @@
+/*
+FUNCTION
+ <<strxfrm>>---transform string
+
+INDEX
+ strxfrm
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ size_t strxfrm(char *<[s1]>, const char *<[s2]>, size_t <[n]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ size_t strxfrm(<[s1]>, <[s2]>, <[n]>);
+ char *<[s1]>;
+ char *<[s2]>;
+ size_t <[n]>;
+
+DESCRIPTION
+ This function transforms the string pointed to by <[s2]> and
+ places the resulting string into the array pointed to by
+ <[s1]>. The transformation is such that if the <<strcmp>>
+ function is applied to the two transformed strings, it returns
+ a value greater than, equal to, or less than zero,
+ correspoinding to the result of a <<strcoll>> function applied
+ to the same two original strings.
+
+ No more than <[n]> characters are placed into the resulting
+ array pointed to by <[s1]>, including the terminating null
+ character. If <[n]> is zero, <[s1]> may be a null pointer. If
+ copying takes place between objects that overlap, the behavior
+ is undefined.
+
+ With a C locale, this function just copies.
+
+RETURNS
+ The <<strxfrm>> function returns the length of the transformed string
+ (not including the terminating null character). If the value returned
+ is <[n]> or more, the contents of the array pointed to by
+ <[s1]> are indeterminate.
+
+PORTABILITY
+<<strxfrm>> is ANSI C.
+
+<<strxfrm>> requires no supporting OS subroutines.
+
+QUICKREF
+ strxfrm ansi pure
+*/
+
+#include <string.h>
+
+size_t
+_DEFUN (strxfrm, (s1, s2, n),
+ char *s1 _AND
+ _CONST char *s2 _AND
+ size_t n)
+{
+ size_t res;
+ res = 0;
+ while (n-- > 0)
+ {
+ if ((*s1++ = *s2++) != '\0')
+ ++res;
+ else
+ return res;
+ }
+ while (*s2)
+ {
+ ++s2;
+ ++res;
+ }
+
+ return res;
+}
diff --git a/newlib/libc/string/u_strerr.c b/newlib/libc/string/u_strerr.c
new file mode 100644
index 000000000..fa4605c8b
--- /dev/null
+++ b/newlib/libc/string/u_strerr.c
@@ -0,0 +1,8 @@
+#include <_ansi.h>
+
+char *
+_DEFUN(_user_strerror, (errnum),
+ int errnum)
+{
+ return 0;
+}