1141cc406Sopenharmony_ci/* Return the offset of one string within another.
2141cc406Sopenharmony_ci   Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
3141cc406Sopenharmony_ci   This file is part of the GNU C Library.
4141cc406Sopenharmony_ci
5141cc406Sopenharmony_ci   The GNU C Library is free software; you can redistribute it and/or
6141cc406Sopenharmony_ci   modify it under the terms of the GNU Library General Public License as
7141cc406Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
8141cc406Sopenharmony_ci   License, or (at your option) any later version.
9141cc406Sopenharmony_ci
10141cc406Sopenharmony_ci   The GNU C Library is distributed in the hope that it will be useful,
11141cc406Sopenharmony_ci   but WITHOUT ANY WARRANTY; without even the implied warranty of
12141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13141cc406Sopenharmony_ci   Library General Public License for more details.
14141cc406Sopenharmony_ci
15141cc406Sopenharmony_ci   You should have received a copy of the GNU Library General Public
16141cc406Sopenharmony_ci   License along with the GNU C Library; see the file COPYING.LIB.  If not,
17141cc406Sopenharmony_ci   see <https://www.gnu.org/licenses/>.  */
18141cc406Sopenharmony_ci
19141cc406Sopenharmony_ci/*
20141cc406Sopenharmony_ci * My personal strstr() implementation that beats most other algorithms.
21141cc406Sopenharmony_ci * Until someone tells me otherwise, I assume that this is the
22141cc406Sopenharmony_ci * fastest implementation of strstr() in C.
23141cc406Sopenharmony_ci * I deliberately chose not to comment it.  You should have at least
24141cc406Sopenharmony_ci * as much fun trying to understand it, as I had to write it :-).
25141cc406Sopenharmony_ci *
26141cc406Sopenharmony_ci * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de	*/
27141cc406Sopenharmony_ci/* added strcasestr support, davidm@lineo.com */
28141cc406Sopenharmony_ci
29141cc406Sopenharmony_ci#include "../include/sane/config.h"
30141cc406Sopenharmony_ci
31141cc406Sopenharmony_ci#ifndef HAVE_STRCASESTR
32141cc406Sopenharmony_ci
33141cc406Sopenharmony_ci#if  defined HAVE_STRING_H
34141cc406Sopenharmony_ci# include <string.h>
35141cc406Sopenharmony_ci#endif
36141cc406Sopenharmony_ci
37141cc406Sopenharmony_citypedef unsigned chartype;
38141cc406Sopenharmony_ci
39141cc406Sopenharmony_ci#include <ctype.h>
40141cc406Sopenharmony_ci#define VAL(x)	tolower(x)
41141cc406Sopenharmony_ci
42141cc406Sopenharmony_cichar * strcasestr ( const char *phaystack, const char *pneedle)
43141cc406Sopenharmony_ci{
44141cc406Sopenharmony_ci	register const unsigned char *haystack, *needle;
45141cc406Sopenharmony_ci	register chartype b, c;
46141cc406Sopenharmony_ci
47141cc406Sopenharmony_ci	haystack = (const unsigned char *) phaystack;
48141cc406Sopenharmony_ci	needle = (const unsigned char *) pneedle;
49141cc406Sopenharmony_ci
50141cc406Sopenharmony_ci	b = *needle;
51141cc406Sopenharmony_ci	if (b != '\0') {
52141cc406Sopenharmony_ci		haystack--;				/* possible ANSI violation */
53141cc406Sopenharmony_ci		do {
54141cc406Sopenharmony_ci			c = *++haystack;
55141cc406Sopenharmony_ci			if (c == '\0')
56141cc406Sopenharmony_ci				goto ret0;
57141cc406Sopenharmony_ci		}
58141cc406Sopenharmony_ci		while (VAL(c) != VAL(b));
59141cc406Sopenharmony_ci
60141cc406Sopenharmony_ci		c = *++needle;
61141cc406Sopenharmony_ci		if (c == '\0')
62141cc406Sopenharmony_ci			goto foundneedle;
63141cc406Sopenharmony_ci		++needle;
64141cc406Sopenharmony_ci		goto jin;
65141cc406Sopenharmony_ci
66141cc406Sopenharmony_ci		for (;;) {
67141cc406Sopenharmony_ci			register chartype a;
68141cc406Sopenharmony_ci			register const unsigned char *rhaystack, *rneedle;
69141cc406Sopenharmony_ci
70141cc406Sopenharmony_ci			do {
71141cc406Sopenharmony_ci				a = *++haystack;
72141cc406Sopenharmony_ci				if (a == '\0')
73141cc406Sopenharmony_ci					goto ret0;
74141cc406Sopenharmony_ci				if (VAL(a) == VAL(b))
75141cc406Sopenharmony_ci					break;
76141cc406Sopenharmony_ci				a = *++haystack;
77141cc406Sopenharmony_ci				if (a == '\0')
78141cc406Sopenharmony_ci					goto ret0;
79141cc406Sopenharmony_ci		  shloop:;}
80141cc406Sopenharmony_ci			while (VAL(a) != VAL(b));
81141cc406Sopenharmony_ci
82141cc406Sopenharmony_ci		  jin:a = *++haystack;
83141cc406Sopenharmony_ci			if (a == '\0')
84141cc406Sopenharmony_ci				goto ret0;
85141cc406Sopenharmony_ci
86141cc406Sopenharmony_ci			if (VAL(a) != VAL(c))
87141cc406Sopenharmony_ci				goto shloop;
88141cc406Sopenharmony_ci
89141cc406Sopenharmony_ci			rhaystack = haystack-- + 1;
90141cc406Sopenharmony_ci			rneedle = needle;
91141cc406Sopenharmony_ci			a = *rneedle;
92141cc406Sopenharmony_ci
93141cc406Sopenharmony_ci			if (VAL(*rhaystack) == VAL(a))
94141cc406Sopenharmony_ci				do {
95141cc406Sopenharmony_ci					if (a == '\0')
96141cc406Sopenharmony_ci						goto foundneedle;
97141cc406Sopenharmony_ci					++rhaystack;
98141cc406Sopenharmony_ci					a = *++needle;
99141cc406Sopenharmony_ci					if (VAL(*rhaystack) != VAL(a))
100141cc406Sopenharmony_ci						break;
101141cc406Sopenharmony_ci					if (a == '\0')
102141cc406Sopenharmony_ci						goto foundneedle;
103141cc406Sopenharmony_ci					++rhaystack;
104141cc406Sopenharmony_ci					a = *++needle;
105141cc406Sopenharmony_ci				}
106141cc406Sopenharmony_ci				while (VAL(*rhaystack) == VAL(a));
107141cc406Sopenharmony_ci
108141cc406Sopenharmony_ci			needle = rneedle;	/* took the register-poor approach */
109141cc406Sopenharmony_ci
110141cc406Sopenharmony_ci			if (a == '\0')
111141cc406Sopenharmony_ci				break;
112141cc406Sopenharmony_ci		}
113141cc406Sopenharmony_ci	}
114141cc406Sopenharmony_ci  foundneedle:
115141cc406Sopenharmony_ci	return (char *) haystack;
116141cc406Sopenharmony_ci  ret0:
117141cc406Sopenharmony_ci	return 0;
118141cc406Sopenharmony_ci}
119141cc406Sopenharmony_ci#endif
120