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