[patch] Add stpcpy/stpncpy
Jeff Johnston
jjohnstn@redhat.com
Thu Jun 28 16:07:00 GMT 2007
Corinna,
Please put the prototypes in the !_STRICT_ANSI_ section of string.h.
Please put the sources in the Makefile.am ELIX_SOURCES list for now.
Also please add the documentation references to the
libc/string/strings.tex file. Other than that, approved.
-- Jeff J.
Corinna Vinschen wrote:
> Hi,
>
> the functions stpcpy and stpncpy are GNU extensions which are candidates
> for inclusion into POSIX and SUSv4. Below is an implementation for both
> functions which I'd like to include into newlib. They are self-written,
> basically taken from the existing strcpy/strncpy functions, to avoid
> licensing problems. The implementation has been tested on Cygwin.
>
> Ok to apply?
>
>
> Corinna
>
>
> * libc/include/string.h: Add prototypes for stpcpy and stpncpy.
> * libc/string/Makefile.am (GENERAL_SOURCES): Add stpcpy.c and
> stpncpy.c.
> (CHEWOUT_FILES): Add stpcpy.def and stpncpy.def.
> * libc/string/Makefile.in: Regenerate.
> * libc/string/stpcpy.c: New file.
> * libc/string/stpncpy.c: New file.
>
>
> Index: libc/include/string.h
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/include/string.h,v
> retrieving revision 1.19
> diff -u -p -r1.19 string.h
> --- libc/include/string.h 8 Jun 2007 18:38:51 -0000 1.19
> +++ libc/include/string.h 28 Jun 2007 15:12:29 -0000
> @@ -40,6 +40,9 @@ char *_EXFUN(strrchr,(const char *, int
> size_t _EXFUN(strspn,(const char *, const char *));
> char *_EXFUN(strstr,(const char *, const char *));
>
> +char *_EXFUN(stpcpy,(char *, const char *));
> +char *_EXFUN(stpncpy,(char *, const char *, size_t));
> +
> #ifndef _REENT_ONLY
> char *_EXFUN(strtok,(char *, const char *));
> #endif
> Index: libc/string/Makefile.am
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/string/Makefile.am,v
> retrieving revision 1.16
> diff -u -p -r1.16 Makefile.am
> --- libc/string/Makefile.am 8 Jun 2007 18:38:51 -0000 1.16
> +++ libc/string/Makefile.am 28 Jun 2007 15:12:30 -0000
> @@ -14,6 +14,8 @@ GENERAL_SOURCES = \
> memmove.c \
> memset.c \
> rindex.c \
> + stpcpy.c \
> + stpncpy.c \
> strcasecmp.c \
> strcat.c \
> strchr.c \
> @@ -105,7 +107,7 @@ index.def rindex.def strcspn.def strpbrk
> 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 strcasestr.def strlwr.def strupr.def \
> -memccpy.def mempcpy.def \
> +memccpy.def mempcpy.def stpcpy.def stpncpy.def \
> wcscat.def wcschr.def wcscmp.def wcscoll.def \
> wcscpy.def wcscspn.def \
> wcslcat.def wcslcpy.def wcslen.def wcsncat.def \
> Index: libc/string/Makefile.in
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/string/Makefile.in,v
> retrieving revision 1.28
> diff -u -p -r1.28 Makefile.in
> --- libc/string/Makefile.in 8 Jun 2007 18:38:51 -0000 1.28
> +++ libc/string/Makefile.in 28 Jun 2007 15:12:30 -0000
> @@ -59,7 +59,8 @@ am__objects_1 = lib_a-bcopy.$(OBJEXT) li
> lib_a-index.$(OBJEXT) lib_a-memchr.$(OBJEXT) \
> lib_a-memcmp.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \
> lib_a-memmove.$(OBJEXT) lib_a-memset.$(OBJEXT) \
> - lib_a-rindex.$(OBJEXT) lib_a-strcasecmp.$(OBJEXT) \
> + lib_a-rindex.$(OBJEXT) lib_a-stpcpy.$(OBJEXT) \
> + lib_a-stpncpy.$(OBJEXT) lib_a-strcasecmp.$(OBJEXT) \
> lib_a-strcat.$(OBJEXT) lib_a-strchr.$(OBJEXT) \
> lib_a-strcmp.$(OBJEXT) lib_a-strcoll.$(OBJEXT) \
> lib_a-strcpy.$(OBJEXT) lib_a-strcspn.$(OBJEXT) \
> @@ -99,18 +100,18 @@ lib_a_OBJECTS = $(am_lib_a_OBJECTS)
> LTLIBRARIES = $(noinst_LTLIBRARIES)
> libstring_la_LIBADD =
> am__objects_3 = bcopy.lo bzero.lo index.lo memchr.lo memcmp.lo \
> - memcpy.lo memmove.lo memset.lo rindex.lo strcasecmp.lo \
> - strcat.lo strchr.lo strcmp.lo strcoll.lo strcpy.lo strcspn.lo \
> - strdup.lo strdup_r.lo strerror.lo strerror_r.lo strlcat.lo \
> - strlcpy.lo strlen.lo strlwr.lo strncasecmp.lo strncat.lo \
> - strncmp.lo strncpy.lo strnlen.lo strpbrk.lo strrchr.lo \
> - strsep.lo strspn.lo strtok.lo strtok_r.lo strupr.lo strxfrm.lo \
> - strstr.lo swab.lo u_strerr.lo wcscat.lo wcschr.lo wcscmp.lo \
> - wcscoll.lo wcscpy.lo wcscspn.lo wcslcat.lo wcslcpy.lo \
> - wcslen.lo wcsncat.lo wcsncmp.lo wcsncpy.lo wcsnlen.lo \
> - wcspbrk.lo wcsrchr.lo wcsspn.lo wcsstr.lo wcswidth.lo \
> - wcwidth.lo wmemchr.lo wmemcmp.lo wmemcpy.lo wmemmove.lo \
> - wmemset.lo
> + memcpy.lo memmove.lo memset.lo rindex.lo stpcpy.lo stpncpy.lo \
> + strcasecmp.lo strcat.lo strchr.lo strcmp.lo strcoll.lo \
> + strcpy.lo strcspn.lo strdup.lo strdup_r.lo strerror.lo \
> + strerror_r.lo strlcat.lo strlcpy.lo strlen.lo strlwr.lo \
> + strncasecmp.lo strncat.lo strncmp.lo strncpy.lo strnlen.lo \
> + strpbrk.lo strrchr.lo strsep.lo strspn.lo strtok.lo \
> + strtok_r.lo strupr.lo strxfrm.lo strstr.lo swab.lo u_strerr.lo \
> + wcscat.lo wcschr.lo wcscmp.lo wcscoll.lo wcscpy.lo wcscspn.lo \
> + wcslcat.lo wcslcpy.lo wcslen.lo wcsncat.lo wcsncmp.lo \
> + wcsncpy.lo wcsnlen.lo wcspbrk.lo wcsrchr.lo wcsspn.lo wcsstr.lo \
> + wcswidth.lo wcwidth.lo wmemchr.lo wmemcmp.lo wmemcpy.lo \
> + wmemmove.lo wmemset.lo
> @ELIX_LEVEL_1_FALSE@am__objects_4 = bcmp.lo memccpy.lo mempcpy.lo \
> @ELIX_LEVEL_1_FALSE@ strndup.lo strcasestr.lo strndup_r.lo
> @USE_LIBTOOL_TRUE@am_libstring_la_OBJECTS = $(am__objects_3) \
> @@ -302,6 +303,8 @@ GENERAL_SOURCES = \
> memmove.c \
> memset.c \
> rindex.c \
> + stpcpy.c \
> + stpncpy.c \
> strcasecmp.c \
> strcat.c \
> strchr.c \
> @@ -383,7 +386,7 @@ index.def rindex.def strcspn.def strpbrk
> 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 strcasestr.def strlwr.def strupr.def \
> -memccpy.def mempcpy.def \
> +memccpy.def mempcpy.def stpcpy.def stpncpy.def \
> wcscat.def wcschr.def wcscmp.def wcscoll.def \
> wcscpy.def wcscspn.def \
> wcslcat.def wcslcpy.def wcslen.def wcsncat.def \
> @@ -517,6 +520,18 @@ lib_a-rindex.o: rindex.c
> lib_a-rindex.obj: rindex.c
> $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-rindex.obj `if test -f 'rindex.c'; then $(CYGPATH_W) 'rindex.c'; else $(CYGPATH_W) '$(srcdir)/rindex.c'; fi`
>
> +lib_a-stpcpy.o: stpcpy.c
> + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-stpcpy.o `test -f 'stpcpy.c' || echo '$(srcdir)/'`stpcpy.c
> +
> +lib_a-stpcpy.obj: stpcpy.c
> + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-stpcpy.obj `if test -f 'stpcpy.c'; then $(CYGPATH_W) 'stpcpy.c'; else $(CYGPATH_W) '$(srcdir)/stpcpy.c'; fi`
> +
> +lib_a-stpncpy.o: stpncpy.c
> + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-stpncpy.o `test -f 'stpncpy.c' || echo '$(srcdir)/'`stpncpy.c
> +
> +lib_a-stpncpy.obj: stpncpy.c
> + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-stpncpy.obj `if test -f 'stpncpy.c'; then $(CYGPATH_W) 'stpncpy.c'; else $(CYGPATH_W) '$(srcdir)/stpncpy.c'; fi`
> +
> lib_a-strcasecmp.o: strcasecmp.c
> $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcasecmp.o `test -f 'strcasecmp.c' || echo '$(srcdir)/'`strcasecmp.c
>
> Index: libc/string/stpcpy.c
> ===================================================================
> RCS file: libc/string/stpcpy.c
> diff -N libc/string/stpcpy.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ libc/string/stpcpy.c 28 Jun 2007 15:12:30 -0000
> @@ -0,0 +1,91 @@
> +/*
> +FUNCTION
> + <<stpcpy>>---copy string returning a pointer to its end
> +
> +INDEX
> + stpcpy
> +
> +ANSI_SYNOPSIS
> + #include <string.h>
> + char *stpcpy(char *<[dst]>, const char *<[src]>);
> +
> +TRAD_SYNOPSIS
> + #include <string.h>
> + char *stpcpy(<[dst]>, <[src]>)
> + char *<[dst]>;
> + char *<[src]>;
> +
> +DESCRIPTION
> + <<stpcpy>> copies the string pointed to by <[src]>
> + (including the terminating null character) to the array
> + pointed to by <[dst]>.
> +
> +RETURNS
> + This function returns a pointer to the end of the destination string,
> + thus pointing to the trailing '\0'.
> +
> +PORTABILITY
> +<<stpcpy>> is a GNU extension, candidate for inclusion into POSIX/SUSv4.
> +
> +<<stpcpy>> requires no supporting OS subroutines.
> +
> +QUICKREF
> + stpcpy gnu
> +*/
> +
> +#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 (stpcpy, (dst, src),
> + char *dst _AND
> + _CONST char *src)
> +{
> +#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
> + 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;
> + }
> +#endif /* not PREFER_SIZE_OVER_SPEED */
> +
> + while ((*dst++ = *src++))
> + ;
> + return --dst;
> +}
> Index: libc/string/stpncpy.c
> ===================================================================
> RCS file: libc/string/stpncpy.c
> diff -N libc/string/stpncpy.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ libc/string/stpncpy.c 28 Jun 2007 15:12:30 -0000
> @@ -0,0 +1,114 @@
> +/*
> +FUNCTION
> + <<stpncpy>>---counted copy string returning a pointer to its end
> +
> +INDEX
> + stpncpy
> +
> +ANSI_SYNOPSIS
> + #include <string.h>
> + char *stpncpy(char *<[dst]>, const char *<[src]>, size_t <[length]>);
> +
> +TRAD_SYNOPSIS
> + #include <string.h>
> + char *stpncpy(<[dst]>, <[src]>, <[length]>)
> + char *<[dst]>;
> + char *<[src]>;
> + size_t <[length]>;
> +
> +DESCRIPTION
> + <<stpncpy>> 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 a pointer to the end of the destination string,
> + thus pointing to the trailing '\0', or, if the destination string is
> + not null-terminated, pointing to dst + n.
> +
> +PORTABILITY
> +<<stpncpy>> is a GNU extension, candidate for inclusion into POSIX/SUSv4.
> +
> +<<stpncpy>> requires no supporting OS subroutines.
> +
> +QUICKREF
> + stpncpy gnu
> +*/
> +
> +#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 (stpncpy, (dst, src),
> + char *dst _AND
> + _CONST char *src _AND
> + size_t count)
> +{
> + char *ret = NULL;
> +
> +#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
> + 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;
> + }
> +#endif /* not PREFER_SIZE_OVER_SPEED */
> +
> + while (count > 0)
> + {
> + --count;
> + if ((*dst++ = *src++) == '\0')
> + {
> + ret = dst - 1;
> + break;
> + }
> + }
> +
> + while (count-- > 0)
> + *dst++ = '\0';
> +
> + return ret ? ret : dst;
> +}
>
More information about the Newlib
mailing list