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