1 /* Return the offset of one string within another.
2 Copyright (C) 1994, 1996, 1997 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 Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 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 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 see <https://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 /* added strcasestr support, davidm@lineo.com */
28
29 #include "../include/sane/config.h"
30
31 #ifndef HAVE_STRCASESTR
32
33 #if defined HAVE_STRING_H
34 # include <string.h>
35 #endif
36
37 typedef unsigned chartype;
38
39 #include <ctype.h>
40 #define VAL(x) tolower(x)
41
strcasestr(const char * phaystack,const char * pneedle)42 char * strcasestr ( const char *phaystack, const char *pneedle)
43 {
44 register const unsigned char *haystack, *needle;
45 register chartype b, c;
46
47 haystack = (const unsigned char *) phaystack;
48 needle = (const unsigned char *) pneedle;
49
50 b = *needle;
51 if (b != '\0') {
52 haystack--; /* possible ANSI violation */
53 do {
54 c = *++haystack;
55 if (c == '\0')
56 goto ret0;
57 }
58 while (VAL(c) != VAL(b));
59
60 c = *++needle;
61 if (c == '\0')
62 goto foundneedle;
63 ++needle;
64 goto jin;
65
66 for (;;) {
67 register chartype a;
68 register const unsigned char *rhaystack, *rneedle;
69
70 do {
71 a = *++haystack;
72 if (a == '\0')
73 goto ret0;
74 if (VAL(a) == VAL(b))
75 break;
76 a = *++haystack;
77 if (a == '\0')
78 goto ret0;
79 shloop:;}
80 while (VAL(a) != VAL(b));
81
82 jin:a = *++haystack;
83 if (a == '\0')
84 goto ret0;
85
86 if (VAL(a) != VAL(c))
87 goto shloop;
88
89 rhaystack = haystack-- + 1;
90 rneedle = needle;
91 a = *rneedle;
92
93 if (VAL(*rhaystack) == VAL(a))
94 do {
95 if (a == '\0')
96 goto foundneedle;
97 ++rhaystack;
98 a = *++needle;
99 if (VAL(*rhaystack) != VAL(a))
100 break;
101 if (a == '\0')
102 goto foundneedle;
103 ++rhaystack;
104 a = *++needle;
105 }
106 while (VAL(*rhaystack) == VAL(a));
107
108 needle = rneedle; /* took the register-poor approach */
109
110 if (a == '\0')
111 break;
112 }
113 }
114 foundneedle:
115 return (char *) haystack;
116 ret0:
117 return 0;
118 }
119 #endif
120