Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2. FUNCTION
  3.         <<strcat>>---concatenate strings
  4.  
  5. INDEX
  6.         strcat
  7.  
  8. ANSI_SYNOPSIS
  9.         #include <string.h>
  10.         char *strcat(char *<[dst]>, const char *<[src]>);
  11.  
  12. TRAD_SYNOPSIS
  13.         #include <string.h>
  14.         char *strcat(<[dst]>, <[src]>)
  15.         char *<[dst]>;
  16.         char *<[src]>;
  17.  
  18. DESCRIPTION
  19.         <<strcat>> appends a copy of the string pointed to by <[src]>
  20.         (including the terminating null character) to the end of the
  21.         string pointed to by <[dst]>.  The initial character of
  22.         <[src]> overwrites the null character at the end of <[dst]>.
  23.  
  24. RETURNS
  25.         This function returns the initial value of <[dst]>
  26.  
  27. PORTABILITY
  28. <<strcat>> is ANSI C.
  29.  
  30. <<strcat>> requires no supporting OS subroutines.
  31.  
  32. QUICKREF
  33.         strcat ansi pure
  34. */
  35.  
  36. #include <string.h>
  37. #include <limits.h>
  38.  
  39. /* Nonzero if X is aligned on a "long" boundary.  */
  40. #define ALIGNED(X) \
  41.   (((long)X & (sizeof (long) - 1)) == 0)
  42.  
  43. #if LONG_MAX == 2147483647L
  44. #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
  45. #else
  46. #if LONG_MAX == 9223372036854775807L
  47. /* Nonzero if X (a long int) contains a NULL byte. */
  48. #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
  49. #else
  50. #error long int is not a 32bit or 64bit type.
  51. #endif
  52. #endif
  53.  
  54. #ifndef DETECTNULL
  55. #error long int is not a 32bit or 64bit byte
  56. #endif
  57.  
  58.  
  59. /*SUPPRESS 560*/
  60. /*SUPPRESS 530*/
  61.  
  62. char *
  63. _DEFUN (strcat, (s1, s2),
  64.         char *s1 _AND
  65.         _CONST char *s2)
  66. {
  67. #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
  68.   char *s = s1;
  69.  
  70.   while (*s1)
  71.     s1++;
  72.  
  73.   while (*s1++ = *s2++)
  74.     ;
  75.   return s;
  76. #else
  77.   char *s = s1;
  78.  
  79.  
  80.   /* Skip over the data in s1 as quickly as possible.  */
  81.   if (ALIGNED (s1))
  82.     {
  83.       unsigned long *aligned_s1 = (unsigned long *)s1;
  84.       while (!DETECTNULL (*aligned_s1))
  85.         aligned_s1++;
  86.  
  87.       s1 = (char *)aligned_s1;
  88.     }
  89.  
  90.   while (*s1)
  91.     s1++;
  92.  
  93.   /* s1 now points to the its trailing null character, we can
  94.      just use strcpy to do the work for us now.
  95.  
  96.      ?!? We might want to just include strcpy here.
  97.      Also, this will cause many more unaligned string copies because
  98.      s1 is much less likely to be aligned.  I don't know if its worth
  99.      tweaking strcpy to handle this better.  */
  100.   strcpy (s1, s2);
  101.        
  102.   return s;
  103. #endif /* not PREFER_SIZE_OVER_SPEED */
  104. }
  105.