Subversion Repositories Kolibri OS

Rev

Rev 4872 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
FUNCTION
3
	<>---character string length
4
 
5
INDEX
6
	strlen
7
 
8
ANSI_SYNOPSIS
9
	#include 
10
	size_t strlen(const char *<[str]>);
11
 
12
TRAD_SYNOPSIS
13
	#include 
14
	size_t strlen(<[str]>)
15
	char *<[src]>;
16
 
17
DESCRIPTION
18
	The <> function works out the length of the string
19
	starting at <<*<[str]>>> by counting chararacters until it
20
	reaches a <> character.
21
 
22
RETURNS
23
	<> returns the character count.
24
 
25
PORTABILITY
26
<> is ANSI C.
27
 
28
<> requires no supporting OS subroutines.
29
 
30
QUICKREF
31
	strlen ansi pure
32
*/
33
 
34
#include <_ansi.h>
35
#include 
36
#include 
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
}