This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Generic strlen


To settle this issue, here's a new strlen for y'all to gander at:

#include<string.h>
#include<limits.h>

/* Nonzero if X is not aligned on a "long" boundary.  */
#define UNALIGNED(X) ((long)X&  (sizeof (long) - 1))

/* How many bytes are loaded each iteration of the word copy loop.  */
#define LBLOCKSIZE (sizeof (long))

#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

size_t
_DEFUN (strlen, (s),
	_CONST char *s)
{
  size_t n = 0;

#if !defined(PREFER_SIZE_OVER_SPEED)&&  !defined(__OPTIMIZE_SIZE__)
  unsigned long *aligned_addr;

  /* Special case for finding 0.  */
  while (UNALIGNED (s))
    {
      if (*s == '\0')
        return n;
      ++s;
      ++n;
    }
  /* Operate a word at a time.  */
  aligned_addr = (unsigned long *) s;
  while (!DETECTNULL (*aligned_addr))
    {
       ++aligned_addr;
       n += sizeof (unsigned long);
    }
  /* Found the end of string.  */
  s = (const char *) aligned_addr;

  /* The block of bytes currently pointed to by aligned_addr
     contains a null.  We catch it using the bytewise search.  */

#endif /* not PREFER_SIZE_OVER_SPEED */

  while (*s != '\0')
    {
      ++s;
      ++n;
    }
  return n;
}

/* END OF FILE */



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]