Subversion Repositories Kolibri OS

Rev

Rev 4874 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2. FUNCTION
  3.         <<stpcpy>>---copy string returning a pointer to its end
  4.  
  5. INDEX
  6.         stpcpy
  7.  
  8. ANSI_SYNOPSIS
  9.         #include <string.h>
  10.         char *stpcpy(char *restrict <[dst]>, const char *restrict <[src]>);
  11.  
  12. TRAD_SYNOPSIS
  13.         #include <string.h>
  14.         char *stpcpy(<[dst]>, <[src]>)
  15.         char *<[dst]>;
  16.         char *<[src]>;
  17.  
  18. DESCRIPTION
  19.         <<stpcpy>> copies the string pointed to by <[src]>
  20.         (including the terminating null character) to the array
  21.         pointed to by <[dst]>.
  22.  
  23. RETURNS
  24.         This function returns a pointer to the end of the destination string,
  25.         thus pointing to the trailing '\0'.
  26.  
  27. PORTABILITY
  28. <<stpcpy>> is a GNU extension, candidate for inclusion into POSIX/SUSv4.
  29.  
  30. <<stpcpy>> requires no supporting OS subroutines.
  31.  
  32. QUICKREF
  33.         stpcpy gnu
  34. */
  35.  
  36. #include <string.h>
  37. #include <limits.h>
  38.  
  39. /*SUPPRESS 560*/
  40. /*SUPPRESS 530*/
  41.  
  42. /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
  43. #define UNALIGNED(X, Y) \
  44.   (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
  45.  
  46. #if LONG_MAX == 2147483647L
  47. #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
  48. #else
  49. #if LONG_MAX == 9223372036854775807L
  50. /* Nonzero if X (a long int) contains a NULL byte. */
  51. #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
  52. #else
  53. #error long int is not a 32bit or 64bit type.
  54. #endif
  55. #endif
  56.  
  57. #ifndef DETECTNULL
  58. #error long int is not a 32bit or 64bit byte
  59. #endif
  60.  
  61. char*
  62. _DEFUN (stpcpy, (dst, src),
  63.         char *__restrict dst _AND
  64.         _CONST char *__restrict src)
  65. {
  66. #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
  67.   long *aligned_dst;
  68.   _CONST long *aligned_src;
  69.  
  70.   /* If SRC or DEST is unaligned, then copy bytes.  */
  71.   if (!UNALIGNED (src, dst))
  72.     {
  73.       aligned_dst = (long*)dst;
  74.       aligned_src = (long*)src;
  75.  
  76.       /* SRC and DEST are both "long int" aligned, try to do "long int"
  77.          sized copies.  */
  78.       while (!DETECTNULL(*aligned_src))
  79.         {
  80.           *aligned_dst++ = *aligned_src++;
  81.         }
  82.  
  83.       dst = (char*)aligned_dst;
  84.       src = (char*)aligned_src;
  85.     }
  86. #endif /* not PREFER_SIZE_OVER_SPEED */
  87.  
  88.   while ((*dst++ = *src++))
  89.     ;
  90.   return --dst;
  91. }
  92.