xref: /netbsd-src/external/gpl2/gettext/dist/gettext-runtime/gnulib-lib/c-strstr.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1*946379e7Schristos /* Copyright (C) 1994, 1999, 2002-2003, 2005-2006 Free Software Foundation, Inc.
2*946379e7Schristos This file is part of the GNU C Library.
3*946379e7Schristos 
4*946379e7Schristos This program is free software; you can redistribute it and/or modify
5*946379e7Schristos it under the terms of the GNU General Public License as published by
6*946379e7Schristos the Free Software Foundation; either version 2, or (at your option)
7*946379e7Schristos any later version.
8*946379e7Schristos 
9*946379e7Schristos This program is distributed in the hope that it will be useful,
10*946379e7Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
11*946379e7Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*946379e7Schristos GNU General Public License for more details.
13*946379e7Schristos 
14*946379e7Schristos You should have received a copy of the GNU General Public License
15*946379e7Schristos along with this program; if not, write to the Free Software Foundation,
16*946379e7Schristos Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17*946379e7Schristos 
18*946379e7Schristos /*
19*946379e7Schristos  * My personal strstr() implementation that beats most other algorithms.
20*946379e7Schristos  * Until someone tells me otherwise, I assume that this is the
21*946379e7Schristos  * fastest implementation of strstr() in C.
22*946379e7Schristos  * I deliberately chose not to comment it.  You should have at least
23*946379e7Schristos  * as much fun trying to understand it, as I had to write it :-).
24*946379e7Schristos  *
25*946379e7Schristos  * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de	*/
26*946379e7Schristos 
27*946379e7Schristos #include <config.h>
28*946379e7Schristos 
29*946379e7Schristos /* Specification.  */
30*946379e7Schristos #include "c-strstr.h"
31*946379e7Schristos 
32*946379e7Schristos #include <string.h>
33*946379e7Schristos 
34*946379e7Schristos typedef unsigned chartype;
35*946379e7Schristos 
36*946379e7Schristos char *
c_strstr(const char * phaystack,const char * pneedle)37*946379e7Schristos c_strstr (const char *phaystack, const char *pneedle)
38*946379e7Schristos {
39*946379e7Schristos   register const unsigned char *haystack, *needle;
40*946379e7Schristos   register chartype b, c;
41*946379e7Schristos 
42*946379e7Schristos   haystack = (const unsigned char *) phaystack;
43*946379e7Schristos   needle = (const unsigned char *) pneedle;
44*946379e7Schristos 
45*946379e7Schristos   b = *needle;
46*946379e7Schristos   if (b != '\0')
47*946379e7Schristos     {
48*946379e7Schristos       haystack--;				/* possible ANSI violation */
49*946379e7Schristos       do
50*946379e7Schristos 	{
51*946379e7Schristos 	  c = *++haystack;
52*946379e7Schristos 	  if (c == '\0')
53*946379e7Schristos 	    goto ret0;
54*946379e7Schristos 	}
55*946379e7Schristos       while (c != b);
56*946379e7Schristos 
57*946379e7Schristos       c = *++needle;
58*946379e7Schristos       if (c == '\0')
59*946379e7Schristos 	goto foundneedle;
60*946379e7Schristos       ++needle;
61*946379e7Schristos       goto jin;
62*946379e7Schristos 
63*946379e7Schristos       for (;;)
64*946379e7Schristos         {
65*946379e7Schristos           register chartype a;
66*946379e7Schristos 	  register const unsigned char *rhaystack, *rneedle;
67*946379e7Schristos 
68*946379e7Schristos 	  do
69*946379e7Schristos 	    {
70*946379e7Schristos 	      a = *++haystack;
71*946379e7Schristos 	      if (a == '\0')
72*946379e7Schristos 		goto ret0;
73*946379e7Schristos 	      if (a == b)
74*946379e7Schristos 		break;
75*946379e7Schristos 	      a = *++haystack;
76*946379e7Schristos 	      if (a == '\0')
77*946379e7Schristos 		goto ret0;
78*946379e7Schristos shloop:;    }
79*946379e7Schristos           while (a != b);
80*946379e7Schristos 
81*946379e7Schristos jin:	  a = *++haystack;
82*946379e7Schristos 	  if (a == '\0')
83*946379e7Schristos 	    goto ret0;
84*946379e7Schristos 
85*946379e7Schristos 	  if (a != c)
86*946379e7Schristos 	    goto shloop;
87*946379e7Schristos 
88*946379e7Schristos 	  rhaystack = haystack-- + 1;
89*946379e7Schristos 	  rneedle = needle;
90*946379e7Schristos 	  a = *rneedle;
91*946379e7Schristos 
92*946379e7Schristos 	  if (*rhaystack == a)
93*946379e7Schristos 	    do
94*946379e7Schristos 	      {
95*946379e7Schristos 		if (a == '\0')
96*946379e7Schristos 		  goto foundneedle;
97*946379e7Schristos 		++rhaystack;
98*946379e7Schristos 		a = *++needle;
99*946379e7Schristos 		if (*rhaystack != a)
100*946379e7Schristos 		  break;
101*946379e7Schristos 		if (a == '\0')
102*946379e7Schristos 		  goto foundneedle;
103*946379e7Schristos 		++rhaystack;
104*946379e7Schristos 		a = *++needle;
105*946379e7Schristos 	      }
106*946379e7Schristos 	    while (*rhaystack == a);
107*946379e7Schristos 
108*946379e7Schristos 	  needle = rneedle;		   /* took the register-poor approach */
109*946379e7Schristos 
110*946379e7Schristos 	  if (a == '\0')
111*946379e7Schristos 	    break;
112*946379e7Schristos         }
113*946379e7Schristos     }
114*946379e7Schristos foundneedle:
115*946379e7Schristos   return (char *) haystack;
116*946379e7Schristos ret0:
117*946379e7Schristos   return 0;
118*946379e7Schristos }
119