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.
This commit is contained in:
Jeff Johnston 2002-07-23 21:38:00 +00:00
parent 5e50e4e45c
commit d254189b38
13 changed files with 357 additions and 24 deletions

View File

@ -1,3 +1,22 @@
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.
2002-07-23 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/stdio.h: Move fcloseall prototype within

View File

@ -55,10 +55,13 @@ void _EXFUN(bzero,(void *, size_t));
int _EXFUN(ffs,(int));
char *_EXFUN(index,(const char *, int));
_PTR _EXFUN(memccpy,(_PTR, const _PTR, int, size_t));
_PTR _EXFUN(mempcpy,(_PTR, const _PTR, size_t));
char *_EXFUN(rindex,(const char *, int));
int _EXFUN(strcasecmp,(const char *, const char *));
char *_EXFUN(strdup,(const char *));
char *_EXFUN(_strdup_r,(struct _reent *, const char *));
char *_EXFUN(strndup,(const char *, size_t));
char *_EXFUN(_strndup_r,(struct _reent *, const char *, size_t));
char *_EXFUN(strerror_r,(int, char *, size_t));
size_t _EXFUN(strlcat,(char *, const char *, size_t));
size_t _EXFUN(strlcpy,(char *, const char *, size_t));

View File

@ -67,8 +67,6 @@ LIB_SOURCES = \
setenv.c \
setenv_r.c \
srand48.c \
strdup.c \
strdup_r.c \
strtod.c \
strtol.c \
strtoll.c \

View File

@ -173,8 +173,6 @@ LIB_SOURCES = \
setenv.c \
setenv_r.c \
srand48.c \
strdup.c \
strdup_r.c \
strtod.c \
strtol.c \
strtoll.c \
@ -290,8 +288,7 @@ LIBS = @LIBS@
@USE_LIBTOOL_FALSE@putenv_r.$(OBJEXT) rand.$(OBJEXT) rand48.$(OBJEXT) \
@USE_LIBTOOL_FALSE@rand_r.$(OBJEXT) realloc.$(OBJEXT) seed48.$(OBJEXT) \
@USE_LIBTOOL_FALSE@setenv.$(OBJEXT) setenv_r.$(OBJEXT) \
@USE_LIBTOOL_FALSE@srand48.$(OBJEXT) strdup.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strdup_r.$(OBJEXT) strtod.$(OBJEXT) strtol.$(OBJEXT) \
@USE_LIBTOOL_FALSE@srand48.$(OBJEXT) strtod.$(OBJEXT) strtol.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strtoll.$(OBJEXT) strtoll_r.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strtoul.$(OBJEXT) strtoull.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strtoull_r.$(OBJEXT) system.$(OBJEXT) \
@ -318,10 +315,10 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
@USE_LIBTOOL_TRUE@msize.lo mstats.lo mtrim.lo nrand48.lo on_exit.lo \
@USE_LIBTOOL_TRUE@putenv.lo putenv_r.lo rand.lo rand48.lo rand_r.lo \
@USE_LIBTOOL_TRUE@realloc.lo seed48.lo setenv.lo setenv_r.lo srand48.lo \
@USE_LIBTOOL_TRUE@strdup.lo strdup_r.lo strtod.lo strtol.lo strtoll.lo \
@USE_LIBTOOL_TRUE@strtoll_r.lo strtoul.lo strtoull.lo strtoull_r.lo \
@USE_LIBTOOL_TRUE@system.lo valloc.lo wcstombs.lo wcstombs_r.lo \
@USE_LIBTOOL_TRUE@wctomb.lo wctomb_r.lo
@USE_LIBTOOL_TRUE@strtod.lo strtol.lo strtoll.lo strtoll_r.lo \
@USE_LIBTOOL_TRUE@strtoul.lo strtoull.lo strtoull_r.lo system.lo \
@USE_LIBTOOL_TRUE@valloc.lo wcstombs.lo wcstombs_r.lo wctomb.lo \
@USE_LIBTOOL_TRUE@wctomb_r.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)

View File

@ -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

View File

@ -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)

View File

@ -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 */
}

View File

@ -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 */
}

View File

@ -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
@ -52,6 +54,9 @@ managing areas of memory. The corresponding declarations are in
@page
@include string/index.def
@page
@include string/memcccpy.def
@page
@include string/memchr.def
@ -64,6 +69,9 @@ managing areas of memory. The corresponding declarations are in
@page
@include string/memmove.def
@page
@include string/mempcpy.def
@page
@include string/memset.def

View File

@ -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 */

View File

@ -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;
}