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