annotate lib/mbscasecmp.c @ 8091:ebf2b19b5684

New module 'mbscasecmp'. strcasecmp is not expected to work with multibyte strings.
author Bruno Haible <bruno@clisp.org>
date Mon, 05 Feb 2007 01:57:07 +0000
parents 6a02aa86f4b4
children bbbbbf4cd1c5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8089
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Case-insensitive string comparison function.
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
2 Copyright (C) 1998-1999, 2005-2007 Free Software Foundation, Inc.
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <bruno@clisp.org>, 2005,
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4 based on earlier glibc code.
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 This program is free software; you can redistribute it and/or modify
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 the Free Software Foundation; either version 2, or (at your option)
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 any later version.
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 This program is distributed in the hope that it will be useful,
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14 GNU General Public License for more details.
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 along with this program; if not, write to the Free Software Foundation,
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 #include <config.h>
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 /* Specification. */
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <string.h>
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include <ctype.h>
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 #include <limits.h>
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 #if HAVE_MBRTOWC
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 # include "mbuiter.h"
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30 #endif
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 #define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33
8091
ebf2b19b5684 New module 'mbscasecmp'. strcasecmp is not expected to work with multibyte
Bruno Haible <bruno@clisp.org>
parents: 8089
diff changeset
34 /* Compare the character strings S1 and S2, ignoring case, returning less than,
ebf2b19b5684 New module 'mbscasecmp'. strcasecmp is not expected to work with multibyte
Bruno Haible <bruno@clisp.org>
parents: 8089
diff changeset
35 equal to or greater than zero if S1 is lexicographically less than, equal to
ebf2b19b5684 New module 'mbscasecmp'. strcasecmp is not expected to work with multibyte
Bruno Haible <bruno@clisp.org>
parents: 8089
diff changeset
36 or greater than S2.
8089
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 Note: This function may, in multibyte locales, return 0 for strings of
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38 different lengths! */
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 int
8091
ebf2b19b5684 New module 'mbscasecmp'. strcasecmp is not expected to work with multibyte
Bruno Haible <bruno@clisp.org>
parents: 8089
diff changeset
40 mbscasecmp (const char *s1, const char *s2)
8089
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 {
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42 if (s1 == s2)
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43 return 0;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 /* Be careful not to look at the entire extent of s1 or s2 until needed.
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 This is useful because when two strings differ, the difference is
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 most often already in the very few first characters. */
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 #if HAVE_MBRTOWC
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 if (MB_CUR_MAX > 1)
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50 {
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51 mbui_iterator_t iter1;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 mbui_iterator_t iter2;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 mbui_init (iter1, s1);
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 mbui_init (iter2, s2);
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57 while (mbui_avail (iter1) && mbui_avail (iter2))
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 {
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 int cmp = mb_casecmp (mbui_cur (iter1), mbui_cur (iter2));
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 if (cmp != 0)
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 return cmp;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 mbui_advance (iter1);
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 mbui_advance (iter2);
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 }
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 if (mbui_avail (iter1))
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 /* s2 terminated before s1. */
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 return 1;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 if (mbui_avail (iter2))
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 /* s1 terminated before s2. */
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 return -1;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 return 0;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 }
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 else
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76 #endif
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 {
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78 const unsigned char *p1 = (const unsigned char *) s1;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 const unsigned char *p2 = (const unsigned char *) s2;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80 unsigned char c1, c2;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 do
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 {
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84 c1 = TOLOWER (*p1);
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85 c2 = TOLOWER (*p2);
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 if (c1 == '\0')
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 break;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
89
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90 ++p1;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91 ++p2;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92 }
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 while (c1 == c2);
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 if (UCHAR_MAX <= INT_MAX)
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96 return c1 - c2;
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97 else
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98 /* On machines where 'char' and 'int' are types of the same size, the
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 difference of two 'unsigned char' values - including the sign bit -
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 doesn't fit in an 'int'. */
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 }
6a02aa86f4b4 Copied from strcasecmp.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 }