Mercurial > hg > octave-shane > gnulib-hg
annotate lib/strcasestr.c @ 17255:d81be792518a
update from texinfo
author | Karl Berry <karl@freefriends.org> |
---|---|
date | Tue, 01 Jan 2013 15:51:49 -0800 |
parents | e542fd46ad6f |
children | 344018b6e5d7 |
rev | line source |
---|---|
6058 | 1 /* Case-insensitive searching in a string. |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16366
diff
changeset
|
2 Copyright (C) 2005-2013 Free Software Foundation, Inc. |
6058 | 3 Written by Bruno Haible <bruno@clisp.org>, 2005. |
4 | |
5 This program is free software; you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 2, or (at your option) | |
8 any later version. | |
9 | |
10 This program 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 | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16366
bb182ee4a09d
maint: replace FSF snail-mail addresses with URLs
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
16 along with this program; if not, see <http://www.gnu.org/licenses/>. */ |
6058 | 17 |
7304
1c4ed7637c24
Include <config.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
6164
diff
changeset
|
18 #include <config.h> |
6058 | 19 |
20 /* Specification. */ | |
7980
89b6dfd07076
Declare strcasestr() in the <string.h> replacement, rather than in
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
21 #include <string.h> |
6058 | 22 |
23 #include <ctype.h> | |
8125
0545abcdfb09
Ensure O(n) worst-case complexity of strcasestr substitute.
Bruno Haible <bruno@clisp.org>
parents:
8098
diff
changeset
|
24 #include <stdbool.h> |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
25 #include <strings.h> |
8145
e8d8167b9164
Optimize memory allocation to use alloca when possible.
Bruno Haible <bruno@clisp.org>
parents:
8125
diff
changeset
|
26 |
6058 | 27 #define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) |
28 | |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
29 /* Two-Way algorithm. */ |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
30 #define RETURN_TYPE char * |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9623
diff
changeset
|
31 #define AVAILABLE(h, h_l, j, n_l) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9623
diff
changeset
|
32 (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \ |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
33 && ((h_l) = (j) + (n_l))) |
9561
d722bd5e44bd
Unify 5 copies of the KMP code.
Bruno Haible <bruno@clisp.org>
parents:
9558
diff
changeset
|
34 #define CANON_ELEMENT(c) TOLOWER (c) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9623
diff
changeset
|
35 #define CMP_FUNC(p1, p2, l) \ |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
36 strncasecmp ((const char *) (p1), (const char *) (p2), l) |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
37 #include "str-two-way.h" |
8125
0545abcdfb09
Ensure O(n) worst-case complexity of strcasestr substitute.
Bruno Haible <bruno@clisp.org>
parents:
8098
diff
changeset
|
38 |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
39 /* Find the first occurrence of NEEDLE in HAYSTACK, using |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
40 case-insensitive comparison. This function gives unspecified |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
41 results in multibyte locales. */ |
6058 | 42 char * |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
43 strcasestr (const char *haystack_start, const char *needle_start) |
6058 | 44 { |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
45 const char *haystack = haystack_start; |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
46 const char *needle = needle_start; |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
47 size_t needle_len; /* Length of NEEDLE. */ |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
48 size_t haystack_len; /* Known minimum length of HAYSTACK. */ |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
49 bool ok = true; /* True if NEEDLE is prefix of HAYSTACK. */ |
8125
0545abcdfb09
Ensure O(n) worst-case complexity of strcasestr substitute.
Bruno Haible <bruno@clisp.org>
parents:
8098
diff
changeset
|
50 |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
51 /* Determine length of NEEDLE, and in the process, make sure |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
52 HAYSTACK is at least as long (no point processing all of a long |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
53 NEEDLE if HAYSTACK is too short). */ |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
54 while (*haystack && *needle) |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
55 { |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
56 ok &= (TOLOWER ((unsigned char) *haystack) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9623
diff
changeset
|
57 == TOLOWER ((unsigned char) *needle)); |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
58 haystack++; |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
59 needle++; |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
60 } |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
61 if (*needle) |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
62 return NULL; |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
63 if (ok) |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
64 return (char *) haystack_start; |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
65 needle_len = needle - needle_start; |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
66 haystack = haystack_start + 1; |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
67 haystack_len = needle_len - 1; |
8125
0545abcdfb09
Ensure O(n) worst-case complexity of strcasestr substitute.
Bruno Haible <bruno@clisp.org>
parents:
8098
diff
changeset
|
68 |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
69 /* Perform the search. Abstract memory is considered to be an array |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
70 of 'unsigned char' values, not an array of 'char' values. See |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
71 ISO C 99 section 6.2.6.1. */ |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
72 if (needle_len < LONG_NEEDLE_THRESHOLD) |
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
73 return two_way_short_needle ((const unsigned char *) haystack, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9623
diff
changeset
|
74 haystack_len, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9623
diff
changeset
|
75 (const unsigned char *) needle_start, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9623
diff
changeset
|
76 needle_len); |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
77 return two_way_long_needle ((const unsigned char *) haystack, haystack_len, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9623
diff
changeset
|
78 (const unsigned char *) needle_start, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9623
diff
changeset
|
79 needle_len); |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
80 } |
6058 | 81 |
9623
69d9307c0aa0
Convert strcasestr module to use Two-Way algorithm.
Eric Blake <ebb9@byu.net>
parents:
9561
diff
changeset
|
82 #undef LONG_NEEDLE_THRESHOLD |