~linaro-toolchain-dev/cortex-strings/trunk

« back to all changes in this revision

Viewing changes to reference/newlib-c/strlen.c

  • Committer: Michael Hope
  • Date: 2012-06-12 03:21:06 UTC
  • Revision ID: michael.hope@linaro.org-20120612032106-r67u7dmb5pq0guq7
Added the C only routines from Newlib 1.20+20120605~git3af2fa7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "shim.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
}