Subversion Repositories Kolibri OS

Rev

Rev 4921 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4921 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 
79
#include 
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
#if __GNUC_PREREQ (4, 2)
88
/* strncasecmp uses signed char, CMP_FUNC is expected to use unsigned char. */
89
#pragma GCC diagnostic ignored "-Wpointer-sign"
90
#endif
91
# define CMP_FUNC strncasecmp
92
# include "str-two-way.h"
93
#endif
94
 
95
/*
96
 * Find the first occurrence of find in s, ignore case.
97
 */
98
char *
6099 serge 99
_DEFUN (strcasestr, (s, find),
100
	_CONST char *s _AND
101
	_CONST char *find)
4921 Serge 102
{
103
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
104
 
105
  /* Less code size, but quadratic performance in the worst case.  */
106
	char c, sc;
107
	size_t len;
108
 
109
	if ((c = *find++) != 0) {
110
		c = tolower((unsigned char)c);
111
		len = strlen(find);
112
		do {
113
			do {
114
				if ((sc = *s++) == 0)
115
					return (NULL);
116
			} while ((char)tolower((unsigned char)sc) != c);
117
		} while (strncasecmp(s, find, len) != 0);
118
		s--;
119
	}
120
	return ((char *)s);
121
 
122
#else /* compilation for speed */
123
 
124
  /* Larger code size, but guaranteed linear performance.  */
125
  const char *haystack = s;
126
  const char *needle = find;
127
  size_t needle_len; /* Length of NEEDLE.  */
128
  size_t haystack_len; /* Known minimum length of HAYSTACK.  */
129
  int ok = 1; /* True if NEEDLE is prefix of HAYSTACK.  */
130
 
131
  /* Determine length of NEEDLE, and in the process, make sure
132
     HAYSTACK is at least as long (no point processing all of a long
133
     NEEDLE if HAYSTACK is too short).  */
134
  while (*haystack && *needle)
135
    ok &= (tolower ((unsigned char) *haystack++)
136
	   == tolower ((unsigned char) *needle++));
137
  if (*needle)
138
    return NULL;
139
  if (ok)
140
    return (char *) s;
141
  needle_len = needle - find;
142
  haystack = s + 1;
143
  haystack_len = needle_len - 1;
144
 
145
  /* Perform the search.  */
146
  if (needle_len < LONG_NEEDLE_THRESHOLD)
147
    return two_way_short_needle ((const unsigned char *) haystack,
148
				 haystack_len,
149
				 (const unsigned char *) find, needle_len);
150
  return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
151
			      (const unsigned char *) find, needle_len);
152
#endif /* compilation for speed */
153
}