xref: /netbsd-src/external/gpl2/grep/dist/lib/memchr.c (revision a8fa202a6440953be7b92a8960a811bff58203f4)
1*a8fa202aSchristos /*	$NetBSD: memchr.c,v 1.1.1.1 2016/01/10 21:36:18 christos Exp $	*/
2*a8fa202aSchristos 
3*a8fa202aSchristos /* Copyright (C) 1991, 1993, 1997, 1999 Free Software Foundation, Inc.
4*a8fa202aSchristos    Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
5*a8fa202aSchristos    with help from Dan Sahlin (dan@sics.se) and
6*a8fa202aSchristos    commentary by Jim Blandy (jimb@ai.mit.edu);
7*a8fa202aSchristos    adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
8*a8fa202aSchristos    and implemented by Roland McGrath (roland@ai.mit.edu).
9*a8fa202aSchristos 
10*a8fa202aSchristos NOTE: The canonical source of this file is maintained with the GNU C Library.
11*a8fa202aSchristos Bugs can be reported to bug-glibc@prep.ai.mit.edu.
12*a8fa202aSchristos 
13*a8fa202aSchristos This program is free software; you can redistribute it and/or modify it
14*a8fa202aSchristos under the terms of the GNU General Public License as published by the
15*a8fa202aSchristos Free Software Foundation; either version 2, or (at your option) any
16*a8fa202aSchristos later version.
17*a8fa202aSchristos 
18*a8fa202aSchristos This program is distributed in the hope that it will be useful,
19*a8fa202aSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of
20*a8fa202aSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21*a8fa202aSchristos GNU General Public License for more details.
22*a8fa202aSchristos 
23*a8fa202aSchristos You should have received a copy of the GNU General Public License
24*a8fa202aSchristos along with this program; if not, write to the Free Software
25*a8fa202aSchristos Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26*a8fa202aSchristos USA.  */
27*a8fa202aSchristos 
28*a8fa202aSchristos #ifdef HAVE_CONFIG_H
29*a8fa202aSchristos # include <config.h>
30*a8fa202aSchristos #endif
31*a8fa202aSchristos 
32*a8fa202aSchristos #undef __ptr_t
33*a8fa202aSchristos #if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
34*a8fa202aSchristos # define __ptr_t void *
35*a8fa202aSchristos #else /* Not C++ or ANSI C.  */
36*a8fa202aSchristos # define __ptr_t char *
37*a8fa202aSchristos #endif /* C++ or ANSI C.  */
38*a8fa202aSchristos 
39*a8fa202aSchristos #if defined (_LIBC)
40*a8fa202aSchristos # include <string.h>
41*a8fa202aSchristos #endif
42*a8fa202aSchristos 
43*a8fa202aSchristos #if defined (HAVE_LIMITS_H) || defined (_LIBC)
44*a8fa202aSchristos # include <limits.h>
45*a8fa202aSchristos #endif
46*a8fa202aSchristos 
47*a8fa202aSchristos #define LONG_MAX_32_BITS 2147483647
48*a8fa202aSchristos 
49*a8fa202aSchristos #ifndef LONG_MAX
50*a8fa202aSchristos # define LONG_MAX LONG_MAX_32_BITS
51*a8fa202aSchristos #endif
52*a8fa202aSchristos 
53*a8fa202aSchristos #include <sys/types.h>
54*a8fa202aSchristos 
55*a8fa202aSchristos 
56*a8fa202aSchristos /* Search no more than N bytes of S for C.  */
57*a8fa202aSchristos 
58*a8fa202aSchristos __ptr_t
memchr(s,c,n)59*a8fa202aSchristos memchr (s, c, n)
60*a8fa202aSchristos      const __ptr_t s;
61*a8fa202aSchristos      int c;
62*a8fa202aSchristos      size_t n;
63*a8fa202aSchristos {
64*a8fa202aSchristos   const unsigned char *char_ptr;
65*a8fa202aSchristos   const unsigned long int *longword_ptr;
66*a8fa202aSchristos   unsigned long int longword, magic_bits, charmask;
67*a8fa202aSchristos 
68*a8fa202aSchristos   c = (unsigned char) c;
69*a8fa202aSchristos 
70*a8fa202aSchristos   /* Handle the first few characters by reading one character at a time.
71*a8fa202aSchristos      Do this until CHAR_PTR is aligned on a longword boundary.  */
72*a8fa202aSchristos   for (char_ptr = (const unsigned char *) s;
73*a8fa202aSchristos        n > 0 && ((unsigned long int) char_ptr
74*a8fa202aSchristos 		 & (sizeof (longword) - 1)) != 0;
75*a8fa202aSchristos        --n, ++char_ptr)
76*a8fa202aSchristos     if (*char_ptr == c)
77*a8fa202aSchristos       return (__ptr_t) char_ptr;
78*a8fa202aSchristos 
79*a8fa202aSchristos   /* All these elucidatory comments refer to 4-byte longwords,
80*a8fa202aSchristos      but the theory applies equally well to 8-byte longwords.  */
81*a8fa202aSchristos 
82*a8fa202aSchristos   longword_ptr = (unsigned long int *) char_ptr;
83*a8fa202aSchristos 
84*a8fa202aSchristos   /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
85*a8fa202aSchristos      the "holes."  Note that there is a hole just to the left of
86*a8fa202aSchristos      each byte, with an extra at the end:
87*a8fa202aSchristos 
88*a8fa202aSchristos      bits:  01111110 11111110 11111110 11111111
89*a8fa202aSchristos      bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
90*a8fa202aSchristos 
91*a8fa202aSchristos      The 1-bits make sure that carries propagate to the next 0-bit.
92*a8fa202aSchristos      The 0-bits provide holes for carries to fall into.  */
93*a8fa202aSchristos 
94*a8fa202aSchristos   if (sizeof (longword) != 4 && sizeof (longword) != 8)
95*a8fa202aSchristos     abort ();
96*a8fa202aSchristos 
97*a8fa202aSchristos #if LONG_MAX <= LONG_MAX_32_BITS
98*a8fa202aSchristos   magic_bits = 0x7efefeff;
99*a8fa202aSchristos #else
100*a8fa202aSchristos   magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;
101*a8fa202aSchristos #endif
102*a8fa202aSchristos 
103*a8fa202aSchristos   /* Set up a longword, each of whose bytes is C.  */
104*a8fa202aSchristos   charmask = c | (c << 8);
105*a8fa202aSchristos   charmask |= charmask << 16;
106*a8fa202aSchristos #if LONG_MAX > LONG_MAX_32_BITS
107*a8fa202aSchristos   charmask |= charmask << 32;
108*a8fa202aSchristos #endif
109*a8fa202aSchristos 
110*a8fa202aSchristos   /* Instead of the traditional loop which tests each character,
111*a8fa202aSchristos      we will test a longword at a time.  The tricky part is testing
112*a8fa202aSchristos      if *any of the four* bytes in the longword in question are zero.  */
113*a8fa202aSchristos   while (n >= sizeof (longword))
114*a8fa202aSchristos     {
115*a8fa202aSchristos       /* We tentatively exit the loop if adding MAGIC_BITS to
116*a8fa202aSchristos 	 LONGWORD fails to change any of the hole bits of LONGWORD.
117*a8fa202aSchristos 
118*a8fa202aSchristos 	 1) Is this safe?  Will it catch all the zero bytes?
119*a8fa202aSchristos 	 Suppose there is a byte with all zeros.  Any carry bits
120*a8fa202aSchristos 	 propagating from its left will fall into the hole at its
121*a8fa202aSchristos 	 least significant bit and stop.  Since there will be no
122*a8fa202aSchristos 	 carry from its most significant bit, the LSB of the
123*a8fa202aSchristos 	 byte to the left will be unchanged, and the zero will be
124*a8fa202aSchristos 	 detected.
125*a8fa202aSchristos 
126*a8fa202aSchristos 	 2) Is this worthwhile?  Will it ignore everything except
127*a8fa202aSchristos 	 zero bytes?  Suppose every byte of LONGWORD has a bit set
128*a8fa202aSchristos 	 somewhere.  There will be a carry into bit 8.  If bit 8
129*a8fa202aSchristos 	 is set, this will carry into bit 16.  If bit 8 is clear,
130*a8fa202aSchristos 	 one of bits 9-15 must be set, so there will be a carry
131*a8fa202aSchristos 	 into bit 16.  Similarly, there will be a carry into bit
132*a8fa202aSchristos 	 24.  If one of bits 24-30 is set, there will be a carry
133*a8fa202aSchristos 	 into bit 31, so all of the hole bits will be changed.
134*a8fa202aSchristos 
135*a8fa202aSchristos 	 The one misfire occurs when bits 24-30 are clear and bit
136*a8fa202aSchristos 	 31 is set; in this case, the hole at bit 31 is not
137*a8fa202aSchristos 	 changed.  If we had access to the processor carry flag,
138*a8fa202aSchristos 	 we could close this loophole by putting the fourth hole
139*a8fa202aSchristos 	 at bit 32!
140*a8fa202aSchristos 
141*a8fa202aSchristos 	 So it ignores everything except 128's, when they're aligned
142*a8fa202aSchristos 	 properly.
143*a8fa202aSchristos 
144*a8fa202aSchristos 	 3) But wait!  Aren't we looking for C, not zero?
145*a8fa202aSchristos 	 Good point.  So what we do is XOR LONGWORD with a longword,
146*a8fa202aSchristos 	 each of whose bytes is C.  This turns each byte that is C
147*a8fa202aSchristos 	 into a zero.  */
148*a8fa202aSchristos 
149*a8fa202aSchristos       longword = *longword_ptr++ ^ charmask;
150*a8fa202aSchristos 
151*a8fa202aSchristos       /* Add MAGIC_BITS to LONGWORD.  */
152*a8fa202aSchristos       if ((((longword + magic_bits)
153*a8fa202aSchristos 
154*a8fa202aSchristos 	    /* Set those bits that were unchanged by the addition.  */
155*a8fa202aSchristos 	    ^ ~longword)
156*a8fa202aSchristos 
157*a8fa202aSchristos 	   /* Look at only the hole bits.  If any of the hole bits
158*a8fa202aSchristos 	      are unchanged, most likely one of the bytes was a
159*a8fa202aSchristos 	      zero.  */
160*a8fa202aSchristos 	   & ~magic_bits) != 0)
161*a8fa202aSchristos 	{
162*a8fa202aSchristos 	  /* Which of the bytes was C?  If none of them were, it was
163*a8fa202aSchristos 	     a misfire; continue the search.  */
164*a8fa202aSchristos 
165*a8fa202aSchristos 	  const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
166*a8fa202aSchristos 
167*a8fa202aSchristos 	  if (cp[0] == c)
168*a8fa202aSchristos 	    return (__ptr_t) cp;
169*a8fa202aSchristos 	  if (cp[1] == c)
170*a8fa202aSchristos 	    return (__ptr_t) &cp[1];
171*a8fa202aSchristos 	  if (cp[2] == c)
172*a8fa202aSchristos 	    return (__ptr_t) &cp[2];
173*a8fa202aSchristos 	  if (cp[3] == c)
174*a8fa202aSchristos 	    return (__ptr_t) &cp[3];
175*a8fa202aSchristos #if LONG_MAX > 2147483647
176*a8fa202aSchristos 	  if (cp[4] == c)
177*a8fa202aSchristos 	    return (__ptr_t) &cp[4];
178*a8fa202aSchristos 	  if (cp[5] == c)
179*a8fa202aSchristos 	    return (__ptr_t) &cp[5];
180*a8fa202aSchristos 	  if (cp[6] == c)
181*a8fa202aSchristos 	    return (__ptr_t) &cp[6];
182*a8fa202aSchristos 	  if (cp[7] == c)
183*a8fa202aSchristos 	    return (__ptr_t) &cp[7];
184*a8fa202aSchristos #endif
185*a8fa202aSchristos 	}
186*a8fa202aSchristos 
187*a8fa202aSchristos       n -= sizeof (longword);
188*a8fa202aSchristos     }
189*a8fa202aSchristos 
190*a8fa202aSchristos   char_ptr = (const unsigned char *) longword_ptr;
191*a8fa202aSchristos 
192*a8fa202aSchristos   while (n-- > 0)
193*a8fa202aSchristos     {
194*a8fa202aSchristos       if (*char_ptr == c)
195*a8fa202aSchristos 	return (__ptr_t) char_ptr;
196*a8fa202aSchristos       else
197*a8fa202aSchristos 	++char_ptr;
198*a8fa202aSchristos     }
199*a8fa202aSchristos 
200*a8fa202aSchristos   return 0;
201*a8fa202aSchristos }
202