Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2. FUNCTION
  3.         <<strlen>>---character string length
  4.  
  5. INDEX
  6.         strlen
  7.  
  8. ANSI_SYNOPSIS
  9.         #include <string.h>
  10.         size_t strlen(const char *<[str]>);
  11.  
  12. TRAD_SYNOPSIS
  13.         #include <string.h>
  14.         size_t strlen(<[str]>)
  15.         char *<[src]>;
  16.  
  17. DESCRIPTION
  18.         The <<strlen>> function works out the length of the string
  19.         starting at <<*<[str]>>> by counting chararacters until it
  20.         reaches a <<NULL>> character.
  21.  
  22. RETURNS
  23.         <<strlen>> returns the character count.
  24.  
  25. PORTABILITY
  26. <<strlen>> is ANSI C.
  27.  
  28. <<strlen>> requires no supporting OS subroutines.
  29.  
  30. QUICKREF
  31.         strlen ansi pure
  32. */
  33.  
  34. #include <_ansi.h>
  35. #include <string.h>
  36. #include <limits.h>
  37.  
  38. #define LBLOCKSIZE   (sizeof (long))
  39. #define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
  40.  
  41. #if LONG_MAX == 2147483647L
  42. #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
  43. #else
  44. #if LONG_MAX == 9223372036854775807L
  45. /* Nonzero if X (a long int) contains a NULL byte. */
  46. #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
  47. #else
  48. #error long int is not a 32bit or 64bit type.
  49. #endif
  50. #endif
  51.  
  52. #ifndef DETECTNULL
  53. #error long int is not a 32bit or 64bit byte
  54. #endif
  55.  
  56. size_t
  57. _DEFUN (strlen, (str),
  58.         _CONST char *str)
  59. {
  60.   _CONST char *start = str;
  61.  
  62. #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
  63.   unsigned long *aligned_addr;
  64.  
  65.   /* Align the pointer, so we can search a word at a time.  */
  66.   while (UNALIGNED (str))
  67.     {
  68.       if (!*str)
  69.         return str - start;
  70.       str++;
  71.     }
  72.  
  73.   /* If the string is word-aligned, we can check for the presence of
  74.      a null in each word-sized block.  */
  75.   aligned_addr = (unsigned long *)str;
  76.   while (!DETECTNULL (*aligned_addr))
  77.     aligned_addr++;
  78.  
  79.   /* Once a null is detected, we check each byte in that block for a
  80.      precise position of the null.  */
  81.   str = (char *) aligned_addr;
  82.  
  83. #endif /* not PREFER_SIZE_OVER_SPEED */
  84.  
  85.   while (*str)
  86.     str++;
  87.   return str - start;
  88. }
  89.