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:
authorJeff Johnston <jjohnstn@redhat.com>2002-07-24 01:38:00 +0400
committerJeff Johnston <jjohnstn@redhat.com>2002-07-24 01:38:00 +0400
commitd254189b38bb5b0b77a18a401c05c415ce0733c9 (patch)
tree7a0a2dfa9e20a356bc0ba94eb20a26bef0c353d1 /newlib/libc/string
parent5e50e4e45c1f8758d431a6d881cd3da5572e8de7 (diff)
2002-07-23 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/string.h: Add mempcpy, strndup, and _strndup_r prototypes. * libc/stdlib/Makefile.am: Remove strdup.c and strdup_r.c. * libc/stdlib/Makefile.in: Regenerated. * libc/stdlib/strdup.c: Removed. * libc/stdlib/strdup_r.c: Removed. * libc/string/Makefile.am: Add strdup.c, strdup_r.c, memccpy.c, mempcpy.c, strndup.c, and strndup_r.c. * libc/string/Makefile.in: Regenerated. * libc/string/memccpy.c: New file. * libc/string/mempcpy.c: Ditto. * libc/string/strndup.c: Ditto. * libc/string/strndup_r.c: Ditto. * libc/string/strdup.c: New file moved from stdlib. * libc/string/strdup_r.c: Ditto. * libc/string/strings.tex: Add memccpy and mempcpy documentation.
Diffstat (limited to 'newlib/libc/string')
-rw-r--r--newlib/libc/string/Makefile.am9
-rw-r--r--newlib/libc/string/Makefile.in37
-rw-r--r--newlib/libc/string/memccpy.c145
-rw-r--r--newlib/libc/string/mempcpy.c108
-rw-r--r--newlib/libc/string/strdup.c13
-rw-r--r--newlib/libc/string/strdup_r.c17
-rw-r--r--newlib/libc/string/strings.tex8
-rw-r--r--newlib/libc/string/strndup.c16
-rw-r--r--newlib/libc/string/strndup_r.c21
9 files changed, 360 insertions, 14 deletions
diff --git a/newlib/libc/string/Makefile.am b/newlib/libc/string/Makefile.am
index f90fed168..525534e07 100644
--- a/newlib/libc/string/Makefile.am
+++ b/newlib/libc/string/Makefile.am
@@ -9,10 +9,12 @@ LIB_SOURCES = \
bcopy.c \
bzero.c \
index.c \
+ memccpy.c \
memchr.c \
memcmp.c \
memcpy.c \
memmove.c \
+ mempcpy.c \
memset.c \
rindex.c \
strcat.c \
@@ -22,6 +24,8 @@ LIB_SOURCES = \
strcoll.c \
strcpy.c \
strcspn.c \
+ strdup.c \
+ strdup_r.c \
strerror.c \
strerror_r.c \
strlcat.c \
@@ -32,6 +36,8 @@ LIB_SOURCES = \
strncmp.c \
strncasecmp.c \
strncpy.c \
+ strndup.c \
+ strndup_r.c \
strnlen.c \
strpbrk.c \
strrchr.c \
@@ -66,7 +72,8 @@ bzero.def memset.def strcpy.def strncpy.def strxfrm.def \
index.def rindex.def strcspn.def strpbrk.def swab.def \
memchr.def strcat.def strerror.def strerror_r.def strrchr.def \
memcmp.def strchr.def strlen.def strnlen.def strspn.def \
-strcasecmp.def strncasecmp.def strlwr.def strupr.def
+strcasecmp.def strncasecmp.def strlwr.def strupr.def memccpy.def \
+mempcpy.def
SUFFIXES = .def
diff --git a/newlib/libc/string/Makefile.in b/newlib/libc/string/Makefile.in
index 32073c400..f93e20d46 100644
--- a/newlib/libc/string/Makefile.in
+++ b/newlib/libc/string/Makefile.in
@@ -115,10 +115,12 @@ LIB_SOURCES = \
bcopy.c \
bzero.c \
index.c \
+ memccpy.c \
memchr.c \
memcmp.c \
memcpy.c \
memmove.c \
+ mempcpy.c \
memset.c \
rindex.c \
strcat.c \
@@ -128,6 +130,8 @@ LIB_SOURCES = \
strcoll.c \
strcpy.c \
strcspn.c \
+ strdup.c \
+ strdup_r.c \
strerror.c \
strerror_r.c \
strlcat.c \
@@ -138,6 +142,8 @@ LIB_SOURCES = \
strncmp.c \
strncasecmp.c \
strncpy.c \
+ strndup.c \
+ strndup_r.c \
strnlen.c \
strpbrk.c \
strrchr.c \
@@ -168,7 +174,8 @@ bzero.def memset.def strcpy.def strncpy.def strxfrm.def \
index.def rindex.def strcspn.def strpbrk.def swab.def \
memchr.def strcat.def strerror.def strerror_r.def strrchr.def \
memcmp.def strchr.def strlen.def strnlen.def strspn.def \
-strcasecmp.def strncasecmp.def strlwr.def strupr.def
+strcasecmp.def strncasecmp.def strlwr.def strupr.def memccpy.def \
+mempcpy.def
SUFFIXES = .def
@@ -188,16 +195,18 @@ CPPFLAGS = @CPPFLAGS@
LIBS = @LIBS@
lib_a_LIBADD =
@USE_LIBTOOL_FALSE@lib_a_OBJECTS = bcmp.$(OBJEXT) bcopy.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@bzero.$(OBJEXT) index.$(OBJEXT) memchr.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@memcmp.$(OBJEXT) memcpy.$(OBJEXT) memmove.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@memset.$(OBJEXT) rindex.$(OBJEXT) strcat.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@strchr.$(OBJEXT) strcmp.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@strcasecmp.$(OBJEXT) strcoll.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@strcpy.$(OBJEXT) strcspn.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@bzero.$(OBJEXT) index.$(OBJEXT) memccpy.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@memchr.$(OBJEXT) memcmp.$(OBJEXT) memcpy.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@memmove.$(OBJEXT) mempcpy.$(OBJEXT) memset.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@rindex.$(OBJEXT) strcat.$(OBJEXT) strchr.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@strcmp.$(OBJEXT) strcasecmp.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@strcoll.$(OBJEXT) strcpy.$(OBJEXT) strcspn.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@strdup.$(OBJEXT) strdup_r.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strerror.$(OBJEXT) strerror_r.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strlcat.$(OBJEXT) strlcpy.$(OBJEXT) strlen.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strlwr.$(OBJEXT) strncat.$(OBJEXT) strncmp.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strncasecmp.$(OBJEXT) strncpy.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@strndup.$(OBJEXT) strndup_r.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strnlen.$(OBJEXT) strpbrk.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strrchr.$(OBJEXT) strsep.$(OBJEXT) strspn.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strtok.$(OBJEXT) strtok_r.$(OBJEXT) strupr.$(OBJEXT) \
@@ -207,14 +216,16 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
libstring_la_LIBADD =
@USE_LIBTOOL_TRUE@libstring_la_OBJECTS = bcmp.lo bcopy.lo bzero.lo \
-@USE_LIBTOOL_TRUE@index.lo memchr.lo memcmp.lo memcpy.lo memmove.lo \
-@USE_LIBTOOL_TRUE@memset.lo rindex.lo strcat.lo strchr.lo strcmp.lo \
-@USE_LIBTOOL_TRUE@strcasecmp.lo strcoll.lo strcpy.lo strcspn.lo \
+@USE_LIBTOOL_TRUE@index.lo memccpy.lo memchr.lo memcmp.lo memcpy.lo \
+@USE_LIBTOOL_TRUE@memmove.lo mempcpy.lo memset.lo rindex.lo strcat.lo \
+@USE_LIBTOOL_TRUE@strchr.lo strcmp.lo strcasecmp.lo strcoll.lo \
+@USE_LIBTOOL_TRUE@strcpy.lo strcspn.lo strdup.lo strdup_r.lo \
@USE_LIBTOOL_TRUE@strerror.lo strerror_r.lo strlcat.lo strlcpy.lo \
@USE_LIBTOOL_TRUE@strlen.lo strlwr.lo strncat.lo strncmp.lo \
-@USE_LIBTOOL_TRUE@strncasecmp.lo strncpy.lo strnlen.lo strpbrk.lo \
-@USE_LIBTOOL_TRUE@strrchr.lo strsep.lo strspn.lo strtok.lo strtok_r.lo \
-@USE_LIBTOOL_TRUE@strupr.lo strxfrm.lo strstr.lo swab.lo u_strerr.lo
+@USE_LIBTOOL_TRUE@strncasecmp.lo strncpy.lo strndup.lo strndup_r.lo \
+@USE_LIBTOOL_TRUE@strnlen.lo strpbrk.lo strrchr.lo strsep.lo strspn.lo \
+@USE_LIBTOOL_TRUE@strtok.lo strtok_r.lo strupr.lo strxfrm.lo strstr.lo \
+@USE_LIBTOOL_TRUE@swab.lo u_strerr.lo
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
diff --git a/newlib/libc/string/memccpy.c b/newlib/libc/string/memccpy.c
new file mode 100644
index 000000000..f677ac02e
--- /dev/null
+++ b/newlib/libc/string/memccpy.c
@@ -0,0 +1,145 @@
+/*
+FUNCTION
+ <<memccpy>>---copy memory regions with end-token check
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void* memccpy(void *<[out]>, const void *<[in]>,
+ int <[endchar]>, size_t <[n]>);
+
+TRAD_SYNOPSIS
+ void *memccpy(<[out]>, <[in]>, <[endchar]>, <[n]>
+ void *<[out]>;
+ void *<[in]>;
+ int <[endchar]>;
+ size_t <[n]>;
+
+DESCRIPTION
+ This function copies up to <[n]> bytes from the memory region
+ pointed to by <[in]> to the memory region pointed to by
+ <[out]>. If a byte matching the <[endchar]> is encountered,
+ the byte is copied and copying stops.
+
+ If the regions overlap, the behavior is undefined.
+
+RETURNS
+ <<memccpy>> returns a pointer to the first byte following the
+ <[endchar]> in the <[out]> region. If no byte matching
+ <[endchar]> was copied, then <<NULL>> is returned.
+
+PORTABILITY
+<<memccpy>> is a GNU extension.
+
+<<memccpy>> requires no supporting OS subroutines.
+
+ */
+
+#include <_ansi.h>
+#include <stddef.h>
+#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)))
+
+/* 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) < LITTLEBLOCKSIZE)
+
+/* Macros for detecting endchar */
+#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
+
+
+_PTR
+_DEFUN (memccpy, (dst0, src0, endchar, len0),
+ _PTR dst0 _AND
+ _CONST _PTR src0 _AND
+ int endchar0 _AND
+ size_t len0)
+{
+
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ _PTR ptr = NULL;
+ char *dst = (char *) dst0;
+ char *src = (char *) src0;
+ char endchar = endchar0 & 0xff;
+
+ while (len0--)
+ {
+ if ((*dst++ = *src++) == endchar)
+ {
+ ptr = dst;
+ break;
+ }
+ }
+
+ return ptr;
+#else
+ _PTR ptr = NULL;
+ char *dst = dst0;
+ _CONST char *src = src0;
+ long *aligned_dst;
+ _CONST long *aligned_src;
+ int len = len0;
+ char endchar = endchar0 & 0xff;
+
+ /* 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))
+ {
+ int i;
+ unsigned long mask = 0;
+
+ aligned_dst = (long*)dst;
+ aligned_src = (long*)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. */
+ for (i = 0; i < LITTLEBLOCKSIZE; i++)
+ mask = (mask << 8) + endchar;
+
+
+ /* Copy one long word at a time if possible. */
+ while (len >= LITTLEBLOCKSIZE)
+ {
+ unsigned long buffer = (unsigned long)(*aligned_src);
+ buffer ^= mask;
+ if (DETECTNULL (buffer))
+ break; /* endchar is found, go byte by byte from here */
+ *aligned_dst++ = *aligned_src++;
+ len -= LITTLEBLOCKSIZE;
+ }
+
+ /* Pick up any residual with a byte copier. */
+ dst = (char*)aligned_dst;
+ src = (char*)aligned_src;
+ }
+
+ while (len--)
+ {
+ if ((*dst++ = *src++) == endchar)
+ {
+ ptr = dst;
+ break;
+ }
+ }
+
+ return ptr;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/mempcpy.c b/newlib/libc/string/mempcpy.c
new file mode 100644
index 000000000..284cbea79
--- /dev/null
+++ b/newlib/libc/string/mempcpy.c
@@ -0,0 +1,108 @@
+/*
+FUNCTION
+ <<mempcpy>>---copy memory regions and return end pointer
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void* mempcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
+
+TRAD_SYNOPSIS
+ void *mempcpy(<[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
+ <<mempcpy>> returns a pointer to the byte following the
+ last byte copied to the <[out]> region.
+
+PORTABILITY
+<<mempcpy>> is a GNU extension.
+
+<<mempcpy>> requires no supporting OS subroutines.
+
+ */
+
+#include <_ansi.h>
+#include <stddef.h>
+#include <limits.h>
+#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 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 (mempcpy, (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;
+
+ while (len0--)
+ {
+ *dst++ = *src++;
+ }
+
+ return dst;
+#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 dst;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
diff --git a/newlib/libc/string/strdup.c b/newlib/libc/string/strdup.c
new file mode 100644
index 000000000..dbb069264
--- /dev/null
+++ b/newlib/libc/string/strdup.c
@@ -0,0 +1,13 @@
+#ifndef _REENT_ONLY
+
+#include <reent.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *
+_DEFUN (strdup, (str), _CONST char *str)
+{
+ return _strdup_r (_REENT, str);
+}
+
+#endif /* !_REENT_ONLY */
diff --git a/newlib/libc/string/strdup_r.c b/newlib/libc/string/strdup_r.c
new file mode 100644
index 000000000..ef77a58eb
--- /dev/null
+++ b/newlib/libc/string/strdup_r.c
@@ -0,0 +1,17 @@
+#include <reent.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *
+_DEFUN (_strdup_r, (reent_ptr, str),
+ struct _reent *reent_ptr _AND
+ _CONST char *str)
+{
+ size_t len = strlen (str) + 1;
+ char *copy = _malloc_r (reent_ptr, len);
+ if (copy)
+ {
+ memcpy (copy, str, len);
+ }
+ return copy;
+}
diff --git a/newlib/libc/string/strings.tex b/newlib/libc/string/strings.tex
index f70580b2c..b5435033a 100644
--- a/newlib/libc/string/strings.tex
+++ b/newlib/libc/string/strings.tex
@@ -10,10 +10,12 @@ managing areas of memory. The corresponding declarations are in
* bcopy:: Copy memory regions
* bzero:: Initialize memory to zero
* index:: Search for character in string
+* memccpy:: Copy memory regions up to end-token
* memchr:: Find character in memory
* memcmp:: Compare two memory areas
* memcpy:: Copy memory regions
* memmove:: Move possibly overlapping memory
+* mempcpy:: Copy memory regions and locate end
* memset:: Set an area of memory
* rindex:: Reverse search for character in string
* strcasecmp:: Compare strings ignoring case
@@ -53,6 +55,9 @@ managing areas of memory. The corresponding declarations are in
@include string/index.def
@page
+@include string/memcccpy.def
+
+@page
@include string/memchr.def
@page
@@ -65,6 +70,9 @@ managing areas of memory. The corresponding declarations are in
@include string/memmove.def
@page
+@include string/mempcpy.def
+
+@page
@include string/memset.def
@page
diff --git a/newlib/libc/string/strndup.c b/newlib/libc/string/strndup.c
new file mode 100644
index 000000000..caa1b68b7
--- /dev/null
+++ b/newlib/libc/string/strndup.c
@@ -0,0 +1,16 @@
+#ifndef _REENT_ONLY
+
+#include <_ansi.h>
+#include <reent.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *
+_DEFUN (strndup, (str, n),
+ _CONST char *str _AND
+ size_t n)
+{
+ return _strndup_r (_REENT, str, n);
+}
+
+#endif /* !_REENT_ONLY */
diff --git a/newlib/libc/string/strndup_r.c b/newlib/libc/string/strndup_r.c
new file mode 100644
index 000000000..86d9eec44
--- /dev/null
+++ b/newlib/libc/string/strndup_r.c
@@ -0,0 +1,21 @@
+#include <reent.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+char *
+_DEFUN (_strndup_r, (reent_ptr, str, n),
+ struct _reent *reent_ptr _AND
+ _CONST char *str _AND
+ size_t n)
+{
+ size_t len = MIN(strlen (str), n);
+ char *copy = _malloc_r (reent_ptr, len + 1);
+ if (copy)
+ {
+ memcpy (copy, str, len);
+ copy[len] = '\0';
+ }
+ return copy;
+}