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