3 <<memchr>>---find character in memory
10 void *memchr(const void *<[src]>, int <[c]>, size_t <[length]>);
14 void *memchr(<[src]>, <[c]>, <[length]>)
20 This function searches memory starting at <<*<[src]>>> for the
21 character <[c]>. The search only ends with the first
22 occurrence of <[c]>, or after <[length]> characters; in
23 particular, <<NULL>> does not terminate the search.
26 If the character <[c]> is found within <[length]> characters
27 of <<*<[src]>>>, a pointer to the character is returned. If
28 <[c]> is not found, then <<NULL>> is returned.
31 <<memchr>>> is ANSI C.
33 <<memchr>> requires no supporting OS subroutines.
43 /* Nonzero if either X or Y is not aligned on a "long" boundary. */
44 #define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
46 /* How many bytes are loaded each iteration of the word copy loop. */
47 #define LBLOCKSIZE (sizeof (long))
49 /* Threshhold for punting to the bytewise iterator. */
50 #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
52 #if LONG_MAX == 2147483647L
53 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
55 #if LONG_MAX == 9223372036854775807L
56 /* Nonzero if X (a long int) contains a NULL byte. */
57 #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
59 #error long int is not a 32bit or 64bit type.
64 #error long int is not a 32bit or 64bit byte
69 _DEFUN (memchr
, (src_void
, c
, length
),
70 _CONST _PTR src_void _AND
74 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
75 _CONST
unsigned char *src
= (_CONST
unsigned char *) src_void
;
87 _CONST
unsigned char *src
= (_CONST
unsigned char *) src_void
;
95 /* If the size is small, or src is unaligned, then
96 use the bytewise loop. We can hope this is rare. */
97 if (!TOO_SMALL (length
) && !UNALIGNED (src
))
99 /* The fast code reads the ASCII one word at a time and only
100 performs the bytewise search on word-sized segments if they
101 contain the search character, which is detected by XORing
102 the word-sized segment with a word-sized block of the search
103 character and then detecting for the presence of NULL in the
105 asrc
= (unsigned long*) src
;
107 for (i
= 0; i
< LBLOCKSIZE
; i
++)
108 mask
= (mask
<< 8) + c
;
110 while (length
>= LBLOCKSIZE
)
114 if (DETECTNULL (buffer
))
116 src
= (unsigned char*) asrc
;
117 for ( j
= 0; j
< LBLOCKSIZE
; j
++ )
124 length
-= LBLOCKSIZE
;
128 /* If there are fewer than LBLOCKSIZE characters left,
129 then we resort to the bytewise loop. */
131 src
= (unsigned char*) asrc
;
142 #endif /* not PREFER_SIZE_OVER_SPEED */