Rev 4872 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /* |
2 | FUNCTION |
||
3 | < |
||
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 < |
||
19 | starting at <<*<[str]>>> by counting chararacters until it |
||
20 | reaches a < |
||
21 | |||
22 | RETURNS |
||
23 | < |
||
24 | |||
25 | PORTABILITY |
||
26 | < |
||
27 | |||
28 | < |
||
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 | } |