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:
		| @@ -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 | ||||
|   | ||||
| @@ -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)); | ||||
|   | ||||
| @@ -67,8 +67,6 @@ LIB_SOURCES = \ | ||||
| 	setenv.c	\ | ||||
| 	setenv_r.c	\ | ||||
| 	srand48.c	\ | ||||
| 	strdup.c	\ | ||||
| 	strdup_r.c	\ | ||||
| 	strtod.c	\ | ||||
| 	strtol.c	\ | ||||
| 	strtoll.c	\ | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
							
								
								
									
										145
									
								
								newlib/libc/string/memccpy.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								newlib/libc/string/memccpy.c
									
									
									
									
									
										Normal 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 */ | ||||
| } | ||||
							
								
								
									
										108
									
								
								newlib/libc/string/mempcpy.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								newlib/libc/string/mempcpy.c
									
									
									
									
									
										Normal 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 */ | ||||
| } | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
							
								
								
									
										16
									
								
								newlib/libc/string/strndup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								newlib/libc/string/strndup.c
									
									
									
									
									
										Normal 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 */ | ||||
							
								
								
									
										21
									
								
								newlib/libc/string/strndup_r.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								newlib/libc/string/strndup_r.c
									
									
									
									
									
										Normal 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; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user