Subversion Repositories Kolibri OS

Rev

Rev 1906 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1906 serge 1
/*
2
FUNCTION
3
	<>---case-insensitive character string search
4
 
5
INDEX
6
	strcasestr
7
 
8
ANSI_SYNOPSIS
9
	#include 
10
	char *strcasestr(const char *<[s]>, const char *<[find]>);
11
 
12
TRAD_SYNOPSIS
13
	#include 
14
	int strcasecmp(<[s]>, <[find]>)
15
	char *<[s]>;
16
	char *<[find]>;
17
 
18
DESCRIPTION
19
	<> searchs the string <[s]> for
20
	the first occurrence of the sequence <[find]>.  <>
21
	is identical to <> except the search is
22
	case-insensitive.
23
 
24
RETURNS
25
 
26
	A pointer to the first case-insensitive occurrence of the sequence
27
	<[find]> or <> if no match was found.
28
 
29
PORTABILITY
30
<> is in the Berkeley Software Distribution.
31
 
32
<> requires no supporting OS subroutines. It uses
33
tolower() from elsewhere in this library.
34
 
35
QUICKREF
36
	strcasestr
37
*/
38
 
39
/*-
40
 * Copyright (c) 1990, 1993
41
 *	The Regents of the University of California.  All rights reserved.
42
 *
43
 * The quadratic code is derived from software contributed to Berkeley by
44
 * Chris Torek.
45
 *
46
 * Redistribution and use in source and binary forms, with or without
47
 * modification, are permitted provided that the following conditions
48
 * are met:
49
 * 1. Redistributions of source code must retain the above copyright
50
 *    notice, this list of conditions and the following disclaimer.
51
 * 2. Redistributions in binary form must reproduce the above copyright
52
 *    notice, this list of conditions and the following disclaimer in the
53
 *    documentation and/or other materials provided with the distribution.
54
 * 4. Neither the name of the University nor the names of its contributors
55
 *    may be used to endorse or promote products derived from this software
56
 *    without specific prior written permission.
57
 *
58
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68
 * SUCH DAMAGE.
69
 */
70
/* Linear algorithm Copyright (C) 2008 Eric Blake
71
 * Permission to use, copy, modify, and distribute the linear portion of
72
 * software is freely granted, provided that this notice is preserved.
73
 */
74
 
75
#include 
76
 
77
#include 
78
#include 
3065 serge 79
#include 
1906 serge 80
 
81
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
82
# define RETURN_TYPE char *
83
# define AVAILABLE(h, h_l, j, n_l)			\
84
  (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))	\
85
   && ((h_l) = (j) + (n_l)))
86
# define CANON_ELEMENT(c) tolower (c)
87
# define CMP_FUNC strncasecmp
88
# include "str-two-way.h"
89
#endif
90
 
91
/*
92
 * Find the first occurrence of find in s, ignore case.
93
 */
94
char *
95
strcasestr(s, find)
96
	const char *s, *find;
97
{
98
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
99
 
100
  /* Less code size, but quadratic performance in the worst case.  */
101
	char c, sc;
102
	size_t len;
103
 
104
	if ((c = *find++) != 0) {
105
		c = tolower((unsigned char)c);
106
		len = strlen(find);
107
		do {
108
			do {
109
				if ((sc = *s++) == 0)
110
					return (NULL);
111
			} while ((char)tolower((unsigned char)sc) != c);
112
		} while (strncasecmp(s, find, len) != 0);
113
		s--;
114
	}
115
	return ((char *)s);
116
 
117
#else /* compilation for speed */
118
 
119
  /* Larger code size, but guaranteed linear performance.  */
120
  const char *haystack = s;
121
  const char *needle = find;
122
  size_t needle_len; /* Length of NEEDLE.  */
123
  size_t haystack_len; /* Known minimum length of HAYSTACK.  */
124
  int ok = 1; /* True if NEEDLE is prefix of HAYSTACK.  */
125
 
126
  /* Determine length of NEEDLE, and in the process, make sure
127
     HAYSTACK is at least as long (no point processing all of a long
128
     NEEDLE if HAYSTACK is too short).  */
129
  while (*haystack && *needle)
130
    ok &= (tolower ((unsigned char) *haystack++)
131
	   == tolower ((unsigned char) *needle++));
132
  if (*needle)
133
    return NULL;
134
  if (ok)
135
    return (char *) s;
136
  needle_len = needle - find;
137
  haystack = s + 1;
138
  haystack_len = needle_len - 1;
139
 
140
  /* Perform the search.  */
141
  if (needle_len < LONG_NEEDLE_THRESHOLD)
142
    return two_way_short_needle ((const unsigned char *) haystack,
143
				 haystack_len,
144
				 (const unsigned char *) find, needle_len);
145
  return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
146
			      (const unsigned char *) find, needle_len);
147
#endif /* compilation for speed */
148
}