Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2. FUNCTION
  3.         <<strncpy>>---counted copy string
  4.  
  5. INDEX
  6.         strncpy
  7.  
  8. ANSI_SYNOPSIS
  9.         #include <string.h>
  10.         char *strncpy(char *<[dst]>, const char *<[src]>, size_t <[length]>);
  11.  
  12. TRAD_SYNOPSIS
  13.         #include <string.h>
  14.         char *strncpy(<[dst]>, <[src]>, <[length]>)
  15.         char *<[dst]>;
  16.         char *<[src]>;
  17.         size_t <[length]>;
  18.  
  19. DESCRIPTION
  20.         <<strncpy>> copies not more than <[length]> characters from the
  21.         the string pointed to by <[src]> (including the terminating
  22.         null character) to the array pointed to by <[dst]>.  If the
  23.         string pointed to by <[src]> is shorter than <[length]>
  24.         characters, null characters are appended to the destination
  25.         array until a total of <[length]> characters have been
  26.         written.
  27.  
  28. RETURNS
  29.         This function returns the initial value of <[dst]>.
  30.  
  31. PORTABILITY
  32. <<strncpy>> is ANSI C.
  33.  
  34. <<strncpy>> requires no supporting OS subroutines.
  35.  
  36. QUICKREF
  37.         strncpy ansi pure
  38. */
  39.  
  40. #include <string.h>
  41. #include <limits.h>
  42.  
  43. /*SUPPRESS 560*/
  44. /*SUPPRESS 530*/
  45.  
  46. /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
  47. #define UNALIGNED(X, Y) \
  48.   (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
  49.  
  50. #if LONG_MAX == 2147483647L
  51. #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
  52. #else
  53. #if LONG_MAX == 9223372036854775807L
  54. /* Nonzero if X (a long int) contains a NULL byte. */
  55. #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
  56. #else
  57. #error long int is not a 32bit or 64bit type.
  58. #endif
  59. #endif
  60.  
  61. #ifndef DETECTNULL
  62. #error long int is not a 32bit or 64bit byte
  63. #endif
  64.  
  65. #define TOO_SMALL(LEN) ((LEN) < sizeof (long))
  66.  
  67. char *
  68. _DEFUN (strncpy, (dst0, src0),
  69.         char *dst0 _AND
  70.         _CONST char *src0 _AND
  71.         size_t count)
  72. {
  73. #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
  74.   char *dscan;
  75.   _CONST char *sscan;
  76.  
  77.   dscan = dst0;
  78.   sscan = src0;
  79.   while (count > 0)
  80.     {
  81.       --count;
  82.       if ((*dscan++ = *sscan++) == '\0')
  83.         break;
  84.     }
  85.   while (count-- > 0)
  86.     *dscan++ = '\0';
  87.  
  88.   return dst0;
  89. #else
  90.   char *dst = dst0;
  91.   _CONST char *src = src0;
  92.   long *aligned_dst;
  93.   _CONST long *aligned_src;
  94.  
  95.   /* If SRC and DEST is aligned and count large enough, then copy words.  */
  96.   if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
  97.     {
  98.       aligned_dst = (long*)dst;
  99.       aligned_src = (long*)src;
  100.  
  101.       /* SRC and DEST are both "long int" aligned, try to do "long int"
  102.          sized copies.  */
  103.       while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
  104.         {
  105.           count -= sizeof (long int);
  106.           *aligned_dst++ = *aligned_src++;
  107.         }
  108.  
  109.       dst = (char*)aligned_dst;
  110.       src = (char*)aligned_src;
  111.     }
  112.  
  113.   while (count > 0)
  114.     {
  115.       --count;
  116.       if ((*dst++ = *src++) == '\0')
  117.         break;
  118.     }
  119.  
  120.   while (count-- > 0)
  121.     *dst++ = '\0';
  122.  
  123.   return dst0;
  124. #endif /* not PREFER_SIZE_OVER_SPEED */
  125. }
  126.