annotate lib/memchr2.c @ 9745:ecc717b72132

Fix bugs in last patch. * lib/memchr2.c (memchr2): Fix typo. * tests/test-memchr2.c: Test previous bug, and don't use GNU extension. Reported by Bruce Korb. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Sat, 01 Mar 2008 08:40:22 -0700
parents 732f01bce79f
children 03b212920228
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9742
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
1 /* Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2006,
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
2 2008 Free Software Foundation, Inc.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
3
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
4 Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
5 with help from Dan Sahlin (dan@sics.se) and
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
6 commentary by Jim Blandy (jimb@ai.mit.edu);
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
7 adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
8 and implemented in glibc by Roland McGrath (roland@ai.mit.edu).
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
9 Extension to memchr2 implemented by Eric Blake (ebb9@byu.net).
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
10
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
11 This program is free software: you can redistribute it and/or modify it
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
12 under the terms of the GNU General Public License as published by the
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
13 Free Software Foundation; either version 3 of the License, or any
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
14 later version.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
15
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
16 This program is distributed in the hope that it will be useful,
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
19 GNU General Public License for more details.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
20
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
21 You should have received a copy of the GNU General Public License
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
23
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
24 #include <config.h>
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
25
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
26 #include "memchr2.h"
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
27
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
28 #include <limits.h>
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
29 #include <stdint.h>
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
30 #include <string.h>
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
31
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
32 /* Return the first address of either C1 or C2 (treated as unsigned
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
33 char) that occurs within N bytes of the memory region S. If
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
34 neither byte appears, return NULL. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
35 void *
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
36 memchr2 (void const *s, int c1_in, int c2_in, size_t n)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
37 {
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
38 const unsigned char *char_ptr;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
39 const uintmax_t *longword_ptr;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
40 uintmax_t longword1;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
41 uintmax_t longword2;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
42 uintmax_t magic_bits;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
43 uintmax_t charmask1;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
44 uintmax_t charmask2;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
45 unsigned char c1;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
46 unsigned char c2;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
47 int i;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
48
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
49 c1 = (unsigned char) c1_in;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
50 c2 = (unsigned char) c2_in;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
51
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
52 if (c1 == c2)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
53 return memchr (s, c1, n);
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
54
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
55 /* Handle the first few characters by reading one character at a time.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
56 Do this until CHAR_PTR is aligned on a longword boundary. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
57 for (char_ptr = (const unsigned char *) s;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
58 n > 0 && (size_t) char_ptr % sizeof longword1 != 0;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
59 --n, ++char_ptr)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
60 if (*char_ptr == c1 || *char_ptr == c2)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
61 return (void *) char_ptr;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
62
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
63 /* All these elucidatory comments refer to 4-byte longwords,
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
64 but the theory applies equally well to any size longwords. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
65
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
66 longword_ptr = (const uintmax_t *) char_ptr;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
67
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
68 /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
69 the "holes." Note that there is a hole just to the left of
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
70 each byte, with an extra at the end:
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
71
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
72 bits: 01111110 11111110 11111110 11111111
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
73 bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
74
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
75 The 1-bits make sure that carries propagate to the next 0-bit.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
76 The 0-bits provide holes for carries to fall into. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
77
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
78 /* Set MAGIC_BITS to be this pattern of 1 and 0 bits.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
79 Set CHARMASK to be a longword, each of whose bytes is C. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
80
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
81 magic_bits = 0xfefefefe;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
82 charmask1 = c1 | (c1 << 8);
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
83 charmask2 = c2 | (c2 << 8);
9745
ecc717b72132 Fix bugs in last patch.
Eric Blake <ebb9@byu.net>
parents: 9742
diff changeset
84 charmask1 |= charmask1 << 16;
ecc717b72132 Fix bugs in last patch.
Eric Blake <ebb9@byu.net>
parents: 9742
diff changeset
85 charmask2 |= charmask2 << 16;
9742
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
86 #if 0xffffffffU < UINTMAX_MAX
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
87 magic_bits |= magic_bits << 32;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
88 charmask1 |= charmask1 << 32;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
89 charmask2 |= charmask2 << 32;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
90 if (8 < sizeof longword1)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
91 for (i = 64; i < sizeof longword1 * 8; i *= 2)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
92 {
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
93 magic_bits |= magic_bits << i;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
94 charmask1 |= charmask1 << i;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
95 charmask2 |= charmask2 << i;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
96 }
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
97 #endif
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
98 magic_bits = (UINTMAX_MAX >> 1) & (magic_bits | 1);
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
99
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
100 /* Instead of the traditional loop which tests each character,
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
101 we will test a longword at a time. The tricky part is testing
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
102 if *any of the four* bytes in the longword in question are zero. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
103 while (n >= sizeof longword1)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
104 {
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
105 /* We tentatively exit the loop if adding MAGIC_BITS to
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
106 LONGWORD fails to change any of the hole bits of LONGWORD.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
107
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
108 1) Is this safe? Will it catch all the zero bytes?
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
109 Suppose there is a byte with all zeros. Any carry bits
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
110 propagating from its left will fall into the hole at its
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
111 least significant bit and stop. Since there will be no
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
112 carry from its most significant bit, the LSB of the
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
113 byte to the left will be unchanged, and the zero will be
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
114 detected.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
115
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
116 2) Is this worthwhile? Will it ignore everything except
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
117 zero bytes? Suppose every byte of LONGWORD has a bit set
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
118 somewhere. There will be a carry into bit 8. If bit 8
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
119 is set, this will carry into bit 16. If bit 8 is clear,
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
120 one of bits 9-15 must be set, so there will be a carry
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
121 into bit 16. Similarly, there will be a carry into bit
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
122 24. If one of bits 24-30 is set, there will be a carry
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
123 into bit 31, so all of the hole bits will be changed.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
124
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
125 The one misfire occurs when bits 24-30 are clear and bit
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
126 31 is set; in this case, the hole at bit 31 is not
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
127 changed. If we had access to the processor carry flag,
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
128 we could close this loophole by putting the fourth hole
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
129 at bit 32!
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
130
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
131 So it ignores everything except 128's, when they're aligned
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
132 properly.
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
133
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
134 3) But wait! Aren't we looking for C, not zero?
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
135 Good point. So what we do is XOR LONGWORD with a longword,
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
136 each of whose bytes is C. This turns each byte that is C
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
137 into a zero. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
138
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
139 longword1 = *longword_ptr ^ charmask1;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
140 longword2 = *longword_ptr++ ^ charmask2;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
141
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
142 /* Add MAGIC_BITS to LONGWORD. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
143 if ((((longword1 + magic_bits)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
144
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
145 /* Set those bits that were unchanged by the addition. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
146 ^ ~longword1)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
147
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
148 /* Look at only the hole bits. If any of the hole bits
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
149 are unchanged, most likely one of the bytes was a
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
150 zero. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
151 & ~magic_bits) != 0
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
152 || (((longword2 + magic_bits) ^ ~longword2) & ~magic_bits) != 0)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
153 {
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
154 /* Which of the bytes was C? If none of them were, it was
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
155 a misfire; continue the search. */
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
156
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
157 const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
158
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
159 if (cp[0] == c1 || cp[0] == c2)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
160 return (void *) cp;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
161 if (cp[1] == c1 || cp[1] == c2)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
162 return (void *) &cp[1];
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
163 if (cp[2] == c1 || cp[2] == c2)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
164 return (void *) &cp[2];
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
165 if (cp[3] == c1 || cp[3] == c2)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
166 return (void *) &cp[3];
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
167 if (4 < sizeof longword1 && (cp[4] == c1 || cp[4] == c2))
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
168 return (void *) &cp[4];
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
169 if (5 < sizeof longword1 && (cp[5] == c1 || cp[5] == c2))
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
170 return (void *) &cp[5];
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
171 if (6 < sizeof longword1 && (cp[6] == c1 || cp[6] == c2))
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
172 return (void *) &cp[6];
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
173 if (7 < sizeof longword1 && (cp[7] == c1 || cp[7] == c2))
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
174 return (void *) &cp[7];
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
175 if (8 < sizeof longword1)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
176 for (i = 8; i < sizeof longword1; i++)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
177 if (cp[i] == c1 || cp[i] == c2)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
178 return (void *) &cp[i];
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
179 }
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
180
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
181 n -= sizeof longword1;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
182 }
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
183
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
184 char_ptr = (const unsigned char *) longword_ptr;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
185
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
186 while (n-- > 0)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
187 {
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
188 if (*char_ptr == c1 || *char_ptr == c2)
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
189 return (void *) char_ptr;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
190 ++char_ptr;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
191 }
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
192
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
193 return 0;
732f01bce79f New module 'memchr2'.
Eric Blake <ebb9@byu.net>
parents:
diff changeset
194 }