]>
Commit | Line | Data |
---|---|---|
f4017d20 | 1 | /* Return the offset of one string within another. |
4f514b6b | 2 | Copyright (C) 1994, 1996-2000, 2004 Free Software Foundation, Inc. |
f4017d20 UD |
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 | |
41bdb6e2 AJ |
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. | |
f4017d20 UD |
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 | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
f4017d20 | 14 | |
41bdb6e2 AJ |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
f4017d20 UD |
19 | |
20 | /* | |
21 | * My personal strstr() implementation that beats most other algorithms. | |
22 | * Until someone tells me otherwise, I assume that this is the | |
23 | * fastest implementation of strstr() in C. | |
24 | * I deliberately chose not to comment it. You should have at least | |
25 | * as much fun trying to understand it, as I had to write it :-). | |
26 | * | |
27 | * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */ | |
28 | ||
29 | #if HAVE_CONFIG_H | |
30 | # include <config.h> | |
31 | #endif | |
32 | ||
33 | #include <ctype.h> | |
34 | ||
35 | #if defined _LIBC || defined HAVE_STRING_H | |
36 | # include <string.h> | |
37 | #endif | |
38 | ||
4f514b6b UD |
39 | #ifdef _LIBC |
40 | # include <locale/localeinfo.h> | |
68dc4dcb | 41 | # define TOLOWER(c) __tolower_l ((unsigned char) c, loc) |
4f514b6b UD |
42 | #else |
43 | # define TOLOWER(c) _tolower (c) | |
44 | #endif | |
45 | ||
f4017d20 UD |
46 | typedef unsigned chartype; |
47 | ||
8619129f UD |
48 | #undef strcasestr |
49 | #undef __strcasestr | |
f4017d20 UD |
50 | |
51 | char * | |
52 | __strcasestr (phaystack, pneedle) | |
53 | const char *phaystack; | |
54 | const char *pneedle; | |
55 | { | |
56 | register const unsigned char *haystack, *needle; | |
57 | register chartype b, c; | |
4f514b6b UD |
58 | #ifdef _LIBC |
59 | __locale_t loc = _NL_CURRENT_LOCALE; | |
60 | #endif | |
f4017d20 UD |
61 | |
62 | haystack = (const unsigned char *) phaystack; | |
63 | needle = (const unsigned char *) pneedle; | |
64 | ||
4f514b6b | 65 | b = TOLOWER (*needle); |
f4017d20 UD |
66 | if (b != '\0') |
67 | { | |
68 | haystack--; /* possible ANSI violation */ | |
69 | do | |
70 | { | |
71 | c = *++haystack; | |
72 | if (c == '\0') | |
73 | goto ret0; | |
74 | } | |
4f514b6b | 75 | while (TOLOWER (c) != (int) b); |
f4017d20 | 76 | |
4f514b6b | 77 | c = TOLOWER (*++needle); |
f4017d20 UD |
78 | if (c == '\0') |
79 | goto foundneedle; | |
80 | ++needle; | |
81 | goto jin; | |
82 | ||
83 | for (;;) | |
84 | { | |
85 | register chartype a; | |
86 | register const unsigned char *rhaystack, *rneedle; | |
87 | ||
88 | do | |
89 | { | |
90 | a = *++haystack; | |
91 | if (a == '\0') | |
92 | goto ret0; | |
4f514b6b | 93 | if (TOLOWER (a) == (int) b) |
f4017d20 UD |
94 | break; |
95 | a = *++haystack; | |
96 | if (a == '\0') | |
97 | goto ret0; | |
c3301189 UD |
98 | shloop: |
99 | ; | |
100 | } | |
4f514b6b | 101 | while (TOLOWER (a) != (int) b); |
f4017d20 UD |
102 | |
103 | jin: a = *++haystack; | |
104 | if (a == '\0') | |
105 | goto ret0; | |
106 | ||
4f514b6b | 107 | if (TOLOWER (a) != (int) c) |
f4017d20 UD |
108 | goto shloop; |
109 | ||
110 | rhaystack = haystack-- + 1; | |
111 | rneedle = needle; | |
4f514b6b | 112 | a = TOLOWER (*rneedle); |
f4017d20 | 113 | |
4f514b6b | 114 | if (TOLOWER (*rhaystack) == (int) a) |
f4017d20 UD |
115 | do |
116 | { | |
117 | if (a == '\0') | |
118 | goto foundneedle; | |
119 | ++rhaystack; | |
4f514b6b UD |
120 | a = TOLOWER (*++needle); |
121 | if (TOLOWER (*rhaystack) != (int) a) | |
f4017d20 UD |
122 | break; |
123 | if (a == '\0') | |
124 | goto foundneedle; | |
125 | ++rhaystack; | |
4f514b6b | 126 | a = TOLOWER (*++needle); |
f4017d20 | 127 | } |
4f514b6b | 128 | while (TOLOWER (*rhaystack) == (int) a); |
f4017d20 UD |
129 | |
130 | needle = rneedle; /* took the register-poor approach */ | |
131 | ||
132 | if (a == '\0') | |
133 | break; | |
134 | } | |
135 | } | |
136 | foundneedle: | |
137 | return (char*) haystack; | |
138 | ret0: | |
139 | return 0; | |
140 | } | |
141 | ||
142 | weak_alias (__strcasestr, strcasestr) |