• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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